Exemplo n.º 1
0
    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)
Exemplo n.º 2
0
    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)
Exemplo n.º 3
0
    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)
Exemplo n.º 4
0
    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)
Exemplo n.º 5
0
 def teardown_fs(self, path):
     '''
     If needed, unload/unmount/remove anything that was set up in setup_fs
     '''
     umount(self.pylib_mount)
Exemplo n.º 6
0
    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)
Exemplo n.º 7
0
 def teardown_fs(self, path):
     '''
     If needed, unload/unmount/remove anything that was set up in setup_fs
     '''
     umount(self.pylib_mount)