def start(self): tmp = tempfile.mkdtemp() mount_tmpfs(self.fs_size, tmp) put_old = 'root' old_root = os.path.join(tmp, put_old) os.mkdir(old_root) usr_mount = os.path.join(tmp, 'usr') try_mkdir(usr_mount) flags = const.MS_NODEV | const.MS_NOSUID | const.MS_NOATIME mount_bind(self.usr_path, usr_mount, flags) flags |= const.MS_REMOUNT | const.MS_RDONLY mount_bind(self.usr_path, usr_mount, flags) ignore_mounts = ['/', '/proc', '/usr'] def jail(): os.environ.clear() os.environ.update( PATH = '/usr/bin', HOME = '/', ) if self.hostname: sethostname(self.hostname) pivot_root(tmp, old_root) os.chdir('/') mount_proc() umount_all(ignore_mounts) os.rmdir('/' + put_old) os.symlink('/usr/lib', '/lib') os.symlink('/usr/lib', '/lib64') mount_tmpfs(self.fs_size, '/', const.MS_REMOUNT | const.MS_RDONLY) self.setup_workers() try: pid = clone_and_wait( jail, const.CLONE_NEWNS | const.CLONE_NEWPID | const.CLONE_NEWUTS | const.CLONE_NEWNET | const.CLONE_NEWIPC ) finally: umount(usr_mount) umount(tmp) os.rmdir(tmp)
def start(self): tmp = tempfile.mkdtemp() mount_tmpfs(self.fs_size, tmp) put_old = 'root' old_root = os.path.join(tmp, put_old) os.mkdir(old_root) usr_mount = os.path.join(tmp, 'usr') try_mkdir(usr_mount) flags = const.MS_NODEV | const.MS_NOSUID | const.MS_NOATIME mount_bind(self.usr_path, usr_mount, flags) flags |= const.MS_REMOUNT | const.MS_RDONLY mount_bind(self.usr_path, usr_mount, flags) ignore_mounts = ['/', '/proc', '/usr'] def jail(): os.environ.clear() os.environ.update( PATH='/usr/bin', HOME='/', ) if self.hostname: sethostname(self.hostname) pivot_root(tmp, old_root) os.chdir('/') mount_proc() umount_all(ignore_mounts) os.rmdir('/' + put_old) os.symlink('/usr/lib', '/lib') os.symlink('/usr/lib', '/lib64') mount_tmpfs(self.fs_size, '/', const.MS_REMOUNT | const.MS_RDONLY) self.setup_workers() try: pid = clone_and_wait( jail, const.CLONE_NEWNS | const.CLONE_NEWPID | const.CLONE_NEWUTS | const.CLONE_NEWNET | const.CLONE_NEWIPC) finally: umount(usr_mount) umount(tmp) os.rmdir(tmp)
def start(self): tmp = tempfile.mkdtemp() mount_tmpfs(self.fs_size, tmp) put_old = "root" old_root = os.path.join(tmp, put_old) os.mkdir(old_root) usr_mount = os.path.join(tmp, "usr") try_mkdir(usr_mount) flags = const.MS_NODEV | const.MS_NOSUID | const.MS_NOATIME mount_bind(self.usr_path, usr_mount, flags) flags |= const.MS_REMOUNT | const.MS_RDONLY mount_bind(self.usr_path, usr_mount, flags) ignore_mounts = ["/", "/proc", "/usr"] def jail(): os.environ.clear() os.environ.update(PATH="/usr/bin", HOME="/") if self.hostname: sethostname(self.hostname) pivot_root(tmp, old_root) os.chdir("/") mount_proc() umount_all(ignore_mounts) os.rmdir("/" + put_old) os.symlink("/usr/lib", "/lib") os.symlink("/usr/lib", "/lib64") mount_tmpfs(self.fs_size, "/", const.MS_REMOUNT | const.MS_RDONLY) self.setup_workers() try: pid = clone_and_wait( jail, const.CLONE_NEWNS | const.CLONE_NEWPID | const.CLONE_NEWUTS | const.CLONE_NEWNET | const.CLONE_NEWIPC, ) finally: umount(usr_mount) umount(tmp) os.rmdir(tmp)
def run(self): ''' Set ups jail and runs prisoner ''' # Get desired gid and uid gid = None uid = None if self.gname: gid = grp.getgrnam(self.gname).gr_gid if self.uname: uid = pwd.getpwnam(self.uname).pw_uid # Create temporary mountpoint for tmpfs tmp = tempfile.mkdtemp() # Mount tmpfs for our use mount_tmpfs(self.fs_size, tmp) # Create directory for old root put_old = 'root' old_root = os.path.join(tmp, put_old) os.mkdir(old_root) # Copy stuff to tmpfs self.setup_fs(tmp) # Clone and create new namespaces. Note CLONE_NEWUSER is not used (yet?) pid = clone(const.CLONE_NEWNS | const.CLONE_NEWPID | const.CLONE_NEWUTS | const.CLONE_NEWNET | const.CLONE_NEWIPC) assert pid is not None if pid: try: while True: try: pid2, status = os.waitpid(pid, const.WALL) except KeyboardInterrupt: try: os.kill(pid, signal.SIGTERM) except OSError as exc: if exc.errno == errno.ESRCH: break raise except OSError as exc: if exc.errno == errno.ECHILD: break raise else: if pid2 == pid: break finally: self.teardown_fs(tmp) # Umount tmpfs and remove mountpoint umount(tmp) os.rmdir(tmp) #print('Child {} exited with status {}'.format(pid, status)) sys.exit(status) else: # We check if new PID namespace worked # Note we use syscall getpid instead of stdlib getpid assert getpid() == 1 # Set desired hostname if self.hostname: sethostname(self.hostname) # Move new root to tmpfs, and old to subdir pivot_root(tmp, old_root) os.chdir('/') # Which mountoints to ignore ignore_mounts = ['/', '/proc'] if self.ignore_mounts: ignore_mounts.extend(self.ignore_mounts) # Mount /proc, /cgroup and /dev mount_proc() if self.mount_cgroup: mount_cgroup() ignore_mounts.append('/cgroup') if self.mount_dev: mount_simple_dev() ignore_mounts.append('/dev') # Umount all filesystems but those we set up by ourselves umount_all(ignore_mounts) # Remove evidence of old root ;) os.rmdir('/' + put_old) os.environ.clear() # Remount tmpfs r/o if self.remount_ro: mount_tmpfs(self.fs_size, '/', const.MS_REMOUNT | const.MS_RDONLY) # Set to desired gid/uid if gid: os.setgid(gid) if uid: os.setuid(uid) # We're ready to go! status = self.prisoner() status = int(status) if status else 0 os._exit(status)
def teardown_fs(self, path): ''' If needed, unload/unmount/remove anything that was set up in setup_fs ''' umount(self.pylib_mount)
def run(self): ''' Set ups jail and runs prisoner ''' # Get desired gid and uid gid = None uid = None if self.gname: gid = grp.getgrnam(self.gname).gr_gid if self.uname: uid = pwd.getpwnam(self.uname).pw_uid # Create temporary mountpoint for tmpfs tmp = tempfile.mkdtemp() # Mount tmpfs for our use mount_tmpfs(self.fs_size, tmp) # Create directory for old root put_old = 'root' old_root = os.path.join(tmp, put_old) os.mkdir(old_root) # Copy stuff to tmpfs self.setup_fs(tmp) # Clone and create new namespaces. Note CLONE_NEWUSER is not used (yet?) pid = clone( const.CLONE_NEWNS | const.CLONE_NEWPID | const.CLONE_NEWUTS | const.CLONE_NEWNET | const.CLONE_NEWIPC ) assert pid is not None if pid: try: while True: try: pid2, status = os.waitpid(pid, const.WALL) except KeyboardInterrupt: try: os.kill(pid, signal.SIGTERM) except OSError as exc: if exc.errno == errno.ESRCH: break raise except OSError as exc: if exc.errno == errno.ECHILD: break raise else: if pid2 == pid: break finally: self.teardown_fs(tmp) # Umount tmpfs and remove mountpoint umount(tmp) os.rmdir(tmp) #print('Child {} exited with status {}'.format(pid, status)) sys.exit(status) else: # We check if new PID namespace worked # Note we use syscall getpid instead of stdlib getpid assert getpid() == 1 # Set desired hostname if self.hostname: sethostname(self.hostname) # Move new root to tmpfs, and old to subdir pivot_root(tmp, old_root) os.chdir('/') # Which mountoints to ignore ignore_mounts = ['/', '/proc'] if self.ignore_mounts: ignore_mounts.extend(self.ignore_mounts) # Mount /proc, /cgroup and /dev mount_proc() if self.mount_cgroup: mount_cgroup() ignore_mounts.append('/cgroup') if self.mount_dev: mount_simple_dev() ignore_mounts.append('/dev') # Umount all filesystems but those we set up by ourselves umount_all(ignore_mounts) # Remove evidence of old root ;) os.rmdir('/' + put_old) os.environ.clear() # Remount tmpfs r/o if self.remount_ro: mount_tmpfs(self.fs_size, '/', const.MS_REMOUNT | const.MS_RDONLY) # Set to desired gid/uid if gid: os.setgid(gid) if uid: os.setuid(uid) # We're ready to go! status = self.prisoner() status = int(status) if status else 0 os._exit(status)