/proc/self/exe overwrite from within a user namespace

mixedbit1 pts0 comments

/proc/self/exe overwrite from within a user namespace — Random notes

Projects

Blog

About

/proc/self/exe overwrite from within a user namespace

I work on Drop, a Linux sandboxing<br>tool that uses user namespaces. As part of the work I have reviewed<br>past vulnerabilities in similar programs.

One such vulnerability was CVE-2019-5736; it allowed rogue<br>processes that ran within a Docker container to escape the container<br>by overwriting the container initialization binary (runc) exposed to<br>the container via /proc/self/exe.

The exploitation wasn’t just a simple write to /proc/self/exe, it<br>required several steps, which I found best described in a post<br>by researchers who discovered the problem.

The often-repeated comment about this vulnerability was that the<br>problem was that runc runs as root. The original runc bug announcement<br>mentions: “The vulnerability is blocked through correct use of user<br>namespaces (where the host root is not mapped into the container’s<br>user namespace).”. Posts in the Hacker News discussion about the bug mention that user<br>namespaces are the answer and that running a container as root is careless.

The comments did not explain why rootless containers are not affected,<br>and the exploit steps didn’t look like something that obviously<br>couldn’t be done in the user namespace, so, to be safe, I tried to<br>redo the exploit for Drop. The original exploit replaced a library<br>that the runc executable loads dynamically with a rogue one, which<br>allowed it to execute attacker-controlled code within the sandboxed<br>runc. This in turn allowed to replace the original runc binary by<br>overwriting the content of /proc/self/exe. This is not possible<br>with Drop for several reasons:

The Drop executable is statically linked

Even if it were linked dynamically, Drop is not a<br>container; the sandboxed process is not able to control the content of<br>the root filesystem and place its own libraries in /usr.

The sandboxed process is also not able to change the content of the<br>LD_PRELOAD environment variable it is run with.

None of these reasons are fundamental to user namespaces. I changed<br>the Drop executable to work around the obstacles, and with these<br>changes I was able to replace the executable from within the sandbox.<br>The conclusion of my experiments is that rootless containers are safe<br>without an additional mitigation mechanism, but ONLY if the<br>container initialization binary is owned and writable only by root.

If the initialization binary is placed in, say, ~/.local/bin and<br>is owned by the current user, it can be susceptible to CVE-2019-5736<br>in the same way that runc was, and can require additional mitigation<br>to protect against this vulnerability; user namespaces alone are not<br>enough.

Posted by Jan Wrobel; June 12, 2026

All posts

/proc/self/exe overwrite from within a user namespace

Improving Unit Test Coverage with Gemini

Shapespark

wwwhisper add-on for Node.js

Object Oriented Programming with closures

wwwhisper add-on released

DoS attack on CDN users

wwwhisper add-on update

Underhanded C Contest

wwwhisper add-on update

Random walk illustrated with D3

Django DB Pool on Heroku

wwwhisper Heroku add-on

C++ puzzle

Productivity Tip of the Week

wwwhisper on OpenShift

Sibling domains cookies isolation

user container proc self within runc

Related Articles