mimmutable
In August 2022, Stephen Röttger and Dave Hansen
were discussing making some VMA on Linux
immutable, as part of the upcoming V8 CFI scheme,
to plug a low-hanging pkey bypass
where an attacker would remap an address covered with a pkey
they don’t have
access to.
In September 2022, De Raadt added
a way to lock memory mappings via the new mimmutable
syscall:
This identifies all current mapped memory in a region, and tags the mappings. Such mappings can never be unmapped. No new mmap can be done on top of the mappings. And the permissions cannot be changed. Other than that, the underlying storage memory works fine, it is just the mapping that is locked.
Apparently, De Raadt is “aware of an method used at least once (not on OpenBSD)
which managed to mprotect
a region of libc, and then place things there, for
later execution.”, which not only sounds dumb (why would anyone mprotect
the
libc mapping‽), but jumping to mmap
isn’t exactly a new technique. Moreover,
nobody, in any real-life exploit so far, relied on changing some library
mappings to do anything, except:
- Once in a zer0pts CTF 2021 challenge writeup, but it could trivially have used another technique instead.
- Another time by Qualys in their CVE-2023-38408: Remote Code Execution in OpenSSH’s forwarded ssh-agent
exploit, but beside being an exotic exploit, it also required:
- an executable stack, done by loading libraries either without an
GNU_STACK
ELF header, or with anRWE
one. The former doesn’t work on grsecurity, and there is a patch by Ramon de C Valle from 2012, and another one by Kees Cook in 2020 to address this behaviour. As of 2023, it still isn’t fixed on Linux, but was addressed on OpenBSD the 8th of June 2016 by Mark Kettenis. dlclose
unmapping loaded libraries, which isn’t the case on musl libc, but is the case on OpenBSD, thus bypassingmimmutable
.
- an executable stack, done by loading libraries either without an
- To bypass the upcoming aforementioned pkey-based V8 CFI scheme, which doesn’t work on OpenBSD in the first place.
- The House of Muney glibc exploitation technique, that doesn’t work on otto-malloc.
An interesting usecase for immutable mapping is highlighted in Control-flow Integrity in V8:
For example, if a thread calls munmap on a corrupted pointer, the attacker could unmap read-only pages and a consecutive mmap call can reuse this address, effectively adding write permissions to the page. Some OSes already provide protections against this attack with memory sealing: Apple platforms provide the VM_FLAGS_PERMANENT flag and OpenBSD has an mimmutable syscall.
In 2023, in his CanSecWest talk, he elaborated on this, saying that it was likely an iPhone exploit, likely the talk from Charlie Miller and Vincenzo Iozzo, at BlackHat 2009, about bypassing code signature.
Interestingly, he also mentioned there that mimmutable
will be used in the
future, for security-related features, building on top of the invariants it
provides.
This looks like a partial copy of
PAX_MPROTECT
, implemented
21 years after its publication, without giving credit,
and after having argued in April
2003 that it was
violating “POSIX by breaking mprotect”.
The 16th of October 2023, Jeff Xu from Google sent a patch to
implement Introduce mseal() syscall in Linux,
a feature similar to mimmutable
, but with v8 CFI exotic threat model in mind.
But in all fairness, De Raadt never called mimmutable
a security improvement.