mirror of git://sourceware.org/git/glibc.git
malloc: Make sure tcache_key is odd enough
We want tcache_key not to be a commonly-occurring value in memory, so ensure
a minimum amount of one and zero bits.
And we need it non-zero, otherwise even if tcache_double_free_verify sets
e->key to 0 before calling __libc_free, it gets called again by __libc_free,
thus looping indefinitely.
Fixes: c968fe5062 ("malloc: Use tailcalls in __libc_free")
This commit is contained in:
parent
a6eb8285d9
commit
2536c4f858
|
|
@ -230,6 +230,9 @@
|
|||
/* For uintptr_t. */
|
||||
#include <stdint.h>
|
||||
|
||||
/* For stdc_count_ones. */
|
||||
#include <stdbit.h>
|
||||
|
||||
/* For va_arg, va_start, va_end. */
|
||||
#include <stdarg.h>
|
||||
|
||||
|
|
@ -3095,6 +3098,19 @@ tcache_key_initialize (void)
|
|||
if (__getrandom_nocancel_nostatus_direct (&tcache_key, sizeof(tcache_key),
|
||||
GRND_NONBLOCK)
|
||||
!= sizeof (tcache_key))
|
||||
tcache_key = 0;
|
||||
|
||||
/* We need tcache_key to be non-zero (otherwise tcache_double_free_verify's
|
||||
clearing of e->key would go unnoticed and it would loop getting called
|
||||
through __libc_free), and we want tcache_key not to be a
|
||||
commonly-occurring value in memory, so ensure a minimum amount of one and
|
||||
zero bits. */
|
||||
int minimum_bits = __WORDSIZE / 4;
|
||||
int maximum_bits = __WORDSIZE - minimum_bits;
|
||||
|
||||
while (labs (tcache_key) <= 0x1000000
|
||||
|| stdc_count_ones (tcache_key) < minimum_bits
|
||||
|| stdc_count_ones (tcache_key) > maximum_bits)
|
||||
{
|
||||
tcache_key = random_bits ();
|
||||
#if __WORDSIZE == 64
|
||||
|
|
|
|||
Loading…
Reference in New Issue