Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Conversation

@Liikt
Copy link
Contributor

@Liikt Liikt commented Jun 19, 2025

House of Io has been described in this blog article.

It's an attack which bypasses the safe-linking by abusing the fact that pointers in the tcache management struct are not protected.

This attack only works in libc versions 2.29 - 2.33, as in those versions the key for a free'd tcache chunk is the pointer to the management struct. Afterwards the key is a random value.

As it was missing I thought of implementing the PoC.

@Kyle-Kyle
Copy link
Contributor

Kyle-Kyle commented Jun 26, 2025

Thanks for bringing up house-of-io again!

I think there was a discussion about house-of-io in the past (maybe internally or maybe on how2heap, I can't remember the details) and we decided not to include it due to the need of very special primitives (such as underflow or free of tcache metadata under a very special ordering and structs).
And I think the core idea of house-of-io is that it points out the tcache metadata can be abused even with the presence of safe-linking, which was/is obvious.

But I think now the UAF variant has a bit more value since it got patched and the behavior is different in the latest glibc.

I'll suggest you to modify the PR as follows (and sorry for the extra work)

  • create another variant (for all glibc) that just demonstrates that you can obtain arbitrary allocation by overwriting pointers in the tcache metadata. (maybe just called tcache_metadata_poison, something like that)
  • keep the uaf variant and point out that in the implementation of glibc 2.29-2.33, there is a pointer to the tcache metadata (key), that can be abused to carry out the tcache_metadata_poison attack.
  • remove the double_free/underflow variants. I think these two can be easily derived from the tcache_metadata_poison and house_of_io_uaf

Feel free to share what you think about the plan. I'm open to discussion.

@Liikt
Copy link
Contributor Author

Liikt commented Jun 26, 2025

You are absolutely correct wrt. the constraints of house of io. I pretty much only wanted to add it for completeness sake.

As far as issues or anything, I haven't found any here specifically on house of io.

As I don't see anything wrong with your suggestions, I have implemented all the changes :)

@Liikt
Copy link
Contributor Author

Liikt commented Jun 27, 2025

I just realized you can generate a libc pointer with the metadata poisoning, even if you can only ever allocate and free one chunk. Should I also include that as a bonus maybe?

@Kyle-Kyle
Copy link
Contributor

Kyle-Kyle commented Jun 30, 2025

The new changes look good! I'd love to merge it. But before that, let's discuss your question.

I just realized you can generate a libc pointer with the metadata poisoning, even if you can only ever allocate and free one chunk. Should I also include that as a bonus maybe?

I'm not sure what you mean here. Do you mean putting the tcache metadata region into unsorted bin (or something similar) so you can allocate into libc?

@Kyle-Kyle
Copy link
Contributor

also, can you please fix the CI issue?
I think it is because when tcache was first introduced, the size of the metadata region was different from now. Should be quickly fixable by changing TCACHE_BINS.
If you don't have a setup for the old libcs, just let me know. I'll be able to fix it for the PR.

@Liikt
Copy link
Contributor Author

Liikt commented Jun 30, 2025

The new changes look good! I'd love to merge it. But before that, let's discuss your question.

I just realized you can generate a libc pointer with the metadata poisoning, even if you can only ever allocate and free one chunk. Should I also include that as a bonus maybe?

I'm not sure what you mean here. Do you mean putting the tcache metadata region into unsorted bin (or something similar) so you can allocate into libc?

What I meant is that when you can manipulate the metadata struct you can change the count to 7, filling the tcache without having to free 7 times. This would be helpful when you are constrained in how you can free. But I guess it's a very niche problem.

@Liikt
Copy link
Contributor Author

Liikt commented Jun 30, 2025

also, can you please fix the CI issue?
I think it is because when tcache was first introduced, the size of the metadata region was different from now. Should be quickly fixable by changing TCACHE_BINS.
If you don't have a setup for the old libcs, just let me know. I'll be able to fix it for the PR.

I'll try my luck first tomorrow and let you know if I can't figure it out :D

@Kyle-Kyle
Copy link
Contributor

The new changes look good! I'd love to merge it. But before that, let's discuss your question.

I just realized you can generate a libc pointer with the metadata poisoning, even if you can only ever allocate and free one chunk. Should I also include that as a bonus maybe?

I'm not sure what you mean here. Do you mean putting the tcache metadata region into unsorted bin (or something similar) so you can allocate into libc?

What I meant is that when you can manipulate the metadata struct you can change the count to 7, filling the tcache without having to free 7 times. This would be helpful when you are constrained in how you can free. But I guess it's a very niche problem.

In that case, I guess we can just leave it out because I believe people can figure it out pretty easily with the help of existing tcache_metadata_poisoning (you do touch the count at the end of the technique)

@Kyle-Kyle
Copy link
Contributor

Now everything passes.
Thanks a lot for the contribution!

@Kyle-Kyle Kyle-Kyle merged commit 58c21b5 into shellphish:master Jul 3, 2025
12 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants