Jumping Through Hoops^H^H^H^H^Hrings
by Jeff NathanPeople of Earth, I send to you greetings from CanSecWest. After several years of performing in rock bands, my hearing is slightly damaged and I suffer from a reasonably annoying case of tinnitus. Sadly, I have difficulty understanding many non-native English speakers at security conferences, especially when I’m not close enough to actually hear their unamplified voice. Due to some unexplained planetary alignment and the clarity of Loic Duflot’s voice, I was able to hear the entirety of a fantastic presentation.
To save you some time on my analysis that follows, here’s the gist of Duflot’s presentation: a problem in X11 is that the entire system runs in userland; because of the need to write to video memory, an attacker could run arbitrary code outside the OS and do all sorts of fun things like write to EFLAGS, EIP or any other physical memory address (as far as I understand the issue).
If knowledge of superheros became a hot topic in information security, I’d be at the top of the foodchain. Unfortunately, my knowledge of Intel Pentium 4 architecture is substantially less complete; that said, I know enough to be mildly dangerous. In his presentation, Duflot mentioned the four modes of CPU operation and focused on System Management Mode (SMM). When a System Management Interrupt (SMI) is raised, the CPU saves all its state and enters SMM. There are a veritable litany of events that can raise an SMI interrupt and on one slide, Duflot presented a table of no fewer than 35 causes for an SMI to be generated. So clearly, there’s no shortage of ways in which an SMI can be generated (At one point, I saw someone lean over and feel a nearby attendee’s laptop, whose fan was on; he mentioned that the laptop’s thermal circuitry had generated an SMI when spinning up the fan).
Without further delving too deep into yawn-inducing details, I will mention that SMM runs in Real mode, all segments are writable with full 4GB memory addressing, and that the EFLAGS and EIP registers are writable. SMM also has its own bit of memory that isn’t actually separate physical memory, but is instead a block of memory between the i386 640K limit and 1MB which coincidentally overlaps legacy video memory and which userspace programs are generally prevented from accessing. SMM uses a special register aptly named the System Management RAM Control Register to control accesses to SMRAM. Specifically, the 6th bit (indexed from the 0th bit) is D_OPEN and controls writes to SMRAM from outside SMM.
Duflot was careful to remind us that that all the fancy memory segmentation, paging, and memory protection technology such as OpenBSD’s W^X and Grsecurity’s SEGMEXEC exist only in protected mode.
Building up to the presentation’s crescendo, a slide coyly asked, “…there is no way to switch to other modes from userspace, right?” He went on to describe an attack scheme where an attacker could replace the default SMI handler with a special handler and trigger an SMI interrupt to perform an action completely unbeknownst to the operating system. With access to the SMM control register, access to at least one I/O register asserts an SMI, and write access to SMRAM (or simply access to the legacy video RAM) could be achieved.
So assuming you already had access to the SMM control register, access to at least one I/O register that can assert an SMI and write access to SMRAM, why would you even care about switching to another mode? Enter OpenBSD; when securelevel is set to either 1 or 2, root is prevented raw access to disks, direct access to physical memory, and write access to /dev/mem and /dev/kmem. At this point, Duflot finally revealed the crux of his entire presentation. The /dev/xf86 pseudo device is similar to /dev/mem but with access only to video memory areas (which coincidentally overlap SMRAM). On any OpenBSD system where the machdep.allowaperture sysctl is set to 1, access to /dev/xf86 is allowed.
Duflot described a scenario where an attacker could execute code as root and subsequently uses the i386_iopl(2) syscall to allow access to the I/O address space, writes to SMRAM via /dev/xf86, and triggers an SMI to run his handler - which coincidentally lowers the securelevel back to 0 (something that shouldn’t be possible on a system in multi-user mode). I don’t know about the rest of you, but I was pretty impressed.
Here’s the most important piece of information from the presentation, IMO: while it was really neat to see an exploit that ran code in SMM mode, the real issue is that X11 device access is occurring within userspace, and the current implementation is really dangerous. The suggestion seems to be that Microsoft Windows has moved much of the video memory access to the kernel, and that X11 should do the same.
The problem isn’t really that X11 is executing in usermode. It is that it relies on having access to arbitrary I/O registers. x86 hardware does support fine-grained access controls on I/O registers, but that support isn’t being used by OpenBSD (or anything else other than a few security-oriented research OSes).