Safe-Linking is a security mechanism that protects single-linked lists (such as the fastbins) 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 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 bits in the PAGE_SHIFT position), will be merged with the 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 attacker will directly fail 7 out of 8 times, and on 64 bit machines it will fail 15 out of 16 times.
The proposed solution adds 3-4 asm instructions per malloc()/free() and therefore has only minor performance implications if it has any. A similar protection was added to Chromium's version of TCMalloc in 2013, and according to their documentation the performance overhead was less than 2%.
For more information, feel free to check out our White Paper which can be found here: https://github.com/gperftools/gperftools/files/4023520/Safe-Linking-White-Pa... --- libc/stdlib/malloc-standard/free.c | 5 +++-- libc/stdlib/malloc-standard/mallinfo.c | 3 ++- libc/stdlib/malloc-standard/malloc.c | 6 ++++-- libc/stdlib/malloc-standard/malloc.h | 12 ++++++++++++ 4 files changed, 21 insertions(+), 5 deletions(-)
diff --git a/libc/stdlib/malloc-standard/free.c b/libc/stdlib/malloc-standard/free.c index a2d765d41..f3602cf48 100644 --- a/libc/stdlib/malloc-standard/free.c +++ b/libc/stdlib/malloc-standard/free.c @@ -214,8 +214,9 @@ void attribute_hidden __malloc_consolidate(mstate av) *fb = 0;
do { + CHECK_PTR(p); check_inuse_chunk(p); - nextp = p->fd; + nextp = REVEAL_PTR(&p->fd, p->fd);
/* Slightly streamlined version of consolidation code in free() */ size = p->size & ~PREV_INUSE; @@ -308,7 +309,7 @@ void free(void* mem)
set_fastchunks(av); fb = &(av->fastbins[fastbin_index(size)]); - p->fd = *fb; + p->fd = PROTECT_PTR(&p->fd, *fb); *fb = p; }
diff --git a/libc/stdlib/malloc-standard/mallinfo.c b/libc/stdlib/malloc-standard/mallinfo.c index dbe4d49b8..992322341 100644 --- a/libc/stdlib/malloc-standard/mallinfo.c +++ b/libc/stdlib/malloc-standard/mallinfo.c @@ -49,7 +49,8 @@ struct mallinfo mallinfo(void) fastavail = 0;
for (i = 0; i < NFASTBINS; ++i) { - for (p = av->fastbins[i]; p != 0; p = p->fd) { + for (p = av->fastbins[i]; p != 0; p = REVEAL_PTR(&p->fd, p->fd)) { + CHECK_PTR(p); ++nfastblocks; fastavail += chunksize(p); } diff --git a/libc/stdlib/malloc-standard/malloc.c b/libc/stdlib/malloc-standard/malloc.c index 1a6d4dc1c..1f898eb29 100644 --- a/libc/stdlib/malloc-standard/malloc.c +++ b/libc/stdlib/malloc-standard/malloc.c @@ -260,12 +260,13 @@ void __do_check_malloc_state(void) assert(p == 0);
while (p != 0) { + CHECK_PTR(p); /* each chunk claims to be inuse */ __do_check_inuse_chunk(p); total += chunksize(p); /* chunk belongs in this bin */ assert(fastbin_index(chunksize(p)) == i); - p = p->fd; + p = REVEAL_PTR(&p->fd, p->fd); } }
@@ -855,7 +856,8 @@ void* malloc(size_t bytes) if ((unsigned long)(nb) <= (unsigned long)(av->max_fast)) { fb = &(av->fastbins[(fastbin_index(nb))]); if ( (victim = *fb) != 0) { - *fb = victim->fd; + CHECK_PTR(victim); + *fb = REVEAL_PTR(&victim->fd, victim->fd); check_remalloced_chunk(victim, nb); retval = chunk2mem(victim); goto DONE; diff --git a/libc/stdlib/malloc-standard/malloc.h b/libc/stdlib/malloc-standard/malloc.h index 44120d388..30a696e5a 100644 --- a/libc/stdlib/malloc-standard/malloc.h +++ b/libc/stdlib/malloc-standard/malloc.h @@ -839,6 +839,18 @@ typedef struct malloc_chunk* mfastbinptr; #define get_max_fast(M) \ ((M)->max_fast & ~(FASTCHUNKS_BIT | ANYCHUNKS_BIT))
+/* + Safe-Linking: + Use randomness from ASLR (mmap_base) to protect single-linked lists + of fastbins. Together with allocation alignment checks, this mechanism + reduces the risk of pointer hijacking, as was done with Safe-Unlinking + in the double-linked lists of smallbins. +*/ +#define PROTECT_PTR(pos, ptr) ((mchunkptr)((((size_t)pos) >> PAGE_SHIFT) ^ ((size_t)ptr))) +#define REVEAL_PTR(pos, ptr) PROTECT_PTR(pos, ptr) +#define CHECK_PTR(P) \ + if (!aligned_OK(P)) \ + abort();
/* morecore_properties is a status word holding dynamically discovered -- 2.17.1
Hi, Eyal Itkin wrote,
Safe-Linking is a security mechanism that protects single-linked lists (such as the fastbins) 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 pointers from being hijacked by an attacker.
The patch does not apply with git am ontop of uClibc-ng master. What mail client do you use and could you try to use git format-patch -s origin and send an e-Mail with the patch as attachment so it does not get corrupted somehow.
best regards Waldemar
Hi,
Sorry for the formatting problem, I'm having trouble sending each open source project the patch in their own format, and I probably mixed up something. The patch is now attached to this email.
In addition, I also attached the White Paper that describes this new security mitigation.
Just as a side note: the patch is signed by eyalit@checkpoint.com but I'm sending this from eyal.itkin@gmail.com due to mail issues with my work e-mail (which is connected to my GitHub account).
Thanks again for your cooperation, Eyal.
On Fri, Feb 14, 2020 at 11:40 AM Waldemar Brodkorb wbx@uclibc-ng.org wrote:
Hi, Eyal Itkin wrote,
Safe-Linking is a security mechanism that protects single-linked lists (such as the fastbins) 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 pointers from being hijacked by an attacker.
The patch does not apply with git am ontop of uClibc-ng master. What mail client do you use and could you try to use git format-patch -s origin and send an e-Mail with the patch as attachment so it does not get corrupted somehow.
best regards Waldemar
Hi,
Shouldn't this be a config option, since there is a performance hit? On most embedded architectures the heap is in a fixed position, so the there is no randomness to extract from ASLR, thus they are only left with the performance overhead.
Best regards, Kjetil Oftedal
On Sun, 16 Feb 2020 at 07:02, Eyal Itkin eyal.itkin@gmail.com wrote:
Hi,
Sorry for the formatting problem, I'm having trouble sending each open source project the patch in their own format, and I probably mixed up something. The patch is now attached to this email.
In addition, I also attached the White Paper that describes this new security mitigation.
Just as a side note: the patch is signed by eyalit@checkpoint.com but I'm sending this from eyal.itkin@gmail.com due to mail issues with my work e-mail (which is connected to my GitHub account).
Thanks again for your cooperation, Eyal.
On Fri, Feb 14, 2020 at 11:40 AM Waldemar Brodkorb wbx@uclibc-ng.org wrote:
Hi, Eyal Itkin wrote,
Safe-Linking is a security mechanism that protects single-linked lists (such as the fastbins) 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 pointers from being hijacked by an attacker.
The patch does not apply with git am ontop of uClibc-ng master. What mail client do you use and could you try to use git format-patch -s origin and send an e-Mail with the patch as attachment so it does not get corrupted somehow.
best regards Waldemar
devel mailing list devel@uclibc-ng.org https://mailman.uclibc-ng.org/cgi-bin/mailman/listinfo/devel
We benchmarked it on glibc and the overhead wasn't even measurable. In addition, the average overhead on TCMalloc's testsuite was 0.02%, so the impact is quite negligible.
We've just finished a research when uClibc was used on a Linux OS and there was ASLR for the heap. This protection would have blocked our exploit completely, if it was already deployed.
I agree that on operating systems without ASLR, there isn't any added value for this protection. If there is some way do automatically enable it for ASLR enabled OSes it would be the preferred method. From my experience when security is not opt-in by default, it never gets activated.
On Sun, 16 Feb 2020, 10:10 Kjetil Oftedal, oftedal@gmail.com wrote:
Hi,
Shouldn't this be a config option, since there is a performance hit? On most embedded architectures the heap is in a fixed position, so the there is no randomness to extract from ASLR, thus they are only left with the performance overhead.
Best regards, Kjetil Oftedal
On Sun, 16 Feb 2020 at 07:02, Eyal Itkin eyal.itkin@gmail.com wrote:
Hi,
Sorry for the formatting problem, I'm having trouble sending each open source project the patch in their own format, and I probably mixed up something. The patch is now attached to this email.
In addition, I also attached the White Paper that describes this new security mitigation.
Just as a side note: the patch is signed by eyalit@checkpoint.com but I'm sending this from eyal.itkin@gmail.com due to mail issues with my work e-mail (which is connected to my GitHub account).
Thanks again for your cooperation, Eyal.
On Fri, Feb 14, 2020 at 11:40 AM Waldemar Brodkorb wbx@uclibc-ng.org wrote:
Hi, Eyal Itkin wrote,
Safe-Linking is a security mechanism that protects single-linked lists (such as the fastbins) 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 pointers from being hijacked by an attacker.
The patch does not apply with git am ontop of uClibc-ng master. What mail client do you use and could you try to use git format-patch -s origin and send an e-Mail with the patch as attachment so it does not get corrupted somehow.
best regards Waldemar
devel mailing list devel@uclibc-ng.org https://mailman.uclibc-ng.org/cgi-bin/mailman/listinfo/devel
I checked in the code, and it looks like the correct macro for enabling this feature only on Linux will be: __UCLIBC_LINUX_SPECIFIC__. Before I send an additional commit for correctly wrapping up this feature, I just wanted to check with you, is this the correct flag to be used?
I thought of setting the configuration as follows: * A global configurable disable flag, that is off by default (I don't know how to set one, and I will need your assistance) * if __UCLIBC_LINUX_SPECIFIC__ is not defined, the disable flag will be automatically defined (in the code level)
This way, the feature will be on by default only on Linux, and it could be manually turned off by developers. In the future, if it will be applicable to other environments as well, it will be easier to modify the second condition accordingly.
Will be happy to hear what you think about this. Eyal Itkin.
On Sun, Feb 16, 2020 at 10:18 AM Eyal Itkin eyal.itkin@gmail.com wrote:
We benchmarked it on glibc and the overhead wasn't even measurable. In addition, the average overhead on TCMalloc's testsuite was 0.02%, so the impact is quite negligible.
We've just finished a research when uClibc was used on a Linux OS and there was ASLR for the heap. This protection would have blocked our exploit completely, if it was already deployed.
I agree that on operating systems without ASLR, there isn't any added value for this protection. If there is some way do automatically enable it for ASLR enabled OSes it would be the preferred method. From my experience when security is not opt-in by default, it never gets activated.
On Sun, 16 Feb 2020, 10:10 Kjetil Oftedal, oftedal@gmail.com wrote:
Hi,
Shouldn't this be a config option, since there is a performance hit? On most embedded architectures the heap is in a fixed position, so the there is no randomness to extract from ASLR, thus they are only left with the performance overhead.
Best regards, Kjetil Oftedal
On Sun, 16 Feb 2020 at 07:02, Eyal Itkin eyal.itkin@gmail.com wrote:
Hi,
Sorry for the formatting problem, I'm having trouble sending each open source project the patch in their own format, and I probably mixed up something. The patch is now attached to this email.
In addition, I also attached the White Paper that describes this new security mitigation.
Just as a side note: the patch is signed by eyalit@checkpoint.com but I'm sending this from eyal.itkin@gmail.com due to mail issues with my work e-mail (which is connected to my GitHub account).
Thanks again for your cooperation, Eyal.
On Fri, Feb 14, 2020 at 11:40 AM Waldemar Brodkorb wbx@uclibc-ng.org wrote:
Hi, Eyal Itkin wrote,
Safe-Linking is a security mechanism that protects single-linked lists (such as the fastbins) 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 pointers from being hijacked by an attacker.
The patch does not apply with git am ontop of uClibc-ng master. What mail client do you use and could you try to use git format-patch -s origin and send an e-Mail with the patch as attachment so it does not get corrupted somehow.
best regards Waldemar
devel mailing list devel@uclibc-ng.org https://mailman.uclibc-ng.org/cgi-bin/mailman/listinfo/devel