Skip to content
A "living" Linux process with no memory
C Python
Branch: master
Clone or download

Latest commit

1
Latest commit 85ffcf8 Mar 26, 2020

Files

Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
README.md meow Mar 26, 2020
fs.py meow Mar 26, 2020
zeromaps.c meow Mar 26, 2020

README.md

A "living" Linux process with no memory

tl;dr

  • thread1 goes into uninterruptible sleep
  • thread2 unmaps everything and segfaults
  • segv can't kill the process because of thread1's D state
  • /proc/pid/maps is now empty
  • ???
  • PROFIT!!!

asciicast

Implementation details

This code gets a list of all memory maps from /proc/self/maps, then creates a new executable map where it jits some code that calls munmap() on each of the maps it just got, and finally on the map it's on. This is just a quick example with no portability in mind, so the source code contains the actual bytes that would be emitted by a x64 compiler. After unmapping the final map, where the jit code lies, there's no new instruction to execute and a segfault is raised.

This segfault can't kill the entire process if one thread is stuck in uninterruptible sleep. To reliably send a thread in such state, we create a simple FUSE filesystem in python, in which doing anything on a particular file will block until a key is pressed.

This code also does its own "linking" to make sure that the list of maps doesn't get unmapped too early.

Requirements

  • a c compiler
  • python2 + fuse
  • x64
  • a modern Linux with no vsyscall page (this page is too high up and munmap would return EINVAL)

Why

I don't know. I thought it was funny.

You can’t perform that action at this time.