I have this very sophisticated program:
#include <gnu/libc-version.h>
uint64_t *ptr = malloc(0x20);
puts (gnu_get_libc_version ());
<code>#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <gnu/libc-version.h>
int main() {
uint64_t *ptr = malloc(0x20);
memset(ptr, 0x55, 0x20);
free(ptr);
printf("%lxn",ptr);
printf("%lxn",*ptr);
puts (gnu_get_libc_version ());
fgetc(stdin);
return 0;
}
</code>
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <gnu/libc-version.h>
int main() {
uint64_t *ptr = malloc(0x20);
memset(ptr, 0x55, 0x20);
free(ptr);
printf("%lxn",ptr);
printf("%lxn",*ptr);
puts (gnu_get_libc_version ());
fgetc(stdin);
return 0;
}
When I run the program I get the following output:
<code>6068ba91e2a0
6068ba91e
2.39
</code>
6068ba91e2a0
6068ba91e
2.39
I actually thought I would find a 64bit address, that would assemble a forward pointer of the heap struct.
It seems the actual output is missing the lower 12 bits.
I can confirm this in gdb:
<code>─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── threads ────
[#0] Id 1, Name: "test", stopped 0x79cd7111ba61 in __GI___libc_read (), reason: SIGINT
───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── trace ────
[#0] 0x79cd7111ba61 → __GI___libc_read(fd=0x0, buf=0x6068ba91e6e0, nbytes=0x400)
[#1] 0x79cd71092795 → _IO_new_file_underflow(fp=0x79cd712038e0 <_IO_2_1_stdin_>)
[#2] 0x79cd710955c2 → __GI__IO_default_uflow(fp=0x79cd712038e0 <_IO_2_1_stdin_>)
[#3] 0x6068acf781c7 → main()
────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
gef➤ x/10gx 0x6068ba91e2a0
0x6068ba91e2a0: 0x00000006068ba91e 0x24c2c355acc8d4bb
0x6068ba91e2b0: 0x5555555555555555 0x5555555555555555
0x6068ba91e2c0: 0x0000000000000000 0x0000000000000411
0x6068ba91e2d0: 0x3139616238363036 0x0000000a30610a65
0x6068ba91e2e0: 0x0000000000000000 0x0000000000000000
───────────────────────────────────────────────────────────────────────────────────────────────────────── Tcachebins for thread 1 ─────────────────────────────────────────────────────────────────────────────────────────────────────────
Tcachebins[idx=1, size=0x30, count=1] ← Chunk(addr=0x6068ba91e2a0, size=0x30, flags=PREV_INUSE | IS_MMAPPED | NON_MAIN_ARENA)
─────────────────────────────────────────────────────────────────────────────────────────────────── Fastbins for arena at 0x79cd71203ac0 ───────────────────────────────────────────────────────────────────────────────────────────────────
Fastbins[idx=0, size=0x20] 0x00
Fastbins[idx=1, size=0x30] 0x00
Fastbins[idx=2, size=0x40] 0x00
Fastbins[idx=3, size=0x50] 0x00
Fastbins[idx=4, size=0x60] 0x00
Fastbins[idx=5, size=0x70] 0x00
Fastbins[idx=6, size=0x80] 0x00
───────────────────────────────────────────────────────────────────────────────────────────────── Unsorted Bin for arena at 0x79cd71203ac0 ─────────────────────────────────────────────────────────────────────────────────────────────────
[+] Found 0 chunks in unsorted bin.
────────────────────────────────────────────────────────────────────────────────────────────────── Small Bins for arena at 0x79cd71203ac0 ──────────────────────────────────────────────────────────────────────────────────────────────────
[+] Found 0 chunks in 0 small non-empty bins.
────────────────────────────────────────────────────────────────────────────────────────────────── Large Bins for arena at 0x79cd71203ac0 ──────────────────────────────────────────────────────────────────────────────────────────────────
[+] Found 0 chunks in 0 large non-empty bins.
<code>─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── threads ────
[#0] Id 1, Name: "test", stopped 0x79cd7111ba61 in __GI___libc_read (), reason: SIGINT
───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── trace ────
[#0] 0x79cd7111ba61 → __GI___libc_read(fd=0x0, buf=0x6068ba91e6e0, nbytes=0x400)
[#1] 0x79cd71092795 → _IO_new_file_underflow(fp=0x79cd712038e0 <_IO_2_1_stdin_>)
[#2] 0x79cd710955c2 → __GI__IO_default_uflow(fp=0x79cd712038e0 <_IO_2_1_stdin_>)
[#3] 0x6068acf781c7 → main()
────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
gef➤ x/10gx 0x6068ba91e2a0
0x6068ba91e2a0: 0x00000006068ba91e 0x24c2c355acc8d4bb
0x6068ba91e2b0: 0x5555555555555555 0x5555555555555555
0x6068ba91e2c0: 0x0000000000000000 0x0000000000000411
0x6068ba91e2d0: 0x3139616238363036 0x0000000a30610a65
0x6068ba91e2e0: 0x0000000000000000 0x0000000000000000
gef➤ heap bin
───────────────────────────────────────────────────────────────────────────────────────────────────────── Tcachebins for thread 1 ─────────────────────────────────────────────────────────────────────────────────────────────────────────
Tcachebins[idx=1, size=0x30, count=1] ← Chunk(addr=0x6068ba91e2a0, size=0x30, flags=PREV_INUSE | IS_MMAPPED | NON_MAIN_ARENA)
─────────────────────────────────────────────────────────────────────────────────────────────────── Fastbins for arena at 0x79cd71203ac0 ───────────────────────────────────────────────────────────────────────────────────────────────────
Fastbins[idx=0, size=0x20] 0x00
Fastbins[idx=1, size=0x30] 0x00
Fastbins[idx=2, size=0x40] 0x00
Fastbins[idx=3, size=0x50] 0x00
Fastbins[idx=4, size=0x60] 0x00
Fastbins[idx=5, size=0x70] 0x00
Fastbins[idx=6, size=0x80] 0x00
───────────────────────────────────────────────────────────────────────────────────────────────── Unsorted Bin for arena at 0x79cd71203ac0 ─────────────────────────────────────────────────────────────────────────────────────────────────
[+] Found 0 chunks in unsorted bin.
────────────────────────────────────────────────────────────────────────────────────────────────── Small Bins for arena at 0x79cd71203ac0 ──────────────────────────────────────────────────────────────────────────────────────────────────
[+] Found 0 chunks in 0 small non-empty bins.
────────────────────────────────────────────────────────────────────────────────────────────────── Large Bins for arena at 0x79cd71203ac0 ──────────────────────────────────────────────────────────────────────────────────────────────────
[+] Found 0 chunks in 0 large non-empty bins.
gef➤
</code>
─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── threads ────
[#0] Id 1, Name: "test", stopped 0x79cd7111ba61 in __GI___libc_read (), reason: SIGINT
───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── trace ────
[#0] 0x79cd7111ba61 → __GI___libc_read(fd=0x0, buf=0x6068ba91e6e0, nbytes=0x400)
[#1] 0x79cd71092795 → _IO_new_file_underflow(fp=0x79cd712038e0 <_IO_2_1_stdin_>)
[#2] 0x79cd710955c2 → __GI__IO_default_uflow(fp=0x79cd712038e0 <_IO_2_1_stdin_>)
[#3] 0x6068acf781c7 → main()
────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
gef➤ x/10gx 0x6068ba91e2a0
0x6068ba91e2a0: 0x00000006068ba91e 0x24c2c355acc8d4bb
0x6068ba91e2b0: 0x5555555555555555 0x5555555555555555
0x6068ba91e2c0: 0x0000000000000000 0x0000000000000411
0x6068ba91e2d0: 0x3139616238363036 0x0000000a30610a65
0x6068ba91e2e0: 0x0000000000000000 0x0000000000000000
gef➤ heap bin
───────────────────────────────────────────────────────────────────────────────────────────────────────── Tcachebins for thread 1 ─────────────────────────────────────────────────────────────────────────────────────────────────────────
Tcachebins[idx=1, size=0x30, count=1] ← Chunk(addr=0x6068ba91e2a0, size=0x30, flags=PREV_INUSE | IS_MMAPPED | NON_MAIN_ARENA)
─────────────────────────────────────────────────────────────────────────────────────────────────── Fastbins for arena at 0x79cd71203ac0 ───────────────────────────────────────────────────────────────────────────────────────────────────
Fastbins[idx=0, size=0x20] 0x00
Fastbins[idx=1, size=0x30] 0x00
Fastbins[idx=2, size=0x40] 0x00
Fastbins[idx=3, size=0x50] 0x00
Fastbins[idx=4, size=0x60] 0x00
Fastbins[idx=5, size=0x70] 0x00
Fastbins[idx=6, size=0x80] 0x00
───────────────────────────────────────────────────────────────────────────────────────────────── Unsorted Bin for arena at 0x79cd71203ac0 ─────────────────────────────────────────────────────────────────────────────────────────────────
[+] Found 0 chunks in unsorted bin.
────────────────────────────────────────────────────────────────────────────────────────────────── Small Bins for arena at 0x79cd71203ac0 ──────────────────────────────────────────────────────────────────────────────────────────────────
[+] Found 0 chunks in 0 small non-empty bins.
────────────────────────────────────────────────────────────────────────────────────────────────── Large Bins for arena at 0x79cd71203ac0 ──────────────────────────────────────────────────────────────────────────────────────────────────
[+] Found 0 chunks in 0 large non-empty bins.
gef➤
The free’d chunk got moved to tCache.
Why are the lower 12 bits missing or does tCache (and fastbin) behave differently?
My system is Kubuntu 24.04.1, glibc 2.39.
EDIT:
I’m aware that one should not use the pointer after free, but this is not my intention. I want to learn about the internals of heap allocation, since I got assigned a task in university where I need to analyze a program. There i stumbled over this behavior and I was not able to explain it.