Plans to strengthen the W^X security mechanism in OpenBSD

Theo De Raadt shared plans to strengthen the W^X (Write XOR Execute) memory protection mechanism. The essence of the mechanism is that process memory pages cannot be simultaneously available for writing and execution. Thus, the code can be executed only after the write is disabled, and writing to the memory page is possible only after the execution is disabled. The W^X mechanism helps protect user-space applications from common buffer overflow attacks, including stack overflows, and is active on OpenBSD by default.

From the beginning of work on W^X, it was clear that this was a long road, since there are a significant number of applications that use JIT. JIT implementations can be divided into three categories:

  • Switching memory between W and X states, resigning to the "cost" of a system call mprotect.
  • Create aliases between a pair of W and X mappings of the same memory.
  • The most "dirty" option - requiring a W|X memory model that allows simultaneous recording and execution.

At present, there are significantly fewer programs using the third option and more using the first and second. However, since it was also necessary to run programs with W|X JIT (mainly Chromium and Iridum), the "wxallowed" filesystem mount option was added, which allowed memory to be used both for writing and for execution, in case if the ELF executable file is marked with the β€œwxneeded” marker, and the applications themselves were additionally protected using mechanisms pledge ΠΈ unveiled to limit the list of used system calls and available parts of the file system for the application, respectively.

To further complicate the exploitation of vulnerabilities in such applications, an addition to the mechanism MAP_STACK, which checks if the system call is being executed from a writable memory page. If the page is writable, the process is forcibly terminated. Thus, the attacker will not be able to use system calls and will be forced to try to find the right gadgets in the JIT implementation, or even do the harder work of discovering system call stubs directly inside randomly linked libc.

Chrome/Iridium processes are already quite well protected by pledge and unveil, but preventing the write(2) system call from being used, for example, obviously has some advantage, as it creates additional difficulties for the attacker. However, complications can also arise if the JIT implementation uses native system calls from W|X memory. However, there is reason to hope that this will not be encountered, since the ABI has changed many times, but no one has ever reported problems.

The changes are already available in regular snapshots of the OpenBSD-Current branch, all interested are invited to test.

A separate comment from Theo deserved related news about the appearance of mode in Chrome / Iridium JITless. From his point of view, this is acceptable for some use cases, but probably not for all, since in this mode the load on the processor will obviously increase. Right now Chrome will mostly work if "wxallowed" is disabled for /usr/local, although there are likely to be issues with some extensions (ghostery is cited as an example). One way or another, Theo hopes that full-fledged work in JITless mode will be brought to a fully working state in the near future.

Source: opennet.ru

Add a comment