Resources

People often ask me "How did you learn how to hack?" The answer: by reading. This page is a collection of the blog posts and other articles that I have accumulated over the years of my journey. Enjoy!

Gaining kernel code execution on an MTE-enabled Pixel 8- 1371

Man Yue MoPosted 2 Years Ago
  • Memory Tagging Extensions (MTE) is a memory corruption protection that was widely considered to be a killer of these types of bugs. The idea is to use the upper bits of a 64 bit pointer to give a random value to it. If the tag of the memory is different than the pointer being used, then a fault occurs, stopping the exploit.
  • The author of this post bought a Pixel 8, enabled MTE then tried to find a vulnerability that would work around these protections. They ended up targeting the JIT memory of the Arm Mali GPU driver.
  • When accessing a page that doesn't have a valid memory mapping, the GPU will increase the size of the space. However, there isn't proper locking when this occurs. So, a race condition allows for an invalid state to be created to cause pseudo-memory corruption.
  • Using some black magic, it's possible to mess with the mappings of the JIT memory. In particular, a section of memory can be treated as unmapped, even though it really isn't. Since the section is freed, it can be allocated as a standard kernel memory allocation.
  • Eventually, using some allocation magic, it's possible to get this memory to be used in the kernel (including kernel code) but still available to the GPU. Now, it's possible to rewrite the kernel from the GPU in order to compromise everything.
  • So, how does this bypass MTE? Well, there's no memory corruption! The pages array in the kernel and the GPU mappings of the JIT are valid from a memory corruption perspective. Since these are accessing physical pages, the MTE protections are not in place.
  • Overall, an interesting look into how some bugs do not care about MTE. The post goes too deep into the weeds of GPUs and kernel for me to understand but it's interesting to get the generic flow none-the-less.