In this article:
In FreeBSD early days, shared memory (SHM) objects were associated to an actual file system object. Each jail having its own filesystem root, SHM object were therefore not reachable by other jails.
FreeBSD 7.0 switched to a purely abstract representation of SHM objects. They are now just names, with no relation to the underlying filesystem.
Due to this, any jail gained a read-write access to any SHM object system-wide, with no available workaround to prevent or limit this (this is not to be confused with IPCs which can be disabled on a per-jail basis, here there is strictly no way to prevent the issue).
fbsd-shm-hole.c is a small POC allowing to quickly test and demonstrate the issue.
Compile and copy this tool in two different jails.
In the first jail, pass an arbitrary SHM object path and a some string as parameter to this tool:
user@jail1:~$ ./fbsd-shm-hole /foo/bar "Anything there?" user@jail1:~$
On the second jail pass only the path, the content of the string will be read from the SHM object and displayed on the output:
user@jail2:~$ ./fbsd-shm-hole /foo/bar Anything there? user@jail2:~$
As demonstrated by the POC, two cooperative processes located in different jails can freely communicate.
This opens an issue in particular for air-gaped jails. While a malware executing in such environment is known to be able alter or destruct the content of the jail (which is usually harmless thanks to snapshots), the lack of communication medium in the jail ensures that no data stored in the jail could be exfiltrated.
Thanks to this system, it becomes possible to use an untrusted jail with networking capabilities as a pivot to control a payload executing in such an air-gaped jail and gain a full access to its content.
Any process relying on SHM objects is susceptible to be attacked from any jail. Moreover SHM objects being usually trusted by the software their content is often not sanitized, leaving a wide range of possible exploits ranging from a simple denial-of-service to arbitrary command execution.
A good example of such vulnerable software is the Squid proxy. This software relies on SHM objects for its inter-process communication and is therefore vulnerable to this issue, in particular when several workers are enabled in which case Squid immediately segfaults as-soon-as a few garbage is written in its shared memory.
In this example, Squid process SHM objects are writable from any jail, and any attacker gaining control of the Squid process becomes in measure to execute man-in-the-middle attacks on every communication routed through this software (and also gains a read-write access to the proxy cache content).
Normally the usage of IPC resources should be limited to some trusted jails
allow.sysipc jail(8) setting:
- A process within the jail has access to System V IPC primitives. In the current jail implementation, System V primitives share a single namespace across the host and jail environments, meaning that processes within a jail would be able to communicate with (and potentially inter- fere with) processes outside of the jail, and in other jails.
However, due to the historical implementation mentioned in the introduction this setting only affects the IPC queues and does not affect other IPC objects such as SHM.
There is therefore no mitigation measure available for this issue on vulnerable systems.
FreeBSD development team has been informed of this issue in March 2016.
They fixed the issue by changing the way SHM objects were handled internally,
allow.sysipc to now take all IPC objects and
updated the jail(8) man page accordingly.
This fix is available for FreeBSD 10.3 and above.