Skip to content

Instantly share code, notes, and snippets.

@cocagne
Created November 16, 2012 16:00
Show Gist options
  • Star 10 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save cocagne/4088467 to your computer and use it in GitHub Desktop.
Save cocagne/4088467 to your computer and use it in GitHub Desktop.
Per-process, read-only filesystem view via Linux's unshare() system call
#!/usr/bin/python
import ctypes
import os
import sys
def err_exit( msg ):
print >> sys.stderr, msg
sys.exit(1)
libc = ctypes.CDLL("libc.so.6")
libc.syscall.argtypes = [ctypes.c_int, ctypes.c_int]
libc.umount.argtypes = [ctypes.c_char_p, ctypes.c_int]
libc.mount.argtypes = [ctypes.c_char_p, # source
ctypes.c_char_p, # target
ctypes.c_char_p, # filesystem_type
ctypes.c_ulong, # mount_flags
ctypes.c_void_p] # data
SYS_unshare = 272 # from asm/unistd_64.h
CLONE_NEWNS = 0x20000 # from linux/sched.h
MS_RDONLY = 1
MS_REMOUNT = 32
MS_BIND = 4096 # from linux/fs.h
MNT_DETACH = 2 # from sys/mount.h
def unshare( flags ):
return libc.syscall(SYS_unshare, flags)
if unshare( CLONE_NEWNS ) < 0:
err_exit("Failed to unshare file system")
with open('/proc/self/mounts') as f:
for line in f:
dev, mp, rest = line.split(' ', 2)
if mp.startswith('/media'):
libc.umount(mp, MNT_DETACH)
for fn in os.listdir('/'):
rfn = '/' + fn
libc.mount(rfn, rfn, 'none', MS_BIND, 0)
libc.mount(rfn, rfn, 'none', MS_BIND | MS_REMOUNT | MS_RDONLY, 0)
print 'Spawning read-only shell'
os.execl('/bin/bash', '/bin/bash')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment