forked from rpms/glibc
import glibc-2.28-216.el8
This commit is contained in:
parent
24ac4d3150
commit
108aa5b0a9
245
SOURCES/glibc-rh1871383-1.patch
Normal file
245
SOURCES/glibc-rh1871383-1.patch
Normal file
@ -0,0 +1,245 @@
|
|||||||
|
From a1a486d70ebcc47a686ff5846875eacad0940e41 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Eyal Itkin <eyalit@checkpoint.com>
|
||||||
|
Date: Fri, 20 Mar 2020 21:19:17 +0200
|
||||||
|
Subject: Add Safe-Linking to fastbins and tcache
|
||||||
|
|
||||||
|
Safe-Linking is a security mechanism that protects single-linked
|
||||||
|
lists (such as the fastbin and tcache) from being tampered by attackers.
|
||||||
|
The mechanism makes use of randomness from ASLR (mmap_base), and when
|
||||||
|
combined with chunk alignment integrity checks, it protects the "next"
|
||||||
|
pointers from being hijacked by an attacker.
|
||||||
|
|
||||||
|
While Safe-Unlinking protects double-linked lists (such as the small
|
||||||
|
bins), there wasn't any similar protection for attacks against
|
||||||
|
single-linked lists. This solution protects against 3 common attacks:
|
||||||
|
* Partial pointer override: modifies the lower bytes (Little Endian)
|
||||||
|
* Full pointer override: hijacks the pointer to an attacker's location
|
||||||
|
* Unaligned chunks: pointing the list to an unaligned address
|
||||||
|
|
||||||
|
The design assumes an attacker doesn't know where the heap is located,
|
||||||
|
and uses the ASLR randomness to "sign" the single-linked pointers. We
|
||||||
|
mark the pointer as P and the location in which it is stored as L, and
|
||||||
|
the calculation will be:
|
||||||
|
* PROTECT(P) := (L >> PAGE_SHIFT) XOR (P)
|
||||||
|
* *L = PROTECT(P)
|
||||||
|
|
||||||
|
This way, the random bits from the address L (which start at the bit
|
||||||
|
in the PAGE_SHIFT position), will be merged with LSB of the stored
|
||||||
|
protected pointer. This protection layer prevents an attacker from
|
||||||
|
modifying the pointer into a controlled value.
|
||||||
|
|
||||||
|
An additional check that the chunks are MALLOC_ALIGNed adds an
|
||||||
|
important layer:
|
||||||
|
* Attackers can't point to illegal (unaligned) memory addresses
|
||||||
|
* Attackers must guess correctly the alignment bits
|
||||||
|
|
||||||
|
On standard 32 bit Linux machines, an attack will directly fail 7
|
||||||
|
out of 8 times, and on 64 bit machines it will fail 15 out of 16
|
||||||
|
times.
|
||||||
|
|
||||||
|
This proposed patch was benchmarked and it's effect on the overall
|
||||||
|
performance of the heap was negligible and couldn't be distinguished
|
||||||
|
from the default variance between tests on the vanilla version. A
|
||||||
|
similar protection was added to Chromium's version of TCMalloc
|
||||||
|
in 2012, and according to their documentation it had an overhead of
|
||||||
|
less than 2%.
|
||||||
|
|
||||||
|
Reviewed-by: DJ Delorie <dj@redhat.com>
|
||||||
|
Reviewed-by: Carlos O'Donell <carlos@redhat.com>
|
||||||
|
Reviewed-by: Adhemerval Zacnella <adhemerval.zanella@linaro.org>
|
||||||
|
|
||||||
|
diff --git a/malloc/malloc.c b/malloc/malloc.c
|
||||||
|
index f7cd29bc2f..1282863681 100644
|
||||||
|
--- a/malloc/malloc.c
|
||||||
|
+++ b/malloc/malloc.c
|
||||||
|
@@ -327,6 +327,18 @@ __malloc_assert (const char *assertion, const char *file, unsigned int line,
|
||||||
|
# define MAX_TCACHE_COUNT UINT16_MAX
|
||||||
|
#endif
|
||||||
|
|
||||||
|
+/* Safe-Linking:
|
||||||
|
+ Use randomness from ASLR (mmap_base) to protect single-linked lists
|
||||||
|
+ of Fast-Bins and TCache. That is, mask the "next" pointers of the
|
||||||
|
+ lists' chunks, and also perform allocation alignment checks on them.
|
||||||
|
+ This mechanism reduces the risk of pointer hijacking, as was done with
|
||||||
|
+ Safe-Unlinking in the double-linked lists of Small-Bins.
|
||||||
|
+ It assumes a minimum page size of 4096 bytes (12 bits). Systems with
|
||||||
|
+ larger pages provide less entropy, although the pointer mangling
|
||||||
|
+ still works. */
|
||||||
|
+#define PROTECT_PTR(pos, ptr) \
|
||||||
|
+ ((__typeof (ptr)) ((((size_t) pos) >> 12) ^ ((size_t) ptr)))
|
||||||
|
+#define REVEAL_PTR(ptr) PROTECT_PTR (&ptr, ptr)
|
||||||
|
|
||||||
|
/*
|
||||||
|
REALLOC_ZERO_BYTES_FREES should be set if a call to
|
||||||
|
@@ -2157,12 +2169,15 @@ do_check_malloc_state (mstate av)
|
||||||
|
|
||||||
|
while (p != 0)
|
||||||
|
{
|
||||||
|
+ if (__glibc_unlikely (!aligned_OK (p)))
|
||||||
|
+ malloc_printerr ("do_check_malloc_state(): " \
|
||||||
|
+ "unaligned fastbin chunk detected");
|
||||||
|
/* each chunk claims to be inuse */
|
||||||
|
do_check_inuse_chunk (av, p);
|
||||||
|
total += chunksize (p);
|
||||||
|
/* chunk belongs in this bin */
|
||||||
|
assert (fastbin_index (chunksize (p)) == i);
|
||||||
|
- p = p->fd;
|
||||||
|
+ p = REVEAL_PTR (p->fd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -2923,7 +2938,7 @@ tcache_put (mchunkptr chunk, size_t tc_idx)
|
||||||
|
detect a double free. */
|
||||||
|
e->key = tcache;
|
||||||
|
|
||||||
|
- e->next = tcache->entries[tc_idx];
|
||||||
|
+ e->next = PROTECT_PTR (&e->next, tcache->entries[tc_idx]);
|
||||||
|
tcache->entries[tc_idx] = e;
|
||||||
|
++(tcache->counts[tc_idx]);
|
||||||
|
}
|
||||||
|
@@ -2934,9 +2949,11 @@ static __always_inline void *
|
||||||
|
tcache_get (size_t tc_idx)
|
||||||
|
{
|
||||||
|
tcache_entry *e = tcache->entries[tc_idx];
|
||||||
|
- tcache->entries[tc_idx] = e->next;
|
||||||
|
+ tcache->entries[tc_idx] = REVEAL_PTR (e->next);
|
||||||
|
--(tcache->counts[tc_idx]);
|
||||||
|
e->key = NULL;
|
||||||
|
+ if (__glibc_unlikely (!aligned_OK (e)))
|
||||||
|
+ malloc_printerr ("malloc(): unaligned tcache chunk detected");
|
||||||
|
return (void *) e;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -2960,7 +2977,10 @@ tcache_thread_shutdown (void)
|
||||||
|
while (tcache_tmp->entries[i])
|
||||||
|
{
|
||||||
|
tcache_entry *e = tcache_tmp->entries[i];
|
||||||
|
- tcache_tmp->entries[i] = e->next;
|
||||||
|
+ if (__glibc_unlikely (!aligned_OK (e)))
|
||||||
|
+ malloc_printerr ("tcache_thread_shutdown(): " \
|
||||||
|
+ "unaligned tcache chunk detected");
|
||||||
|
+ tcache_tmp->entries[i] = REVEAL_PTR (e->next);
|
||||||
|
__libc_free (e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -3570,8 +3590,11 @@ _int_malloc (mstate av, size_t bytes)
|
||||||
|
victim = pp; \
|
||||||
|
if (victim == NULL) \
|
||||||
|
break; \
|
||||||
|
+ pp = REVEAL_PTR (victim->fd); \
|
||||||
|
+ if (__glibc_unlikely (!aligned_OK (pp))) \
|
||||||
|
+ malloc_printerr ("malloc(): unaligned fastbin chunk detected"); \
|
||||||
|
} \
|
||||||
|
- while ((pp = catomic_compare_and_exchange_val_acq (fb, victim->fd, victim)) \
|
||||||
|
+ while ((pp = catomic_compare_and_exchange_val_acq (fb, pp, victim)) \
|
||||||
|
!= victim); \
|
||||||
|
|
||||||
|
if ((unsigned long) (nb) <= (unsigned long) (get_max_fast ()))
|
||||||
|
@@ -3583,8 +3606,11 @@ _int_malloc (mstate av, size_t bytes)
|
||||||
|
|
||||||
|
if (victim != NULL)
|
||||||
|
{
|
||||||
|
+ if (__glibc_unlikely (!aligned_OK (victim)))
|
||||||
|
+ malloc_printerr ("malloc(): unaligned fastbin chunk detected");
|
||||||
|
+
|
||||||
|
if (SINGLE_THREAD_P)
|
||||||
|
- *fb = victim->fd;
|
||||||
|
+ *fb = REVEAL_PTR (victim->fd);
|
||||||
|
else
|
||||||
|
REMOVE_FB (fb, pp, victim);
|
||||||
|
if (__glibc_likely (victim != NULL))
|
||||||
|
@@ -3605,8 +3631,10 @@ _int_malloc (mstate av, size_t bytes)
|
||||||
|
while (tcache->counts[tc_idx] < mp_.tcache_count
|
||||||
|
&& (tc_victim = *fb) != NULL)
|
||||||
|
{
|
||||||
|
+ if (__glibc_unlikely (!aligned_OK (tc_victim)))
|
||||||
|
+ malloc_printerr ("malloc(): unaligned fastbin chunk detected");
|
||||||
|
if (SINGLE_THREAD_P)
|
||||||
|
- *fb = tc_victim->fd;
|
||||||
|
+ *fb = REVEAL_PTR (tc_victim->fd);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
REMOVE_FB (fb, pp, tc_victim);
|
||||||
|
@@ -4196,11 +4224,15 @@ _int_free (mstate av, mchunkptr p, int have_lock)
|
||||||
|
LIBC_PROBE (memory_tcache_double_free, 2, e, tc_idx);
|
||||||
|
for (tmp = tcache->entries[tc_idx];
|
||||||
|
tmp;
|
||||||
|
- tmp = tmp->next)
|
||||||
|
+ tmp = REVEAL_PTR (tmp->next))
|
||||||
|
+ {
|
||||||
|
+ if (__glibc_unlikely (!aligned_OK (tmp)))
|
||||||
|
+ malloc_printerr ("free(): unaligned chunk detected in tcache 2");
|
||||||
|
if (tmp == e)
|
||||||
|
malloc_printerr ("free(): double free detected in tcache 2");
|
||||||
|
/* If we get here, it was a coincidence. We've wasted a
|
||||||
|
few cycles, but don't abort. */
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tcache->counts[tc_idx] < mp_.tcache_count)
|
||||||
|
@@ -4264,7 +4296,7 @@ _int_free (mstate av, mchunkptr p, int have_lock)
|
||||||
|
add (i.e., double free). */
|
||||||
|
if (__builtin_expect (old == p, 0))
|
||||||
|
malloc_printerr ("double free or corruption (fasttop)");
|
||||||
|
- p->fd = old;
|
||||||
|
+ p->fd = PROTECT_PTR (&p->fd, old);
|
||||||
|
*fb = p;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
@@ -4274,7 +4306,8 @@ _int_free (mstate av, mchunkptr p, int have_lock)
|
||||||
|
add (i.e., double free). */
|
||||||
|
if (__builtin_expect (old == p, 0))
|
||||||
|
malloc_printerr ("double free or corruption (fasttop)");
|
||||||
|
- p->fd = old2 = old;
|
||||||
|
+ old2 = old;
|
||||||
|
+ p->fd = PROTECT_PTR (&p->fd, old);
|
||||||
|
}
|
||||||
|
while ((old = catomic_compare_and_exchange_val_rel (fb, p, old2))
|
||||||
|
!= old2);
|
||||||
|
@@ -4472,13 +4505,17 @@ static void malloc_consolidate(mstate av)
|
||||||
|
if (p != 0) {
|
||||||
|
do {
|
||||||
|
{
|
||||||
|
+ if (__glibc_unlikely (!aligned_OK (p)))
|
||||||
|
+ malloc_printerr ("malloc_consolidate(): " \
|
||||||
|
+ "unaligned fastbin chunk detected");
|
||||||
|
+
|
||||||
|
unsigned int idx = fastbin_index (chunksize (p));
|
||||||
|
if ((&fastbin (av, idx)) != fb)
|
||||||
|
malloc_printerr ("malloc_consolidate(): invalid chunk size");
|
||||||
|
}
|
||||||
|
|
||||||
|
check_inuse_chunk(av, p);
|
||||||
|
- nextp = p->fd;
|
||||||
|
+ nextp = REVEAL_PTR (p->fd);
|
||||||
|
|
||||||
|
/* Slightly streamlined version of consolidation code in free() */
|
||||||
|
size = chunksize (p);
|
||||||
|
@@ -4896,8 +4933,13 @@ int_mallinfo (mstate av, struct mallinfo *m)
|
||||||
|
|
||||||
|
for (i = 0; i < NFASTBINS; ++i)
|
||||||
|
{
|
||||||
|
- for (p = fastbin (av, i); p != 0; p = p->fd)
|
||||||
|
+ for (p = fastbin (av, i);
|
||||||
|
+ p != 0;
|
||||||
|
+ p = REVEAL_PTR (p->fd))
|
||||||
|
{
|
||||||
|
+ if (__glibc_unlikely (!aligned_OK (p)))
|
||||||
|
+ malloc_printerr ("int_mallinfo(): " \
|
||||||
|
+ "unaligned fastbin chunk detected");
|
||||||
|
++nfastblocks;
|
||||||
|
fastavail += chunksize (p);
|
||||||
|
}
|
||||||
|
@@ -5437,8 +5479,11 @@ __malloc_info (int options, FILE *fp)
|
||||||
|
|
||||||
|
while (p != NULL)
|
||||||
|
{
|
||||||
|
+ if (__glibc_unlikely (!aligned_OK (p)))
|
||||||
|
+ malloc_printerr ("__malloc_info(): " \
|
||||||
|
+ "unaligned fastbin chunk detected");
|
||||||
|
++nthissize;
|
||||||
|
- p = p->fd;
|
||||||
|
+ p = REVEAL_PTR (p->fd);
|
||||||
|
}
|
||||||
|
|
||||||
|
fastavail += nthissize * thissize;
|
87
SOURCES/glibc-rh1871383-2.patch
Normal file
87
SOURCES/glibc-rh1871383-2.patch
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
From 768358b6a80742f6be68ecd9f952f4b60614df96 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Eyal Itkin <eyalit@checkpoint.com>
|
||||||
|
Date: Tue, 31 Mar 2020 01:55:13 -0400
|
||||||
|
Subject: Typo fixes and CR cleanup in Safe-Linking
|
||||||
|
|
||||||
|
Removed unneeded '\' chars from end of lines and fixed some
|
||||||
|
indentation issues that were introduced in the original
|
||||||
|
Safe-Linking patch.
|
||||||
|
|
||||||
|
Reviewed-by: Carlos O'Donell <carlos@redhat.com>
|
||||||
|
|
||||||
|
diff --git a/malloc/malloc.c b/malloc/malloc.c
|
||||||
|
index 1282863681..0e4acb22f6 100644
|
||||||
|
--- a/malloc/malloc.c
|
||||||
|
+++ b/malloc/malloc.c
|
||||||
|
@@ -2170,7 +2170,7 @@ do_check_malloc_state (mstate av)
|
||||||
|
while (p != 0)
|
||||||
|
{
|
||||||
|
if (__glibc_unlikely (!aligned_OK (p)))
|
||||||
|
- malloc_printerr ("do_check_malloc_state(): " \
|
||||||
|
+ malloc_printerr ("do_check_malloc_state(): "
|
||||||
|
"unaligned fastbin chunk detected");
|
||||||
|
/* each chunk claims to be inuse */
|
||||||
|
do_check_inuse_chunk (av, p);
|
||||||
|
@@ -2977,9 +2977,9 @@ tcache_thread_shutdown (void)
|
||||||
|
while (tcache_tmp->entries[i])
|
||||||
|
{
|
||||||
|
tcache_entry *e = tcache_tmp->entries[i];
|
||||||
|
- if (__glibc_unlikely (!aligned_OK (e)))
|
||||||
|
- malloc_printerr ("tcache_thread_shutdown(): " \
|
||||||
|
- "unaligned tcache chunk detected");
|
||||||
|
+ if (__glibc_unlikely (!aligned_OK (e)))
|
||||||
|
+ malloc_printerr ("tcache_thread_shutdown(): "
|
||||||
|
+ "unaligned tcache chunk detected");
|
||||||
|
tcache_tmp->entries[i] = REVEAL_PTR (e->next);
|
||||||
|
__libc_free (e);
|
||||||
|
}
|
||||||
|
@@ -4225,14 +4225,14 @@ _int_free (mstate av, mchunkptr p, int have_lock)
|
||||||
|
for (tmp = tcache->entries[tc_idx];
|
||||||
|
tmp;
|
||||||
|
tmp = REVEAL_PTR (tmp->next))
|
||||||
|
- {
|
||||||
|
- if (__glibc_unlikely (!aligned_OK (tmp)))
|
||||||
|
- malloc_printerr ("free(): unaligned chunk detected in tcache 2");
|
||||||
|
- if (tmp == e)
|
||||||
|
- malloc_printerr ("free(): double free detected in tcache 2");
|
||||||
|
- /* If we get here, it was a coincidence. We've wasted a
|
||||||
|
- few cycles, but don't abort. */
|
||||||
|
- }
|
||||||
|
+ {
|
||||||
|
+ if (__glibc_unlikely (!aligned_OK (tmp)))
|
||||||
|
+ malloc_printerr ("free(): unaligned chunk detected in tcache 2");
|
||||||
|
+ if (tmp == e)
|
||||||
|
+ malloc_printerr ("free(): double free detected in tcache 2");
|
||||||
|
+ /* If we get here, it was a coincidence. We've wasted a
|
||||||
|
+ few cycles, but don't abort. */
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tcache->counts[tc_idx] < mp_.tcache_count)
|
||||||
|
@@ -4506,7 +4506,7 @@ static void malloc_consolidate(mstate av)
|
||||||
|
do {
|
||||||
|
{
|
||||||
|
if (__glibc_unlikely (!aligned_OK (p)))
|
||||||
|
- malloc_printerr ("malloc_consolidate(): " \
|
||||||
|
+ malloc_printerr ("malloc_consolidate(): "
|
||||||
|
"unaligned fastbin chunk detected");
|
||||||
|
|
||||||
|
unsigned int idx = fastbin_index (chunksize (p));
|
||||||
|
@@ -4938,7 +4938,7 @@ int_mallinfo (mstate av, struct mallinfo *m)
|
||||||
|
p = REVEAL_PTR (p->fd))
|
||||||
|
{
|
||||||
|
if (__glibc_unlikely (!aligned_OK (p)))
|
||||||
|
- malloc_printerr ("int_mallinfo(): " \
|
||||||
|
+ malloc_printerr ("int_mallinfo(): "
|
||||||
|
"unaligned fastbin chunk detected");
|
||||||
|
++nfastblocks;
|
||||||
|
fastavail += chunksize (p);
|
||||||
|
@@ -5480,7 +5480,7 @@ __malloc_info (int options, FILE *fp)
|
||||||
|
while (p != NULL)
|
||||||
|
{
|
||||||
|
if (__glibc_unlikely (!aligned_OK (p)))
|
||||||
|
- malloc_printerr ("__malloc_info(): " \
|
||||||
|
+ malloc_printerr ("__malloc_info(): "
|
||||||
|
"unaligned fastbin chunk detected");
|
||||||
|
++nthissize;
|
||||||
|
p = REVEAL_PTR (p->fd);
|
100
SOURCES/glibc-rh1871383-3.patch
Normal file
100
SOURCES/glibc-rh1871383-3.patch
Normal file
@ -0,0 +1,100 @@
|
|||||||
|
From 49c3c37651e2d2ec4ff8ce21252bbbc08a9d6639 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Eyal Itkin <eyalit@checkpoint.com>
|
||||||
|
Date: Tue, 31 Mar 2020 02:00:14 -0400
|
||||||
|
Subject: Fix alignment bug in Safe-Linking
|
||||||
|
|
||||||
|
Alignment checks should be performed on the user's buffer and NOT
|
||||||
|
on the mchunkptr as was done before. This caused bugs in 32 bit
|
||||||
|
versions, because: 2*sizeof(t) != MALLOC_ALIGNMENT.
|
||||||
|
|
||||||
|
As the tcache works on users' buffers it uses the aligned_OK()
|
||||||
|
check, and the rest work on mchunkptr and therefore check using
|
||||||
|
misaligned_chunk().
|
||||||
|
|
||||||
|
Reviewed-by: Carlos O'Donell <carlos@redhat.com>
|
||||||
|
|
||||||
|
diff --git a/malloc/malloc.c b/malloc/malloc.c
|
||||||
|
index 0e4acb22f6..6acb5ad43a 100644
|
||||||
|
--- a/malloc/malloc.c
|
||||||
|
+++ b/malloc/malloc.c
|
||||||
|
@@ -2169,7 +2169,7 @@ do_check_malloc_state (mstate av)
|
||||||
|
|
||||||
|
while (p != 0)
|
||||||
|
{
|
||||||
|
- if (__glibc_unlikely (!aligned_OK (p)))
|
||||||
|
+ if (__glibc_unlikely (misaligned_chunk (p)))
|
||||||
|
malloc_printerr ("do_check_malloc_state(): "
|
||||||
|
"unaligned fastbin chunk detected");
|
||||||
|
/* each chunk claims to be inuse */
|
||||||
|
@@ -2949,11 +2949,11 @@ static __always_inline void *
|
||||||
|
tcache_get (size_t tc_idx)
|
||||||
|
{
|
||||||
|
tcache_entry *e = tcache->entries[tc_idx];
|
||||||
|
+ if (__glibc_unlikely (!aligned_OK (e)))
|
||||||
|
+ malloc_printerr ("malloc(): unaligned tcache chunk detected");
|
||||||
|
tcache->entries[tc_idx] = REVEAL_PTR (e->next);
|
||||||
|
--(tcache->counts[tc_idx]);
|
||||||
|
e->key = NULL;
|
||||||
|
- if (__glibc_unlikely (!aligned_OK (e)))
|
||||||
|
- malloc_printerr ("malloc(): unaligned tcache chunk detected");
|
||||||
|
return (void *) e;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -3591,7 +3591,7 @@ _int_malloc (mstate av, size_t bytes)
|
||||||
|
if (victim == NULL) \
|
||||||
|
break; \
|
||||||
|
pp = REVEAL_PTR (victim->fd); \
|
||||||
|
- if (__glibc_unlikely (!aligned_OK (pp))) \
|
||||||
|
+ if (__glibc_unlikely (pp != NULL && misaligned_chunk (pp))) \
|
||||||
|
malloc_printerr ("malloc(): unaligned fastbin chunk detected"); \
|
||||||
|
} \
|
||||||
|
while ((pp = catomic_compare_and_exchange_val_acq (fb, pp, victim)) \
|
||||||
|
@@ -3606,8 +3606,8 @@ _int_malloc (mstate av, size_t bytes)
|
||||||
|
|
||||||
|
if (victim != NULL)
|
||||||
|
{
|
||||||
|
- if (__glibc_unlikely (!aligned_OK (victim)))
|
||||||
|
- malloc_printerr ("malloc(): unaligned fastbin chunk detected");
|
||||||
|
+ if (__glibc_unlikely (misaligned_chunk (victim)))
|
||||||
|
+ malloc_printerr ("malloc(): unaligned fastbin chunk detected 2");
|
||||||
|
|
||||||
|
if (SINGLE_THREAD_P)
|
||||||
|
*fb = REVEAL_PTR (victim->fd);
|
||||||
|
@@ -3631,8 +3631,8 @@ _int_malloc (mstate av, size_t bytes)
|
||||||
|
while (tcache->counts[tc_idx] < mp_.tcache_count
|
||||||
|
&& (tc_victim = *fb) != NULL)
|
||||||
|
{
|
||||||
|
- if (__glibc_unlikely (!aligned_OK (tc_victim)))
|
||||||
|
- malloc_printerr ("malloc(): unaligned fastbin chunk detected");
|
||||||
|
+ if (__glibc_unlikely (misaligned_chunk (tc_victim)))
|
||||||
|
+ malloc_printerr ("malloc(): unaligned fastbin chunk detected 3");
|
||||||
|
if (SINGLE_THREAD_P)
|
||||||
|
*fb = REVEAL_PTR (tc_victim->fd);
|
||||||
|
else
|
||||||
|
@@ -4505,7 +4505,7 @@ static void malloc_consolidate(mstate av)
|
||||||
|
if (p != 0) {
|
||||||
|
do {
|
||||||
|
{
|
||||||
|
- if (__glibc_unlikely (!aligned_OK (p)))
|
||||||
|
+ if (__glibc_unlikely (misaligned_chunk (p)))
|
||||||
|
malloc_printerr ("malloc_consolidate(): "
|
||||||
|
"unaligned fastbin chunk detected");
|
||||||
|
|
||||||
|
@@ -4937,7 +4937,7 @@ int_mallinfo (mstate av, struct mallinfo *m)
|
||||||
|
p != 0;
|
||||||
|
p = REVEAL_PTR (p->fd))
|
||||||
|
{
|
||||||
|
- if (__glibc_unlikely (!aligned_OK (p)))
|
||||||
|
+ if (__glibc_unlikely (misaligned_chunk (p)))
|
||||||
|
malloc_printerr ("int_mallinfo(): "
|
||||||
|
"unaligned fastbin chunk detected");
|
||||||
|
++nfastblocks;
|
||||||
|
@@ -5479,7 +5479,7 @@ __malloc_info (int options, FILE *fp)
|
||||||
|
|
||||||
|
while (p != NULL)
|
||||||
|
{
|
||||||
|
- if (__glibc_unlikely (!aligned_OK (p)))
|
||||||
|
+ if (__glibc_unlikely (misaligned_chunk (p)))
|
||||||
|
malloc_printerr ("__malloc_info(): "
|
||||||
|
"unaligned fastbin chunk detected");
|
||||||
|
++nthissize;
|
215
SOURCES/glibc-rh1871383-4.patch
Normal file
215
SOURCES/glibc-rh1871383-4.patch
Normal file
@ -0,0 +1,215 @@
|
|||||||
|
From 6310d570bf20348135d09e1f9de84a9ae7d06f83 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Eyal Itkin <eyalit@checkpoint.com>
|
||||||
|
Date: Thu, 2 Apr 2020 07:26:35 -0400
|
||||||
|
Subject: Add tests for Safe-Linking
|
||||||
|
|
||||||
|
Adding the test "tst-safe-linking" for testing that Safe-Linking works
|
||||||
|
as expected. The test checks these 3 main flows:
|
||||||
|
* tcache protection
|
||||||
|
* fastbin protection
|
||||||
|
* malloc_consolidate() correctness
|
||||||
|
|
||||||
|
As there is a random chance of 1/16 that of the alignment will remain
|
||||||
|
correct, the test checks each flow up to 10 times, using different random
|
||||||
|
values for the pointer corruption. As a result, the chance for a false
|
||||||
|
failure of a given tested flow is 2**(-40), thus highly unlikely.
|
||||||
|
|
||||||
|
Reviewed-by: Carlos O'Donell <carlos@redhat.com>
|
||||||
|
|
||||||
|
diff --git a/malloc/Makefile b/malloc/Makefile
|
||||||
|
index 984045b5b9..e22cbde22d 100644
|
||||||
|
--- a/malloc/Makefile
|
||||||
|
+++ b/malloc/Makefile
|
||||||
|
@@ -39,6 +39,7 @@ tests := mallocbug tst-malloc tst-valloc tst-calloc tst-obstack \
|
||||||
|
tst-malloc-too-large \
|
||||||
|
tst-malloc-stats-cancellation \
|
||||||
|
tst-tcfree1 tst-tcfree2 tst-tcfree3 \
|
||||||
|
+ tst-safe-linking \
|
||||||
|
|
||||||
|
tests-static := \
|
||||||
|
tst-interpose-static-nothread \
|
||||||
|
diff --git a/malloc/tst-safe-linking.c b/malloc/tst-safe-linking.c
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000..067b6c09cf
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/malloc/tst-safe-linking.c
|
||||||
|
@@ -0,0 +1,179 @@
|
||||||
|
+/* Test reporting of Safe-Linking caught errors.
|
||||||
|
+ Copyright (C) 2020 Free Software Foundation, Inc.
|
||||||
|
+ This file is part of the GNU C Library.
|
||||||
|
+
|
||||||
|
+ The GNU C Library is free software; you can redistribute it and/or
|
||||||
|
+ modify it under the terms of the GNU Lesser General Public
|
||||||
|
+ License as published by the Free Software Foundation; either
|
||||||
|
+ version 2.1 of the License, or (at your option) any later version.
|
||||||
|
+
|
||||||
|
+ The GNU C Library is distributed in the hope that it will be useful,
|
||||||
|
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
+ Lesser General Public License for more details.
|
||||||
|
+
|
||||||
|
+ You should have received a copy of the GNU Lesser General Public
|
||||||
|
+ License along with the GNU C Library; if not, see
|
||||||
|
+ <https://www.gnu.org/licenses/>. */
|
||||||
|
+
|
||||||
|
+#include <signal.h>
|
||||||
|
+#include <stdint.h>
|
||||||
|
+#include <stdlib.h>
|
||||||
|
+#include <memory.h>
|
||||||
|
+#include <string.h>
|
||||||
|
+#include <time.h>
|
||||||
|
+#include <stdbool.h>
|
||||||
|
+#include <support/capture_subprocess.h>
|
||||||
|
+#include <support/check.h>
|
||||||
|
+
|
||||||
|
+/* Run CALLBACK and check that the data on standard error equals
|
||||||
|
+ EXPECTED. */
|
||||||
|
+static void
|
||||||
|
+check (const char *test, void (*callback) (void *),
|
||||||
|
+ const char *expected)
|
||||||
|
+{
|
||||||
|
+ int i, rand_mask;
|
||||||
|
+ bool success = false;
|
||||||
|
+ /* There is a chance of 1/16 that a corrupted pointer will be aligned.
|
||||||
|
+ Try multiple times so that statistical failure will be improbable. */
|
||||||
|
+ for (i = 0; i < 10 && !success; ++i)
|
||||||
|
+ {
|
||||||
|
+ rand_mask = rand () & 0xFF;
|
||||||
|
+ struct support_capture_subprocess result
|
||||||
|
+ = support_capture_subprocess (callback, &rand_mask);
|
||||||
|
+ /* Did not crash, could happen. Try again. */
|
||||||
|
+ if (strlen (result.err.buffer) == 0)
|
||||||
|
+ continue;
|
||||||
|
+ /* Crashed, must be the expected result. */
|
||||||
|
+ if (strcmp (result.err.buffer, expected) != 0)
|
||||||
|
+ {
|
||||||
|
+ support_record_failure ();
|
||||||
|
+ printf ("error: test %s unexpected standard error data\n"
|
||||||
|
+ " expected: %s\n"
|
||||||
|
+ " actual: %s\n",
|
||||||
|
+ test, expected, result.err.buffer);
|
||||||
|
+ }
|
||||||
|
+ TEST_VERIFY (WIFSIGNALED (result.status));
|
||||||
|
+ if (WIFSIGNALED (result.status))
|
||||||
|
+ TEST_VERIFY (WTERMSIG (result.status) == SIGABRT);
|
||||||
|
+ support_capture_subprocess_free (&result);
|
||||||
|
+ success = true;
|
||||||
|
+ }
|
||||||
|
+ TEST_VERIFY (success);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/* Implementation details must be kept in sync with malloc. */
|
||||||
|
+#define TCACHE_FILL_COUNT 7
|
||||||
|
+#define TCACHE_ALLOC_SIZE 0x20
|
||||||
|
+#define MALLOC_CONSOLIDATE_SIZE 256*1024
|
||||||
|
+
|
||||||
|
+/* Try corrupting the tcache list. */
|
||||||
|
+static void
|
||||||
|
+test_tcache (void *closure)
|
||||||
|
+{
|
||||||
|
+ int mask = ((int *)closure)[0];
|
||||||
|
+ size_t size = TCACHE_ALLOC_SIZE;
|
||||||
|
+
|
||||||
|
+ /* Populate the tcache list. */
|
||||||
|
+ void * volatile a = malloc (size);
|
||||||
|
+ void * volatile b = malloc (size);
|
||||||
|
+ void * volatile c = malloc (size);
|
||||||
|
+ free (a);
|
||||||
|
+ free (b);
|
||||||
|
+ free (c);
|
||||||
|
+
|
||||||
|
+ /* Corrupt the pointer with a random value, and avoid optimizations. */
|
||||||
|
+ printf ("Before: c=%p, c[0]=%p\n", c, ((void **)c)[0]);
|
||||||
|
+ memset (c, mask & 0xFF, size);
|
||||||
|
+ printf ("After: c=%p, c[0]=%p\n", c, ((void **)c)[0]);
|
||||||
|
+
|
||||||
|
+ c = malloc (size);
|
||||||
|
+ /* This line will trigger the Safe-Linking check. */
|
||||||
|
+ b = malloc (size);
|
||||||
|
+ printf ("b=%p\n", b);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/* Try corrupting the fastbin list. */
|
||||||
|
+static void
|
||||||
|
+test_fastbin (void *closure)
|
||||||
|
+{
|
||||||
|
+ int i;
|
||||||
|
+ int mask = ((int *)closure)[0];
|
||||||
|
+ size_t size = TCACHE_ALLOC_SIZE;
|
||||||
|
+
|
||||||
|
+ /* Take the tcache out of the game. */
|
||||||
|
+ for (i = 0; i < TCACHE_FILL_COUNT; ++i)
|
||||||
|
+ {
|
||||||
|
+ void * volatile p = calloc (1, size);
|
||||||
|
+ free (p);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* Populate the fastbin list. */
|
||||||
|
+ void * volatile a = calloc (1, size);
|
||||||
|
+ void * volatile b = calloc (1, size);
|
||||||
|
+ void * volatile c = calloc (1, size);
|
||||||
|
+ free (a);
|
||||||
|
+ free (b);
|
||||||
|
+ free (c);
|
||||||
|
+
|
||||||
|
+ /* Corrupt the pointer with a random value, and avoid optimizations. */
|
||||||
|
+ printf ("Before: c=%p, c[0]=%p\n", c, ((void **)c)[0]);
|
||||||
|
+ memset (c, mask & 0xFF, size);
|
||||||
|
+ printf ("After: c=%p, c[0]=%p\n", c, ((void **)c)[0]);
|
||||||
|
+
|
||||||
|
+ c = calloc (1, size);
|
||||||
|
+ /* This line will trigger the Safe-Linking check. */
|
||||||
|
+ b = calloc (1, size);
|
||||||
|
+ printf ("b=%p\n", b);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/* Try corrupting the fastbin list and trigger a consolidate. */
|
||||||
|
+static void
|
||||||
|
+test_fastbin_consolidate (void *closure)
|
||||||
|
+{
|
||||||
|
+ int i;
|
||||||
|
+ int mask = ((int*)closure)[0];
|
||||||
|
+ size_t size = TCACHE_ALLOC_SIZE;
|
||||||
|
+
|
||||||
|
+ /* Take the tcache out of the game. */
|
||||||
|
+ for (i = 0; i < TCACHE_FILL_COUNT; ++i)
|
||||||
|
+ {
|
||||||
|
+ void * volatile p = calloc (1, size);
|
||||||
|
+ free (p);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* Populate the fastbin list. */
|
||||||
|
+ void * volatile a = calloc (1, size);
|
||||||
|
+ void * volatile b = calloc (1, size);
|
||||||
|
+ void * volatile c = calloc (1, size);
|
||||||
|
+ free (a);
|
||||||
|
+ free (b);
|
||||||
|
+ free (c);
|
||||||
|
+
|
||||||
|
+ /* Corrupt the pointer with a random value, and avoid optimizations. */
|
||||||
|
+ printf ("Before: c=%p, c[0]=%p\n", c, ((void **)c)[0]);
|
||||||
|
+ memset (c, mask & 0xFF, size);
|
||||||
|
+ printf ("After: c=%p, c[0]=%p\n", c, ((void **)c)[0]);
|
||||||
|
+
|
||||||
|
+ /* This line will trigger the Safe-Linking check. */
|
||||||
|
+ b = malloc (MALLOC_CONSOLIDATE_SIZE);
|
||||||
|
+ printf ("b=%p\n", b);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int
|
||||||
|
+do_test (void)
|
||||||
|
+{
|
||||||
|
+ /* Seed the random for the test. */
|
||||||
|
+ srand (time (NULL));
|
||||||
|
+
|
||||||
|
+ check ("test_tcache", test_tcache,
|
||||||
|
+ "malloc(): unaligned tcache chunk detected\n");
|
||||||
|
+ check ("test_fastbin", test_fastbin,
|
||||||
|
+ "malloc(): unaligned fastbin chunk detected 2\n");
|
||||||
|
+ check ("test_fastbin_consolidate", test_fastbin_consolidate,
|
||||||
|
+ "malloc_consolidate(): unaligned fastbin chunk detected\n");
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+#include <support/test-driver.c>
|
35
SOURCES/glibc-rh1871383-5.patch
Normal file
35
SOURCES/glibc-rh1871383-5.patch
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
From b9cde4e3aa1ff338da7064daf1386b2f4a7351ba Mon Sep 17 00:00:00 2001
|
||||||
|
From: DJ Delorie <dj@redhat.com>
|
||||||
|
Date: Sat, 4 Apr 2020 01:44:56 -0400
|
||||||
|
Subject: malloc: ensure set_max_fast never stores zero [BZ #25733]
|
||||||
|
|
||||||
|
The code for set_max_fast() stores an "impossibly small value"
|
||||||
|
instead of zero, when the parameter is zero. However, for
|
||||||
|
small values of the parameter (ex: 1 or 2) the computation
|
||||||
|
results in a zero being stored anyway.
|
||||||
|
|
||||||
|
This patch checks for the parameter being small enough for the
|
||||||
|
computation to result in zero instead, so that a zero is never
|
||||||
|
stored.
|
||||||
|
|
||||||
|
key values which result in zero being stored:
|
||||||
|
|
||||||
|
x86-64: 1..7 (or other 64-bit)
|
||||||
|
i686: 1..11
|
||||||
|
armhfp: 1..3 (or other 32-bit)
|
||||||
|
|
||||||
|
Reviewed-by: Carlos O'Donell <carlos@redhat.com>
|
||||||
|
|
||||||
|
diff --git a/malloc/malloc.c b/malloc/malloc.c
|
||||||
|
index 6acb5ad43a..ee87ddbbf9 100644
|
||||||
|
--- a/malloc/malloc.c
|
||||||
|
+++ b/malloc/malloc.c
|
||||||
|
@@ -1632,7 +1632,7 @@ static INTERNAL_SIZE_T global_max_fast;
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define set_max_fast(s) \
|
||||||
|
- global_max_fast = (((s) == 0) \
|
||||||
|
+ global_max_fast = (((size_t) (s) <= MALLOC_ALIGN_MASK - SIZE_SZ) \
|
||||||
|
? MIN_CHUNK_SIZE / 2 : ((s + SIZE_SZ) & ~MALLOC_ALIGN_MASK))
|
||||||
|
|
||||||
|
static inline INTERNAL_SIZE_T
|
35
SOURCES/glibc-rh1871383-6.patch
Normal file
35
SOURCES/glibc-rh1871383-6.patch
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
From 0e00b35704e67c499c3abfbd5b6224a13d38b012 Mon Sep 17 00:00:00 2001
|
||||||
|
From: "W. Hashimoto" <ssmallkirby@gmail.com>
|
||||||
|
Date: Fri, 11 Dec 2020 16:59:10 -0500
|
||||||
|
Subject: malloc: Detect infinite-loop in _int_free when freeing tcache
|
||||||
|
[BZ#27052]
|
||||||
|
|
||||||
|
If linked-list of tcache contains a loop, it invokes infinite
|
||||||
|
loop in _int_free when freeing tcache. The PoC which invokes
|
||||||
|
such infinite loop is on the Bugzilla(#27052). This loop
|
||||||
|
should terminate when the loop exceeds mp_.tcache_count and
|
||||||
|
the program should abort. The affected glibc version is
|
||||||
|
2.29 or later.
|
||||||
|
|
||||||
|
Reviewed-by: DJ Delorie <dj@redhat.com>
|
||||||
|
|
||||||
|
diff --git a/malloc/malloc.c b/malloc/malloc.c
|
||||||
|
index 5b87bdb081..ec2d934595 100644
|
||||||
|
--- a/malloc/malloc.c
|
||||||
|
+++ b/malloc/malloc.c
|
||||||
|
@@ -4224,11 +4224,14 @@ _int_free (mstate av, mchunkptr p, int have_lock)
|
||||||
|
if (__glibc_unlikely (e->key == tcache))
|
||||||
|
{
|
||||||
|
tcache_entry *tmp;
|
||||||
|
+ size_t cnt = 0;
|
||||||
|
LIBC_PROBE (memory_tcache_double_free, 2, e, tc_idx);
|
||||||
|
for (tmp = tcache->entries[tc_idx];
|
||||||
|
tmp;
|
||||||
|
- tmp = REVEAL_PTR (tmp->next))
|
||||||
|
+ tmp = REVEAL_PTR (tmp->next), ++cnt)
|
||||||
|
{
|
||||||
|
+ if (cnt >= mp_.tcache_count)
|
||||||
|
+ malloc_printerr ("free(): too many chunks detected in tcache");
|
||||||
|
if (__glibc_unlikely (!aligned_OK (tmp)))
|
||||||
|
malloc_printerr ("free(): unaligned chunk detected in tcache 2");
|
||||||
|
if (tmp == e)
|
133
SOURCES/glibc-rh1871383-7.patch
Normal file
133
SOURCES/glibc-rh1871383-7.patch
Normal file
@ -0,0 +1,133 @@
|
|||||||
|
From fc859c304898a5ec72e0ba5269ed136ed0ea10e1 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Siddhesh Poyarekar <siddhesh@sourceware.org>
|
||||||
|
Date: Wed, 7 Jul 2021 23:02:46 +0530
|
||||||
|
Subject: Harden tcache double-free check
|
||||||
|
|
||||||
|
The tcache allocator layer uses the tcache pointer as a key to
|
||||||
|
identify a block that may be freed twice. Since this is in the
|
||||||
|
application data area, an attacker exploiting a use-after-free could
|
||||||
|
potentially get access to the entire tcache structure through this
|
||||||
|
key. A detailed write-up was provided by Awarau here:
|
||||||
|
|
||||||
|
https://awaraucom.wordpress.com/2020/07/19/house-of-io-remastered/
|
||||||
|
|
||||||
|
Replace this static pointer use for key checking with one that is
|
||||||
|
generated at malloc initialization. The first attempt is through
|
||||||
|
getrandom with a fallback to random_bits(), which is a simple
|
||||||
|
pseudo-random number generator based on the clock. The fallback ought
|
||||||
|
to be sufficient since the goal of the randomness is only to make the
|
||||||
|
key arbitrary enough that it is very unlikely to collide with user
|
||||||
|
data.
|
||||||
|
|
||||||
|
Co-authored-by: Eyal Itkin <eyalit@checkpoint.com>
|
||||||
|
|
||||||
|
[note: context for arena.c chunk #2 changed to accomodate missing
|
||||||
|
tagging support code - DJ]
|
||||||
|
|
||||||
|
diff -rup a/malloc/arena.c b/malloc/arena.c
|
||||||
|
--- a/malloc/arena.c 2022-09-16 01:09:02.003843024 -0400
|
||||||
|
+++ b/malloc/arena.c 2022-09-16 01:25:51.879994057 -0400
|
||||||
|
@@ -286,6 +286,10 @@ extern struct dl_open_hook *_dl_open_hoo
|
||||||
|
libc_hidden_proto (_dl_open_hook);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
+#if USE_TCACHE
|
||||||
|
+static void tcache_key_initialize (void);
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
static void
|
||||||
|
ptmalloc_init (void)
|
||||||
|
{
|
||||||
|
@@ -294,6 +298,10 @@ ptmalloc_init (void)
|
||||||
|
|
||||||
|
__malloc_initialized = 0;
|
||||||
|
|
||||||
|
+#if USE_TCACHE
|
||||||
|
+ tcache_key_initialize ();
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
#ifdef SHARED
|
||||||
|
/* In case this libc copy is in a non-default namespace, never use brk.
|
||||||
|
Likewise if dlopened from statically linked program. */
|
||||||
|
diff -rup a/malloc/malloc.c b/malloc/malloc.c
|
||||||
|
--- a/malloc/malloc.c 2022-09-16 01:09:05.491977387 -0400
|
||||||
|
+++ b/malloc/malloc.c 2022-09-16 01:25:51.883994213 -0400
|
||||||
|
@@ -247,6 +247,10 @@
|
||||||
|
/* For SINGLE_THREAD_P. */
|
||||||
|
#include <sysdep-cancel.h>
|
||||||
|
|
||||||
|
+/* For tcache double-free check. */
|
||||||
|
+#include <random-bits.h>
|
||||||
|
+#include <sys/random.h>
|
||||||
|
+
|
||||||
|
/*
|
||||||
|
Debugging:
|
||||||
|
|
||||||
|
@@ -2924,7 +2928,7 @@ typedef struct tcache_entry
|
||||||
|
{
|
||||||
|
struct tcache_entry *next;
|
||||||
|
/* This field exists to detect double frees. */
|
||||||
|
- struct tcache_perthread_struct *key;
|
||||||
|
+ uintptr_t key;
|
||||||
|
} tcache_entry;
|
||||||
|
|
||||||
|
/* There is one of these for each thread, which contains the
|
||||||
|
@@ -2941,6 +2945,31 @@ typedef struct tcache_perthread_struct
|
||||||
|
static __thread bool tcache_shutting_down = false;
|
||||||
|
static __thread tcache_perthread_struct *tcache = NULL;
|
||||||
|
|
||||||
|
+/* Process-wide key to try and catch a double-free in the same thread. */
|
||||||
|
+static uintptr_t tcache_key;
|
||||||
|
+
|
||||||
|
+/* The value of tcache_key does not really have to be a cryptographically
|
||||||
|
+ secure random number. It only needs to be arbitrary enough so that it does
|
||||||
|
+ not collide with values present in applications. If a collision does happen
|
||||||
|
+ consistently enough, it could cause a degradation in performance since the
|
||||||
|
+ entire list is checked to check if the block indeed has been freed the
|
||||||
|
+ second time. The odds of this happening are exceedingly low though, about 1
|
||||||
|
+ in 2^wordsize. There is probably a higher chance of the performance
|
||||||
|
+ degradation being due to a double free where the first free happened in a
|
||||||
|
+ different thread; that's a case this check does not cover. */
|
||||||
|
+static void
|
||||||
|
+tcache_key_initialize (void)
|
||||||
|
+{
|
||||||
|
+ if (__getrandom (&tcache_key, sizeof(tcache_key), GRND_NONBLOCK)
|
||||||
|
+ != sizeof (tcache_key))
|
||||||
|
+ {
|
||||||
|
+ tcache_key = random_bits ();
|
||||||
|
+#if __WORDSIZE == 64
|
||||||
|
+ tcache_key = (tcache_key << 32) | random_bits ();
|
||||||
|
+#endif
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
/* Caller must ensure that we know tc_idx is valid and there's room
|
||||||
|
for more chunks. */
|
||||||
|
static __always_inline void
|
||||||
|
@@ -2950,7 +2979,7 @@ tcache_put (mchunkptr chunk, size_t tc_i
|
||||||
|
|
||||||
|
/* Mark this chunk as "in the tcache" so the test in _int_free will
|
||||||
|
detect a double free. */
|
||||||
|
- e->key = tcache;
|
||||||
|
+ e->key = tcache_key;
|
||||||
|
|
||||||
|
e->next = PROTECT_PTR (&e->next, tcache->entries[tc_idx]);
|
||||||
|
tcache->entries[tc_idx] = e;
|
||||||
|
@@ -2967,7 +2996,7 @@ tcache_get (size_t tc_idx)
|
||||||
|
malloc_printerr ("malloc(): unaligned tcache chunk detected");
|
||||||
|
tcache->entries[tc_idx] = REVEAL_PTR (e->next);
|
||||||
|
--(tcache->counts[tc_idx]);
|
||||||
|
- e->key = NULL;
|
||||||
|
+ e->key = 0;
|
||||||
|
return (void *) e;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -4231,7 +4260,7 @@ _int_free (mstate av, mchunkptr p, int h
|
||||||
|
trust it (it also matches random payload data at a 1 in
|
||||||
|
2^<size_t> chance), so verify it's not an unlikely
|
||||||
|
coincidence before aborting. */
|
||||||
|
- if (__glibc_unlikely (e->key == tcache))
|
||||||
|
+ if (__glibc_unlikely (e->key == tcache_key))
|
||||||
|
{
|
||||||
|
tcache_entry *tmp;
|
||||||
|
size_t cnt = 0;
|
@ -17,6 +17,8 @@
|
|||||||
set -evx
|
set -evx
|
||||||
|
|
||||||
tar_tmp="$(mktemp)"
|
tar_tmp="$(mktemp)"
|
||||||
|
declare -A libc_dlink_tmp_list
|
||||||
|
ldso_annobin_sym_tmp_list=""
|
||||||
|
|
||||||
# Prefer a separately installed debugedit over the RPM-integrated one.
|
# Prefer a separately installed debugedit over the RPM-integrated one.
|
||||||
if command -v debugedit >/dev/null ; then
|
if command -v debugedit >/dev/null ; then
|
||||||
@ -26,7 +28,7 @@ else
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
cleanup () {
|
cleanup () {
|
||||||
rm -f "$tar_tmp"
|
rm -f "$tar_tmp" ${libc_dlink_tmp_list[@]} $ldso_annobin_sym_tmp_list
|
||||||
}
|
}
|
||||||
trap cleanup 0
|
trap cleanup 0
|
||||||
|
|
||||||
@ -51,6 +53,15 @@ full_list="$ldso_list $libc_list $libdl_list $libpthread_list $librt_list"
|
|||||||
# Run the debuginfo extraction.
|
# Run the debuginfo extraction.
|
||||||
"$script_path" "$@"
|
"$script_path" "$@"
|
||||||
|
|
||||||
|
# libc.so.6: Extract the .gnu_debuglink section
|
||||||
|
for f in $libc_list
|
||||||
|
do
|
||||||
|
dlink_tmp="$(mktemp)"
|
||||||
|
libc_dlink_tmp_list["$f"]="$dlink_tmp"
|
||||||
|
objcopy -j.gnu_debuglink --set-section-flags .gnu_debuglink=alloc \
|
||||||
|
-O binary "$sysroot_path/$f" "$dlink_tmp"
|
||||||
|
done
|
||||||
|
|
||||||
# Restore the original files.
|
# Restore the original files.
|
||||||
(cd "$sysroot_path"; tar xf "$tar_tmp")
|
(cd "$sysroot_path"; tar xf "$tar_tmp")
|
||||||
(cd "$sysroot_path"; ls -l $full_list)
|
(cd "$sysroot_path"; ls -l $full_list)
|
||||||
@ -61,6 +72,20 @@ do
|
|||||||
objcopy --merge-notes "$sysroot_path/$p"
|
objcopy --merge-notes "$sysroot_path/$p"
|
||||||
done
|
done
|
||||||
|
|
||||||
|
# libc.so.6: Restore the .gnu_debuglink section
|
||||||
|
for f in ${!libc_dlink_tmp_list[@]}
|
||||||
|
do
|
||||||
|
dlink_tmp="${libc_dlink_tmp_list[$f]}"
|
||||||
|
objcopy --add-section .gnu_debuglink="$dlink_tmp" "$sysroot_path/$f"
|
||||||
|
done
|
||||||
|
|
||||||
|
# ld.so does not have separated debuginfo and so the debuginfo file
|
||||||
|
# generated by find-debuginfo is redundant. Therefore, remove it.
|
||||||
|
for ldso_debug in `find "$sysroot_path" -name 'ld-*.so*.debug' -type f`
|
||||||
|
do
|
||||||
|
rm -f "$ldso_debug"
|
||||||
|
done
|
||||||
|
|
||||||
# libc.so.6 and other shared objects: Reduce to valuable symbols.
|
# libc.so.6 and other shared objects: Reduce to valuable symbols.
|
||||||
# Eliminate file symbols, annobin symbols, and symbols used by the
|
# Eliminate file symbols, annobin symbols, and symbols used by the
|
||||||
# glibc build to implement hidden aliases (__EI_*). We would also
|
# glibc build to implement hidden aliases (__EI_*). We would also
|
||||||
@ -103,6 +128,14 @@ debug_base_name=${last_arg:-$RPM_BUILD_ROOT}
|
|||||||
for p in $ldso_list
|
for p in $ldso_list
|
||||||
do
|
do
|
||||||
$debugedit -b "$debug_base_name" -d "$debug_dest_name" -n "$sysroot_path/$p"
|
$debugedit -b "$debug_base_name" -d "$debug_dest_name" -n "$sysroot_path/$p"
|
||||||
|
|
||||||
|
# Remove the .annobin* symbols (and only them).
|
||||||
|
ldso_annobin_sym_tmp="$(mktemp)"
|
||||||
|
ldso_annobin_sym_tmp_list+=" $ldso_annobin_sym_tmp"
|
||||||
|
if nm --format=posix "$sysroot_path/$p" | cut -d' ' -f1 \
|
||||||
|
| grep '^\.annobin' > "$ldso_annobin_sym_tmp"; then
|
||||||
|
objcopy --strip-symbols="$ldso_annobin_sym_tmp" "$sysroot_path/$p"
|
||||||
|
fi
|
||||||
done
|
done
|
||||||
|
|
||||||
# Apply single-file DWARF optimization.
|
# Apply single-file DWARF optimization.
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
%define glibcsrcdir glibc-2.28
|
%define glibcsrcdir glibc-2.28
|
||||||
%define glibcversion 2.28
|
%define glibcversion 2.28
|
||||||
%define glibcrelease 214%{?dist}
|
%define glibcrelease 216%{?dist}
|
||||||
# Pre-release tarballs are pulled in from git using a command that is
|
# Pre-release tarballs are pulled in from git using a command that is
|
||||||
# effectively:
|
# effectively:
|
||||||
#
|
#
|
||||||
@ -971,6 +971,13 @@ Patch778: glibc-rh2119304-3.patch
|
|||||||
Patch779: glibc-rh2118667.patch
|
Patch779: glibc-rh2118667.patch
|
||||||
Patch780: glibc-rh2122498.patch
|
Patch780: glibc-rh2122498.patch
|
||||||
Patch781: glibc-rh2125222.patch
|
Patch781: glibc-rh2125222.patch
|
||||||
|
Patch782: glibc-rh1871383-1.patch
|
||||||
|
Patch783: glibc-rh1871383-2.patch
|
||||||
|
Patch784: glibc-rh1871383-3.patch
|
||||||
|
Patch785: glibc-rh1871383-4.patch
|
||||||
|
Patch786: glibc-rh1871383-5.patch
|
||||||
|
Patch787: glibc-rh1871383-6.patch
|
||||||
|
Patch788: glibc-rh1871383-7.patch
|
||||||
|
|
||||||
##############################################################################
|
##############################################################################
|
||||||
# Continued list of core "glibc" package information:
|
# Continued list of core "glibc" package information:
|
||||||
@ -2801,6 +2808,14 @@ fi
|
|||||||
%files -f compat-libpthread-nonshared.filelist -n compat-libpthread-nonshared
|
%files -f compat-libpthread-nonshared.filelist -n compat-libpthread-nonshared
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
|
* Wed Oct 05 2022 Arjun Shankar <arjun@redhat.com> - 2.28-216
|
||||||
|
- Retain .gnu_debuglink section for libc.so.6 (#2115830)
|
||||||
|
- Remove .annobin* symbols from ld.so
|
||||||
|
- Remove redundant ld.so debuginfo file
|
||||||
|
|
||||||
|
* Wed Sep 28 2022 DJ Delorie <dj@redhat.com> - 2.28-215
|
||||||
|
- Improve malloc implementation (#1871383)
|
||||||
|
|
||||||
* Tue Sep 20 2022 Florian Weimer <fweimer@redhat.com> - 2.28-214
|
* Tue Sep 20 2022 Florian Weimer <fweimer@redhat.com> - 2.28-214
|
||||||
- Fix hwcaps search path size computation (#2125222)
|
- Fix hwcaps search path size computation (#2125222)
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user