diff options
author | Yasuhiro Matsumoto <mattn.jp@gmail.com> | 2022-12-05 21:55:55 +0000 |
---|---|---|
committer | Bram Moolenaar <Bram@vim.org> | 2022-12-05 21:55:55 +0000 |
commit | f0a9c004825ab686270ee57260652cce25e61049 (patch) | |
tree | e1e2abb369c58ae0057276158931822f8d39f5e6 /src | |
parent | 25201016d5043954689a4c9f7833935294149404 (diff) |
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.c | 27 | ||||
-rw-r--r-- | src/testdir/test_random.vim | 19 | ||||
-rw-r--r-- | src/version.c | 2 |
3 files changed, 46 insertions, 2 deletions
diff --git a/src/evalfunc.c b/src/evalfunc.c index 0b2ba00b6e..428c4cb2b2 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 afb3044e7f..fdfaea2575 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 9e4411eb69..a19d947653 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, |