Implementing baseline glibc 2.42 support for #3264 (#3272)

* Implementing baseline glibc 2.42 support for #3264

* fixes #3264

* implement tcache_perthread_struct changes from https://elixir.bootlin.com/glibc/glibc-2.42/source/malloc/malloc.c#L3127

* implemented new num_slots decrement instead of counts increment: https://elixir.bootlin.com/glibc/glibc-2.42/source/malloc/malloc.c#L3129

* added warning for limited glibc 2.42 feature implementation

* removed unneded import for TCACHE_FILL_COUNT

* removed unneded import for message.color

* Heap.tcachebins new print warning once implementation

* binded print warning once for Heap.tcachebins to function instead of object

* set correct function path this time
pull/3278/head
0x6fe1be2 4 months ago committed by GitHub
parent 1fb969e0ff
commit a693fc7c7d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -72,7 +72,6 @@ HEAP_MAX_SIZE: int = None
NBINS = 128
BINMAPSIZE = 4
TCACHE_MAX_BINS = 64
NFASTBINS = 10
NSMALLBINS = 64
@ -1250,6 +1249,17 @@ class GlibcMemoryAllocator(pwndbg.aglib.heap.heap.MemoryAllocator, Generic[TheTy
if tcache is None:
return None
if pwndbg.glibc.get_version() >= (2, 42) and not hasattr(
GlibcMemoryAllocator.tcachebins, "tcache_2_42_warning_issued"
):
print(
message.warn(
"Changes to tcache in GLIBC 2.42 have not been fully implemented. "
"PR contributions are highly appreciated!"
)
)
setattr(GlibcMemoryAllocator.tcachebins, "tcache_2_42_warning_issued", True)
counts = tcache["counts"]
entries = tcache["entries"]
@ -1264,6 +1274,8 @@ class GlibcMemoryAllocator(pwndbg.aglib.heap.heap.MemoryAllocator, Generic[TheTy
for i in range(num_tcachebins):
size = self._request2size(tidx2usize(i))
count = int(counts[i])
if pwndbg.glibc.get_version() >= (2, 42):
count = pwndbg.aglib.heap.structs.TCACHE_FILL_COUNT - count
chain = pwndbg.chain.get(
int(entries[i]),
offset=self.tcache_next_offset,

@ -44,7 +44,9 @@ MALLOC_ALIGN_MASK = MALLOC_ALIGN - 1
MAX_FAST_SIZE = 80 * SIZE_SZ // 4
NBINS = 128
BINMAPSIZE = 4
TCACHE_MAX_BINS = 64
TCACHE_SMALL_BINS = 64
TCACHE_LARGE_BINS = 12
TCACHE_MAX_BINS = TCACHE_SMALL_BINS + TCACHE_LARGE_BINS
NFASTBINS = fastbin_index(request2size(MAX_FAST_SIZE)) + 1
if pwndbg.aglib.arch.ptrsize == 4:
@ -542,14 +544,14 @@ class c_tcache_perthread_struct_2_29(Structure):
"""
_fields_ = [
("counts", ctypes.c_char * TCACHE_MAX_BINS),
("entries", c_pvoid * TCACHE_MAX_BINS),
("counts", ctypes.c_char * TCACHE_SMALL_BINS),
("entries", c_pvoid * TCACHE_SMALL_BINS),
]
class c_tcache_perthread_struct_2_30(Structure):
"""
This class represents the tcache_perthread_struct for GLIBC >= 2.30 as a ctypes struct.
This class represents the tcache_perthread_struct for 2.30 <= GLIBC < 2.42 as a ctypes struct.
https://github.com/bminor/glibc/blob/glibc-2.34/malloc/malloc.c#L3025
@ -560,9 +562,28 @@ class c_tcache_perthread_struct_2_30(Structure):
} tcache_perthread_struct;
"""
_fields_ = [
("counts", ctypes.c_uint16 * TCACHE_SMALL_BINS),
("entries", c_pvoid * TCACHE_SMALL_BINS),
]
class c_tcache_perthread_struct_2_42(Structure):
"""
This class represents the tcache_perthread_struct for 2.42 <= GLIBC as a ctypes struct.
https://elixir.bootlin.com/glibc/glibc-2.42/source/malloc/malloc.c#L3127
typedef struct tcache_perthread_struct
{
uint16_t num_slots[TCACHE_MAX_BINS];
tcache_entry *entries[TCACHE_MAX_BINS];
} tcache_perthread_struct;
"""
_fields_ = [
("counts", ctypes.c_uint16 * TCACHE_MAX_BINS),
("entries", c_pvoid * TCACHE_MAX_BINS),
("entries", c_pvoid * TCACHE_SMALL_BINS),
]
@ -571,7 +592,9 @@ class TcachePerthreadStruct(CStruct2GDB):
This class represents tcache_perthread_struct with interface compatible with `pwndbg.dbg_mod.Value`.
"""
if GLIBC_VERSION >= (2, 30):
if GLIBC_VERSION >= (2, 42):
_c_struct = c_tcache_perthread_struct_2_42
elif GLIBC_VERSION >= (2, 30):
_c_struct = c_tcache_perthread_struct_2_30
else:
_c_struct = c_tcache_perthread_struct_2_29
@ -967,7 +990,7 @@ DEFAULT_MP_.arena_test = 2 if pwndbg.aglib.arch.ptrsize == 4 else 8
if (MallocPar._c_struct != c_malloc_par_2_23) and (MallocPar._c_struct != c_malloc_par_2_12):
# the only difference between 2.23 and the rest is the lack of tcache
DEFAULT_MP_.tcache_count = TCACHE_FILL_COUNT
DEFAULT_MP_.tcache_bins = TCACHE_MAX_BINS
DEFAULT_MP_.tcache_max_bytes = (TCACHE_MAX_BINS - 1) * MALLOC_ALIGN + MINSIZE - SIZE_SZ
DEFAULT_MP_.tcache_bins = TCACHE_SMALL_BINS
DEFAULT_MP_.tcache_max_bytes = (TCACHE_SMALL_BINS - 1) * MALLOC_ALIGN + MINSIZE - SIZE_SZ
if MallocPar._c_struct == c_malloc_par_2_12:
DEFAULT_MP_.pagesize = DEFAULT_PAGE_SIZE

Loading…
Cancel
Save