summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorYasuhiro Matsumoto <mattn.jp@gmail.com>2022-12-05 21:55:55 +0000
committerBram Moolenaar <Bram@vim.org>2022-12-05 21:55:55 +0000
commitf0a9c004825ab686270ee57260652cce25e61049 (patch)
treee1e2abb369c58ae0057276158931822f8d39f5e6 /src
parent25201016d5043954689a4c9f7833935294149404 (diff)
downloadvim-git-f0a9c004825ab686270ee57260652cce25e61049.tar.gz
patch 9.0.1015: without /dev/urandom srand() seed is too predictablev9.0.1015
Problem: Without /dev/urandom srand() seed is too predictable. Solution: Use micro seconds and XOR with process ID. (Yasuhiro Matsumoto, closes #11656)
Diffstat (limited to 'src')
-rw-r--r--src/evalfunc.c27
-rw-r--r--src/testdir/test_random.vim19
-rw-r--r--src/version.c2
3 files changed, 46 insertions, 2 deletions
diff --git a/src/evalfunc.c b/src/evalfunc.c
index 0b2ba00b6..428c4cb2b 100644
--- a/src/evalfunc.c
+++ b/src/evalfunc.c
@@ -8159,9 +8159,32 @@ init_srand(UINT32_T *x)
}
}
if (dev_urandom_state != OK)
- // Reading /dev/urandom doesn't work, fall back to time().
#endif
- *x = vim_time();
+ {
+ // Reading /dev/urandom doesn't work, fall back to:
+ // - randombytes_random()
+ // - reltime() or time()
+ // - XOR with process ID
+#if defined(FEAT_SODIUM)
+ if (sodium_init() >= 0)
+ *x = randombytes_random();
+ else
+#endif
+ {
+#if defined(FEAT_RELTIME)
+ proftime_T res;
+ profile_start(&res);
+# if defined(MSWIN)
+ *x = (UINT32_T)res.LowPart;
+# else
+ *x = (UINT32_T)res.tv_usec;
+# endif
+#else
+ *x = vim_time();
+#endif
+ *x ^= mch_get_pid();
+ }
+ }
}
#define ROTL(x, k) (((x) << (k)) | ((x) >> (32 - (k))))
diff --git a/src/testdir/test_random.vim b/src/testdir/test_random.vim
index afb3044e7..fdfaea257 100644
--- a/src/testdir/test_random.vim
+++ b/src/testdir/test_random.vim
@@ -1,5 +1,8 @@
" Tests for srand() and rand()
+source check.vim
+source shared.vim
+
func Test_Rand()
let r = srand(123456789)
call assert_equal([1573771921, 319883699, 2742014374, 1324369493], r)
@@ -44,4 +47,20 @@ func Test_issue_5587()
call rand()
endfunc
+func Test_srand()
+ CheckNotGui
+
+ let cmd = GetVimCommand() .. ' -V -es -c "echo rand()" -c qa!'
+ let bad = 0
+ for _ in range(10)
+ echo cmd
+ let result1 = system(cmd)
+ let result2 = system(cmd)
+ if result1 ==# result2
+ let bad += 1
+ endif
+ endfor
+ call assert_inrange(0, 4, bad)
+endfunc
+
" vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/version.c b/src/version.c
index 9e4411eb6..a19d94765 100644
--- a/src/version.c
+++ b/src/version.c
@@ -696,6 +696,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 1015,
+/**/
1014,
/**/
1013,