Skip to content

Instantly share code, notes, and snippets.

@stefanesser
Last active December 19, 2019 13:46
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save stefanesser/8d57b3c99aba26d898767448f0ab4fed to your computer and use it in GitHub Desktop.
Save stefanesser/8d57b3c99aba26d898767448f0ab4fed to your computer and use it in GitHub Desktop.
BlackHat EU - Wrong information in Talk "Eternal War in XNU Kernel Objects"

It has come to my attention that BlackHat EU had talks from Alibaba Security about iOS security topics. It seems to be from the same people that have previously presented at DEFCON. Back then I had publicly discussed how their talk is basically just a summary of other people's work that is heavily miscredited to the wrong people.

Considering this history it is surprising that BlackHat would allow the same people to give a talk again on iOS security topics. But I have given up a long time ago on the BlackHat review board and their decisions, which is one of the reasons why I have stopped submitting to them years ago.

But I am digressing from the actual reason for this GIST. And no it is not about the fact that the talk once again starts with summarizing other people's work and crediting the wrong parties for the work done. In this GIST I want to go over one of the slides from the "summary part" of the talk, because not a single item on that slide is correct information.

So here is the offending slide:

FreelistMitigation

The first statement is:

"In previous XNU, the freelist that contains all freed kernel objects inside a zone uses the LIFO policy"

This statement is wrong on multiple levels:

  1. Around the time of iOS 9.2 the kernel already had something called page lists. This means for zones using this new feature there exists a per page free-list and not one global freelist.
  2. But even if you ignore (1) and think in terms of a simplification of how the heap works the statement is wrong, because iOS 9.2 did not stop the LIFO policy for free elements inside a free-list at all. In fact up to iOS 12 the LIFO principle is still there for memory coming out of the zone allocator (unless the iOS 12 zone cache is used).

The second statement is:

"To make the adjacent object hard to predict, Apple deployed a mitigation called freelist randomization in iOS 9.2. When a kernel object is freed, the XNU will randomly choose the first or last position of the freelist to store the freed element."

  1. iOS 9.2. does not have a freelist randomization. It has an initial freelist randomization. This means there is no randomization of freelist during usage but only a randomization of fresh memory added to a zone.
  2. Because it is only an initial freelist randomization and not a freelist randomization the claimed random freeing of kernel objects does not happen. When an object is freed it always becomes the HEAD of the freelist (be it an inpage freelist or a global one) - there is no randomness involved.
  3. "XNU will randomly choose the first or last ..." is an attempt to explain the randomization of the initial freelist creation. But even that description is completely wrong. The random initial freelist generation does not randomly add something to the front or the end of the freelist. In fact the random initial freelist generation algorithm repeatedly puts either the first or last block in a page (or allocation unit) to the HEAD of the free list.

The visualization

Before I forget. The picture showing a random freelist shows a random freelist that could never ever have come out of the initial freelist randomizer, because it follows a completely wrong "randomization pattern".

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment