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!

That's FAR-out, Man- 1296

Dataflow SecurityPosted 2 Years Ago
  • This report is about an information leak that was discovered by accident. In some cases, the userland processes on an XNU system could crash with a kernel pointer in the far register. This was a great information leak that could be done over and over again. However, the cause of the bug is very complicated.
  • Exceptions happen when the userland program has done something illegal, such as access unmapped memory. On arm64, the Vector Base Address Register holds a table where the kernel should jump to. There are many different exception types that are all handled by specific functions.
  • The addresses we see in GDB aren't real - they're virtual. The CPUs create an abstraction layer between the physical memory and the virtual memory using page tables. This allows for the reuse of the same page and separate permission settings on that.
  • When a fault occurs, the address will be put into the FAR_ELn register for some exception types. However, if the register is not used on the exception, it's also NOT cleared. This creates some ambiguity on what to do with it.
  • Within XNU, the entire core state is copied into the threads data structure. This is done in order to optimize the hot code, as opposed to only copying in things conditionally. Finally, we have enough to understand the bug!
  • Consider the following scenarios:
    1. A write triggers a fault on a unmapped page, resulting in a data abort exception.
    2. The adress of data is copied to FAR_EL1.
    3. The exception is handled by XNU.
    4. The core switches to executing in userland once again.
    5. Another exception occurs, such as a breakpoint debug instruction.
    6. FAR_EL1 is NOT updated because of the specific exception type but other data is.
    7. XNU copies the cores state.
  • Using the scenario above, step 6 gets stale data copied in. This is a typically uninitialized memory issue. This isn't just a standard memory leak though! This pointer is a pointer to the thread information that can be used to query information about the crashing state of a task. Since this is using the wrong task, we can get leaked from various other tasks and leak kernel pointers. Sick!
  • To make this more reliable, they found that forcing crashesat a specific memory offset within an unmapped page made it better. An additional way was relying on the object having a pre-known size, which would leak a bunch of information after that.
  • The bug is fascinating. I do not fully understand where the information is truly leaked at bug enjoyed it regardless. Sometimes, observing strange behavior can lead you to crazy bugs.