Overview
The House of IO (also called “House of Io Remastered”) exploits the tcachekey field to manipulate the tcache_perthread_struct and achieve arbitrary allocation. When a chunk is freed into tcache, it receives a pointer to the tcache management struct in its key field. With UAF, this pointer can be used to directly manipulate tcache metadata.
This technique is particularly powerful because it works even with safe-linking enabled, as the tcache key pointer is not mangled.
Glibc Version Compatibility
Compatible with: glibc 2.29 - 2.33 only
- Glibc 2.29+ introduced the
keyfield for double-free protection - Glibc 2.29-2.33 set
keyto the address oftcache_perthread_struct - Glibc 2.34+ changed how the key works
Requirements
- Use-After-Free: Ability to read from and write to a freed tcache chunk
- Pointer at Offset +0x08: The UAF struct must have a pointer accessible at +0x08 (the key location)
- No Leaks Required: The technique doesn’t require address leaks
- Single Free: Only one free is needed
What It Achieves
The House of IO enables:- Tcache Metadata Control: Direct manipulation of
tcache_perthread_struct - Arbitrary Allocation: Return arbitrary pointers from malloc
- Counter Manipulation: Control tcache bin counts
- Freelist Poisoning: Insert arbitrary addresses into tcache freelists
Technical Details
The Tcache Key Field
When a chunk is freed into tcache (glibc 2.29-2.33), the following occurs:key field is set to:
Attack Flow
Allocate Struct with Pointer at +0x08
Allocate a structure that has a pointer at offset +0x08 from the user data. This will align with where the tcache
key field will be placed.Free to Get Tcache Pointer
Free the struct. The tcache code sets:Now the struct contains a direct pointer to tcache metadata!
Read Pointer (UAF)
Use UAF to read the pointer at offset +0x08. This gives you the address of
tcache_perthread_struct without any leaks!Manipulate Tcache Metadata
Use the pointer to directly modify tcache metadata:
- Increase counter for a bin:
tcache->counts[idx] = N - Insert arbitrary address:
tcache->entries[idx] = target
Source Code
Walkthrough
Why Offset +0x08 Matters
Why Offset +0x08 Matters
The tcache chunk layout in memory is:If your structure has any pointer at offset +0x08, you can use UAF to read the tcache pointer even if the structure wasn’t designed for exploitation!Example vulnerable structures:
Tcache Perthread Struct Layout
Tcache Perthread Struct Layout
The Each bin (size class) has:
tcache_perthread_struct is allocated as the first heap chunk:counts[idx]: Number of chunks in this bin (max 7)entries[idx]: Pointer to first chunk in freelist
idx = (size >> 4) - 1Examples:- Size 0x20: idx = 0, counts[0], entries[0]
- Size 0x30: idx = 1, counts[1], entries[1]
- Size 0x80: idx = 6, counts[6], entries[6]
Why Safe-Linking Doesn't Protect This
Why Safe-Linking Doesn't Protect This
Safe-linking (glibc 2.32+) mangles the However:
next pointers in tcache:- The
keyfield is NOT mangled - The pointers in
tcache_perthread_structare NOT mangled - Only the
nextfield in freed chunks is mangled
- Read unmangled tcache struct address from
key - Write unmangled target address to
tcache->entries[idx] - Get target back from malloc (malloc will mangle/unmangle as needed)
Comparison with Other Tcache Attacks
Comparison with Other Tcache Attacks
Tcache Poisoning (basic):
- Requires: UAF to overwrite
nextpointer - Difficulty: Must handle safe-linking mangling (requires heap leak)
- Result: Single arbitrary allocation
- Requires: UAF to read/write at +0x08
- Difficulty: No mangling needed, no leaks needed
- Result: Complete tcache control, multiple arbitrary allocations
Variant: Double-Free Variant
There’s also a double-free variant of House of IO:CTF Challenges
No specific challenges listed, but applicable to:- CTF challenges on glibc 2.29-2.33
- Challenges with UAF on structures with pointers
- Modern heap challenges before glibc 2.34
References
- Original House of IO Remastered
- Safe-linking doesn’t protect tcache struct pointers
Related Techniques
- [Tcache Poisoning/techniques/tcache/tcache-poisoning) - Direct next pointer overwrite
- House of Water - Another tcache metadata control technique
- [Tcache Metadata Poisoning/techniques/tcache/tcache-metadata-poisoning) - Direct metadata control
Notes
Negative Overflow VariantThe source mentions a “negative overflow variant” which is very rare. This would involve overflowing backwards to corrupt the tcache key of a chunk before it’s freed.Order-Dependent Free VariantAnother variant relies on specific free orderings to craft the attack, which is also quite constrained.The UAF variant shown here is the most practical.
