* random.c (Init_RandomSeed): move all Random::DEFAULT
construction bits to Init_RandomSeed2. Random::DEFAULT and Ruby internal hashes are no longer shared their seed. * random.c (Init_RandomSeed2): ditto. And, kill evil rb_obj_reveal() stuff. * random.c (init_hashseed): add MT argument. * random.c: (init_siphash): ditto. * test/ruby/test_rand.rb (TestRand#test_default_seed): new test for Random::DEFAULT::seed. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@52815 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
052535be3e
commit
99c05fb38e
14
ChangeLog
14
ChangeLog
@ -1,3 +1,17 @@
|
|||||||
|
Thu Oct 22 06:20:48 2015 KOSAKI Motohiro <kosaki.motohiro@gmail.com>
|
||||||
|
|
||||||
|
* random.c (Init_RandomSeed): move all Random::DEFAULT
|
||||||
|
construction bits to Init_RandomSeed2. Random::DEFAULT
|
||||||
|
and Ruby internal hashes are no longer shared their seed.
|
||||||
|
* random.c (Init_RandomSeed2): ditto. And, kill evil
|
||||||
|
rb_obj_reveal() stuff.
|
||||||
|
|
||||||
|
* random.c (init_hashseed): add MT argument.
|
||||||
|
* random.c: (init_siphash): ditto.
|
||||||
|
|
||||||
|
* test/ruby/test_rand.rb (TestRand#test_default_seed): new
|
||||||
|
test for Random::DEFAULT::seed.
|
||||||
|
|
||||||
Thu Oct 22 05:23:48 2015 KOSAKI Motohiro <kosaki.motohiro@gmail.com>
|
Thu Oct 22 05:23:48 2015 KOSAKI Motohiro <kosaki.motohiro@gmail.com>
|
||||||
|
|
||||||
* random.c (init_hashseed, init_siphash): extract initialize
|
* random.c (init_hashseed, init_siphash): extract initialize
|
||||||
|
62
random.c
62
random.c
@ -1452,24 +1452,9 @@ static union {
|
|||||||
uint32_t u32[(16 * sizeof(uint8_t) - 1) / sizeof(uint32_t)];
|
uint32_t u32[(16 * sizeof(uint8_t) - 1) / sizeof(uint32_t)];
|
||||||
} sipseed;
|
} sipseed;
|
||||||
|
|
||||||
static VALUE
|
|
||||||
init_randomseed(struct MT *mt)
|
|
||||||
{
|
|
||||||
uint32_t initial[DEFAULT_SEED_CNT];
|
|
||||||
VALUE seed;
|
|
||||||
|
|
||||||
fill_random_seed(initial);
|
|
||||||
init_by_array(mt, initial, DEFAULT_SEED_CNT);
|
|
||||||
seed = make_seed_value(initial);
|
|
||||||
explicit_bzero(initial, DEFAULT_SEED_LEN);
|
|
||||||
return seed;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
init_hashseed(void)
|
init_hashseed(struct MT *mt)
|
||||||
{
|
{
|
||||||
struct MT *mt = default_mt();
|
|
||||||
|
|
||||||
hashseed = genrand_int32(mt);
|
hashseed = genrand_int32(mt);
|
||||||
#if SIZEOF_ST_INDEX_T*CHAR_BIT > 4*8
|
#if SIZEOF_ST_INDEX_T*CHAR_BIT > 4*8
|
||||||
hashseed <<= 32;
|
hashseed <<= 32;
|
||||||
@ -1486,9 +1471,8 @@ init_hashseed(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
init_siphash(void)
|
init_siphash(struct MT *mt)
|
||||||
{
|
{
|
||||||
struct MT *mt = default_mt();
|
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < numberof(sipseed.u32); ++i)
|
for (i = 0; i < numberof(sipseed.u32); ++i)
|
||||||
@ -1512,28 +1496,48 @@ rb_memhash(const void *ptr, long len)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Initialize Ruby internal seeds */
|
||||||
void
|
void
|
||||||
Init_RandomSeed(void)
|
Init_RandomSeed(void)
|
||||||
{
|
{
|
||||||
rb_random_t *r = &default_rand;
|
/*
|
||||||
struct MT *mt = &r->mt;
|
Don't reuse this MT for Random::DEFAULT. Random::DEFAULT::seed shouldn't
|
||||||
VALUE seed = init_randomseed(mt);
|
provide a hint that an attacker guess siphash's seed.
|
||||||
|
*/
|
||||||
|
struct MT mt;
|
||||||
|
uint32_t initial_seed[DEFAULT_SEED_CNT];
|
||||||
|
|
||||||
init_hashseed();
|
fill_random_seed(initial_seed);
|
||||||
init_siphash();
|
init_by_array(&mt, initial_seed, DEFAULT_SEED_CNT);
|
||||||
|
|
||||||
rb_global_variable(&r->seed);
|
init_hashseed(&mt);
|
||||||
r->seed = seed;
|
init_siphash(&mt);
|
||||||
|
|
||||||
|
explicit_bzero(initial_seed, DEFAULT_SEED_LEN);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static VALUE
|
||||||
|
init_randomseed(struct MT *mt)
|
||||||
|
{
|
||||||
|
uint32_t initial[DEFAULT_SEED_CNT];
|
||||||
|
VALUE seed;
|
||||||
|
|
||||||
|
fill_random_seed(initial);
|
||||||
|
init_by_array(mt, initial, DEFAULT_SEED_CNT);
|
||||||
|
seed = make_seed_value(initial);
|
||||||
|
explicit_bzero(initial, DEFAULT_SEED_LEN);
|
||||||
|
return seed;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* construct Random::DEFAULT bits */
|
||||||
static void
|
static void
|
||||||
Init_RandomSeed2(void)
|
Init_RandomSeed2(void)
|
||||||
{
|
{
|
||||||
VALUE seed = default_rand.seed;
|
rb_random_t *r = &default_rand;
|
||||||
|
struct MT *mt = &r->mt;
|
||||||
|
|
||||||
if (RB_TYPE_P(seed, T_BIGNUM)) {
|
r->seed = init_randomseed(mt);
|
||||||
rb_obj_reveal(seed, rb_cBignum);
|
rb_global_variable(&r->seed);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -524,4 +524,13 @@ END
|
|||||||
[1, 2].sample(1, random: gen)
|
[1, 2].sample(1, random: gen)
|
||||||
assert_equal(2, gen.limit, bug7935)
|
assert_equal(2, gen.limit, bug7935)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_default_seed
|
||||||
|
assert_separately([], <<-End)
|
||||||
|
seed = Random::DEFAULT::seed
|
||||||
|
rand1 = Random::DEFAULT::rand
|
||||||
|
rand2 = Random.new(seed).rand
|
||||||
|
assert_equal(rand1, rand2)
|
||||||
|
End
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
Loading…
x
Reference in New Issue
Block a user