LibC: Cleanup and fix random functions
I was getting the size of random state incorrectly and ended up with double the size user gave us leading to OOB access :D Also remove hardcoded type -> size mappings and just use a looup table
This commit is contained in:
@@ -625,11 +625,6 @@ static constexpr uint64_t s_rand_multiplier = 6364136223846793005;
|
||||
static constexpr uint64_t s_rand_increment = 1442695040888963407;
|
||||
static uint64_t s_rand_state;
|
||||
|
||||
static constexpr uint32_t rotr32(uint32_t x, unsigned r)
|
||||
{
|
||||
return x >> r | x << (-r & 31);
|
||||
}
|
||||
|
||||
template<BAN::integral T>
|
||||
static inline int rand_impl(T& state)
|
||||
{
|
||||
@@ -644,6 +639,10 @@ static inline int rand_impl(T& state)
|
||||
state = x * s_rand_multiplier + s_rand_increment;
|
||||
x ^= x >> 18;
|
||||
|
||||
constexpr auto rotr32 = [](uint32_t x, unsigned r) {
|
||||
return x >> r | x << (-r & 31);
|
||||
};
|
||||
|
||||
return rotr32(x >> 27, count) % RAND_MAX;
|
||||
}
|
||||
|
||||
@@ -671,25 +670,21 @@ struct random_state_t
|
||||
uint32_t table[];
|
||||
};
|
||||
|
||||
static constexpr size_t s_random_state_sizes[] { 8, 32, 64, 128, 256 };
|
||||
static constexpr size_t s_random_state_size_count = sizeof(s_random_state_sizes) / sizeof(*s_random_state_sizes);
|
||||
|
||||
static char* s_random_state;
|
||||
|
||||
static size_t get_random_state_size()
|
||||
{
|
||||
auto& state = *reinterpret_cast<random_state_t*>(s_random_state);
|
||||
switch (state.type)
|
||||
{
|
||||
case 0: return 8;
|
||||
case 1: return 32;
|
||||
case 2: return 64;
|
||||
case 3: return 128;
|
||||
case 4: return 256;
|
||||
}
|
||||
ASSERT_NOT_REACHED();
|
||||
const auto& state = *reinterpret_cast<random_state_t*>(s_random_state);
|
||||
ASSERT(state.type < s_random_state_size_count);
|
||||
return s_random_state_sizes[state.type];
|
||||
}
|
||||
|
||||
static size_t get_random_table_size()
|
||||
{
|
||||
return get_random_state_size() / sizeof(uint32_t) - 1;
|
||||
return (get_random_state_size() - offsetof(random_state_t, table)) / sizeof(uint32_t);
|
||||
}
|
||||
|
||||
long random(void)
|
||||
@@ -712,22 +707,13 @@ char* initstate(unsigned seed, char* statebuf, size_t size)
|
||||
if (size < 8)
|
||||
return NULL;
|
||||
|
||||
auto& new_state = *reinterpret_cast<random_state_t*>(statebuf);
|
||||
|
||||
if (size < 8)
|
||||
new_state.type = 0;
|
||||
else if (size < 32)
|
||||
new_state.type = 1;
|
||||
else if (size < 64)
|
||||
new_state.type = 2;
|
||||
else if (size < 128)
|
||||
new_state.type = 3;
|
||||
else if (size < 256)
|
||||
new_state.type = 4;
|
||||
|
||||
char* old_state = s_random_state;
|
||||
s_random_state = statebuf;
|
||||
|
||||
auto& new_state = *reinterpret_cast<random_state_t*>(s_random_state);
|
||||
for (size_t i = 0; i < s_random_state_size_count && size >= s_random_state_sizes[i]; i++)
|
||||
new_state.type = i;
|
||||
|
||||
const size_t table_size = get_random_table_size();
|
||||
new_state.idx1 = 0;
|
||||
new_state.idx2 = table_size - 1;
|
||||
|
||||
Reference in New Issue
Block a user