Largebins size range tests for x64 & i386_big (#1658)

* Add largebins size range tests for x64 & i386_big

* Don't run i386_big test on unsupported platforms
pull/1665/head
CptGibbon 3 years ago committed by GitHub
parent ceb7258de6
commit 9d3ee52ea6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -0,0 +1,17 @@
/* Initialize the main arena by requesting a single chunk.
* For general GLIBC malloc testing.
*/
#include <stdlib.h>
void break_here(void) {}
int main(void)
{
__attribute__((unused))
void* m = malloc(1);
break_here();
return 0;
}

@ -38,7 +38,7 @@ GLIBC_2_33=$(PWD)/glibcs/2.33
.PHONY : all clean
CUSTOM_TARGETS = reference_bin_pie.out reference_bin_nopie.out symbol_1600_and_752.out
CUSTOM_TARGETS = reference_bin_pie.out reference_bin_nopie.out symbol_1600_and_752.out initialized_heap_x64.out initialized_heap_i386_big.out
all: $(LINKED) $(LINKED_ASM) $(COMPILED_GO) $(CUSTOM_TARGETS)
@ -111,6 +111,22 @@ issue_1565.out: issue_1565.c
@echo "[+] Building issue_1565.out"
${CC} -g -O0 -o issue_1565.out issue_1565.c -pthread -lpthread
# TODO: Link against a specific GLIBC version >= 2.26
initialized_heap_i386_big.out: initialized_heap.c
@echo "[+] Building initialized_heap_i386_big.out"
${ZIGCC} \
${CFLAGS} \
-target i386-linux-gnu \
-o initialized_heap_i386_big.out initialized_heap.c
# TODO: Link against a specific GLIBC version.
initialized_heap_x64.out: initialized_heap.c
@echo "[+] Building initialized_heap_x64.out"
${ZIGCC} \
${CFLAGS} \
-target x86_64-linux-gnu \
-o initialized_heap_x64.out initialized_heap.c
clean :
@echo "[+] Cleaning stuff"
@rm -f $(COMPILED) $(LINKED) $(COMPILED_ASM) $(LINKED_ASM) $(COMPILED_GO) *.out *.o

@ -1,4 +1,5 @@
import gdb
import pytest
import pwndbg.gdblib.memory
import pwndbg.gdblib.symbol
@ -153,3 +154,169 @@ def test_heap_bins(start_binary):
assert result.bins[largebin_size].is_corrupted
gdb.execute("bins")
def test_largebins_size_range_64bit(start_binary):
"""
Ensure the "largebins" command displays the correct largebin size ranges.
This test targets 64-bit architectures.
"""
start_binary(tests.binaries.get("initialized_heap_x64.out"))
gdb.execute("break break_here")
gdb.execute("continue")
command_output = gdb.execute("largebins --verbose", to_string=True).splitlines()[1:]
expected = [
"0x400-0x430",
"0x440-0x470",
"0x480-0x4b0",
"0x4c0-0x4f0",
"0x500-0x530",
"0x540-0x570",
"0x580-0x5b0",
"0x5c0-0x5f0",
"0x600-0x630",
"0x640-0x670",
"0x680-0x6b0",
"0x6c0-0x6f0",
"0x700-0x730",
"0x740-0x770",
"0x780-0x7b0",
"0x7c0-0x7f0",
"0x800-0x830",
"0x840-0x870",
"0x880-0x8b0",
"0x8c0-0x8f0",
"0x900-0x930",
"0x940-0x970",
"0x980-0x9b0",
"0x9c0-0x9f0",
"0xa00-0xa30",
"0xa40-0xa70",
"0xa80-0xab0",
"0xac0-0xaf0",
"0xb00-0xb30",
"0xb40-0xb70",
"0xb80-0xbb0",
"0xbc0-0xbf0",
"0xc00-0xc30",
"0xc40-0xdf0",
"0xe00-0xff0",
"0x1000-0x11f0",
"0x1200-0x13f0",
"0x1400-0x15f0",
"0x1600-0x17f0",
"0x1800-0x19f0",
"0x1a00-0x1bf0",
"0x1c00-0x1df0",
"0x1e00-0x1ff0",
"0x2000-0x21f0",
"0x2200-0x23f0",
"0x2400-0x25f0",
"0x2600-0x27f0",
"0x2800-0x29f0",
"0x2a00-0x2ff0",
"0x3000-0x3ff0",
"0x4000-0x4ff0",
"0x5000-0x5ff0",
"0x6000-0x6ff0",
"0x7000-0x7ff0",
"0x8000-0x8ff0",
"0x9000-0x9ff0",
"0xa000-0xfff0",
"0x10000-0x17ff0",
"0x18000-0x1fff0",
"0x20000-0x27ff0",
"0x28000-0x3fff0",
"0x40000-0x7fff0",
"0x80000-∞",
]
for bin_index, size_range in enumerate(command_output):
assert size_range.split(":")[0] == expected[bin_index]
def test_largebins_size_range_32bit_big(start_binary):
"""
Ensure the "largebins" command displays the correct largebin size ranges.
This test targets 32-bit architectures with MALLOC_ALIGNMENT == 16.
"""
try:
start_binary(tests.binaries.get("initialized_heap_i386_big.out"))
except gdb.error:
pytest.skip("Test not supported on this platform.")
gdb.execute("break break_here")
gdb.execute("continue")
command_output = gdb.execute("largebins --verbose", to_string=True).splitlines()[1:]
expected = [
"0x3f0-0x3f0",
"0x400-0x430",
"0x440-0x470",
"0x480-0x4b0",
"0x4c0-0x4f0",
"0x500-0x530",
"0x540-0x570",
"0x580-0x5b0",
"0x5c0-0x5f0",
"0x600-0x630",
"0x640-0x670",
"0x680-0x6b0",
"0x6c0-0x6f0",
"0x700-0x730",
"0x740-0x770",
"0x780-0x7b0",
"0x7c0-0x7f0",
"0x800-0x830",
"0x840-0x870",
"0x880-0x8b0",
"0x8c0-0x8f0",
"0x900-0x930",
"0x940-0x970",
"0x980-0x9b0",
"0x9c0-0x9f0",
"0xa00-0xa30",
"0xa40-0xa70",
"0xa80-0xab0",
"0xac0-0xaf0",
"0xb00-0xb30",
"0xb40-0xb70",
"0xb80-0xb70", # Largebin 31 (bin 95) is unused, but its size is used to calculate the previous bin's maximum chunk size.
"0xb80-0xbf0",
"0xc00-0xdf0",
"0xe00-0xff0",
"0x1000-0x11f0",
"0x1200-0x13f0",
"0x1400-0x15f0",
"0x1600-0x17f0",
"0x1800-0x19f0",
"0x1a00-0x1bf0",
"0x1c00-0x1df0",
"0x1e00-0x1ff0",
"0x2000-0x21f0",
"0x2200-0x23f0",
"0x2400-0x25f0",
"0x2600-0x27f0",
"0x2800-0x29f0",
"0x2a00-0x2ff0",
"0x3000-0x3ff0",
"0x4000-0x4ff0",
"0x5000-0x5ff0",
"0x6000-0x6ff0",
"0x7000-0x7ff0",
"0x8000-0x8ff0",
"0x9000-0x9ff0",
"0xa000-0xfff0",
"0x10000-0x17ff0",
"0x18000-0x1fff0",
"0x20000-0x27ff0",
"0x28000-0x3fff0",
"0x40000-0x7fff0",
"0x80000-∞",
]
for bin_index, size_range in enumerate(command_output):
assert size_range.split(":")[0] == expected[bin_index]

Loading…
Cancel
Save