Skip to main content

Overview

The House of IO (also called “House of Io Remastered”) exploits the tcache key 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
Patched in glibc 2.34+In glibc 2.34, the tcache key mechanism was changed. The key no longer points directly to the tcache structure, making this specific attack obsolete.
The technique works specifically because:
  • Glibc 2.29+ introduced the key field for double-free protection
  • Glibc 2.29-2.33 set key to the address of tcache_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:
  1. Tcache Metadata Control: Direct manipulation of tcache_perthread_struct
  2. Arbitrary Allocation: Return arbitrary pointers from malloc
  3. Counter Manipulation: Control tcache bin counts
  4. 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:
The key field is set to:
This is used for double-free detection:

Attack Flow

1

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.
2

Free to Get Tcache Pointer

Free the struct. The tcache code sets:
Now the struct contains a direct pointer to tcache metadata!
3

Read Pointer (UAF)

Use UAF to read the pointer at offset +0x08. This gives you the address of tcache_perthread_struct without any leaks!
4

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
5

Allocate Arbitrary Address

Call malloc for the target size. Tcache will return your controlled address.

Source Code

Walkthrough

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:
The tcache_perthread_struct is allocated as the first heap chunk:
Each bin (size class) has:
  • counts[idx]: Number of chunks in this bin (max 7)
  • entries[idx]: Pointer to first chunk in freelist
Size to index: 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]
Safe-linking (glibc 2.32+) mangles the next pointers in tcache:
However:
  • The key field is NOT mangled
  • The pointers in tcache_perthread_struct are NOT mangled
  • Only the next field in freed chunks is mangled
So we can:
  1. Read unmangled tcache struct address from key
  2. Write unmangled target address to tcache->entries[idx]
  3. Get target back from malloc (malloc will mangle/unmangle as needed)
Tcache Poisoning (basic):
  • Requires: UAF to overwrite next pointer
  • Difficulty: Must handle safe-linking mangling (requires heap leak)
  • Result: Single arbitrary allocation
House of IO:
  • Requires: UAF to read/write at +0x08
  • Difficulty: No mangling needed, no leaks needed
  • Result: Complete tcache control, multiple arbitrary allocations
Advantage: House of IO is simpler and more powerful when UAF is available!

Variant: Double-Free Variant

There’s also a double-free variant of House of IO:
This bypasses the double-free check because allocating the chunk back clears the key.

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

  • [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.