Ejemplo n.º 1
0
def contain(command, image_name, image_dir, container_id, container_dir):
    linux.unshare(linux.CLONE_NEWNS)  # create a new mount namespace

    linux.mount(None, '/', None, linux.MS_PRIVATE | linux.MS_REC, None)  # TODO: we added MS_REC here. wanna guess why?

    new_root = create_container_root(image_name, image_dir, container_id, container_dir)
    print('Created a new root fs for our container: {}'.format(new_root))

    # Create mounts (/proc, /sys, /dev) under new_root
    linux.mount('proc', os.path.join(new_root, 'proc'), 'proc', 0, '')
    linux.mount('sysfs', os.path.join(new_root, 'sys'), 'sysfs', 0, '')
    linux.mount('tmpfs', os.path.join(new_root, 'dev'), 'tmpfs',
                linux.MS_NOSUID | linux.MS_STRICTATIME, 'mode=755')

    # Add some basic devices
    devpts_path = os.path.join(new_root, 'dev', 'pts')
    if not os.path.exists(devpts_path):
        os.makedirs(devpts_path)
        linux.mount('devpts', devpts_path, 'devpts', 0, '')

    makedev(os.path.join(new_root, 'dev'))

    os.chroot(new_root)  # TODO: replace with pivot_root

    os.chdir('/')

    # TODO: umount2 old root (HINT: see MNT_DETACH in man mount)

    os.execvp(command[0], command)
Ejemplo n.º 2
0
def contain(command, image_name, image_dir, container_id, container_dir):
    linux.unshare(linux.CLONE_NEWNS)  # create a new mount namespace

    linux.mount(None, '/', None, linux.MS_PRIVATE | linux.MS_REC,
                None)  # TODO: we added MS_REC here. wanna guess why?

    new_root = create_container_root(image_name, image_dir, container_id,
                                     container_dir)
    print('Created a new root fs for our container: {}'.format(new_root))

    # Create mounts (/proc, /sys, /dev) under new_root
    linux.mount('proc', os.path.join(new_root, 'proc'), 'proc', 0, '')
    linux.mount('sysfs', os.path.join(new_root, 'sys'), 'sysfs', 0, '')
    linux.mount('tmpfs', os.path.join(new_root, 'dev'), 'tmpfs',
                linux.MS_NOSUID | linux.MS_STRICTATIME, 'mode=755')

    # Add some basic devices
    devpts_path = os.path.join(new_root, 'dev', 'pts')
    if not os.path.exists(devpts_path):
        os.makedirs(devpts_path)
        linux.mount('devpts', devpts_path, 'devpts', 0, '')

    makedev(os.path.join(new_root, 'dev'))

    os.chroot(new_root)  # TODO: replace with pivot_root

    os.chdir('/')

    # TODO: umount2 old root (HINT: see MNT_DETACH in man mount)

    os.execvp(command[0], command)
Ejemplo n.º 3
0
def contain(command, image_name, image_dir, container_id, container_dir):
    linux.unshare(linux.CLONE_NEWNS)  # create a new mount namespace
    # TODO: switch to a new UTS namespace, change hostname to container_id
    # HINT: use linux.sethostname()
    linux.unshare(linux.CLONE_NEWUTS)
    linux.sethostname(container_id)

    linux.mount(None, '/', None, linux.MS_PRIVATE | linux.MS_REC, None)

    new_root = create_container_root(image_name, image_dir, container_id,
                                     container_dir)
    print('Created a new root fs for our container: {}'.format(new_root))

    _create_mounts(new_root)

    old_root = os.path.join(new_root, 'old_root')
    os.makedirs(old_root)
    linux.pivot_root(new_root, old_root)

    os.chdir('/')

    linux.umount2('/old_root', linux.MNT_DETACH)  # umount old root
    os.rmdir('/old_root')  # rmdir the old_root dir

    os.execvp(command[0], command)
Ejemplo n.º 4
0
def test_unshare_net():
    import os
    from pyLinux import linux

    pid = os.fork()

    if pid == 0:
        linux.unshare(linux.CLONE_NEWNET)
Ejemplo n.º 5
0
def contain(command, image_name, image_dir, container_id, container_dir):
    try:
        linux.unshare(linux.CLONE_NEWNS)  # create a new mount namespace
    except RuntimeError as e:
        if getattr(e, 'args', '') == (1, 'Operation not permitted'):
            print('Error: Use of CLONE_NEWNS with unshare(2) requires the '
                  'CAP_SYS_ADMIN capability (i.e. you probably want to retry '
                  'this with sudo)')
        raise e

    # TODO: we added MS_REC here. wanna guess why?
    linux.mount(None, '/', None, linux.MS_PRIVATE | linux.MS_REC, None)

    new_root = create_container_root(image_name, image_dir, container_id,
                                     container_dir)
    print('Created a new root fs for our container: {}'.format(new_root))

    def _create_mounts(
            new_root):  # Create mounts (/proc, /sys, /dev) under new_root
        linux.mount('proc', os.path.join(new_root, 'proc'), 'proc', 0, '')
        linux.mount('sysfs', os.path.join(new_root, 'sys'), 'sysfs', 0, '')
        linux.mount('tmpfs', os.path.join(new_root, 'dev'), 'tmpfs',
                    linux.MS_NOSUID | linux.MS_STRICTATIME, 'mode=755')

    # Add some basic devices
    devpts_path = os.path.join(new_root, 'dev', 'pts')
    if not os.path.exists(devpts_path):
        os.makedirs(devpts_path)
        linux.mount('devpts', devpts_path, 'devpts', 0, '')

    makedev(os.path.join(new_root, 'dev'))

    _create_mounts(new_root)
    old_root = os.path.join(new_root, 'old_root')
    os.mkdirs(new_root)
    os.pivot_root(new_root, 'old_root')  # TODO: replace with pivot_root

    os.chdir('/')

    linux.umount2("/old_root", linux.MNT_DETACH)
    linux.rm("/old_root")
    # TODO: umount2 old root (HINT: see MNT_DETACH in man 2 umount)

    os.execvp(command[0], command)
Ejemplo n.º 6
0
def contain(command, image_name, image_dir, container_id, container_dir):
    linux.unshare(linux.CLONE_NEWNS)  # create a new mount namespace

    linux.mount(None, '/', None, linux.MS_PRIVATE | linux.MS_REC, None)

    new_root = create_container_root(image_name, image_dir, container_id, container_dir)
    print('Created a new root fs for our container: {}'.format(new_root))

    _create_mounts(new_root)

    old_root = os.path.join(new_root, 'old_root')
    os.makedirs(old_root)
    linux.pivot_root(new_root, old_root)

    os.chdir('/')

    linux.umount2('/old_root', linux.MNT_DETACH)  # umount old root

    os.execvp(command[0], command)
Ejemplo n.º 7
0
def contain(command, image_name, image_dir, container_id, container_dir):
    linux.unshare(linux.CLONE_NEWNS)  # create a new mount namespace

    linux.mount(None, '/', None, linux.MS_PRIVATE | linux.MS_REC, None)

    new_root = create_container_root(image_name, image_dir, container_id,
                                     container_dir)
    print('Created a new root fs for our container: {}'.format(new_root))

    _create_mounts(new_root)

    old_root = os.path.join(new_root, 'old_root')
    os.makedirs(old_root)
    linux.pivot_root(new_root, old_root)

    os.chdir('/')

    linux.umount2('/old_root', linux.MNT_DETACH)  # umount old root

    os.execvp(command[0], command)
Ejemplo n.º 8
0
def contain(command, image_name, image_dir, container_id, container_dir):
    linux.unshare(linux.CLONE_NEWNS)  # create a new mount namespace
    # TODO: switch to a new UTS namespace, change hostname to container_id
    # HINT: use linux.sethostname()

    linux.mount(None, "/", None, linux.MS_PRIVATE | linux.MS_REC, None)

    new_root = create_container_root(image_name, image_dir, container_id, container_dir)
    print("Created a new root fs for our container: {}".format(new_root))

    _create_mounts(new_root)

    old_root = os.path.join(new_root, "old_root")
    os.makedirs(old_root)
    linux.pivot_root(new_root, old_root)

    os.chdir("/")

    linux.umount2("/old_root", linux.MNT_DETACH)  # umount old root
    os.rmdir("/old_root")  # rmdir the old_root dir

    os.execvp(command[0], command)
Ejemplo n.º 9
0
def test_unshare_mount(tmpdir):
    import os
    from pyLinux import linux

    def path_in_mounts(path):
        with open('/proc/mounts', 'r') as f:
            for line in f:
                line = line.strip()
                if path in line:
                    return True
        return False

    path = os.path.join(str(tmpdir), 'meshde')
    os.makedirs(path)

    r, w = os.pipe()

    pid = os.fork()

    if pid == 0:
        os.close(r)
        w = os.fdopen(w, 'w')

        linux.unshare(linux.CLONE_NEWNS)
        linux.mount(None, '/', None, linux.MS_PRIVATE | linux.MS_REC, None)
        linux.mount('tmpfs', path, 'tmpfs')
        assert path_in_mounts(path)

        w.write('I\'m done')
        w.close()

    else:
        os.close(w)
        r = os.fdopen(r)
        msg = r.read()
        print('Child sent:', msg)
        assert not path_in_mounts(path)

    return
Ejemplo n.º 10
0
def run(image_name, image_dir, container_dir, command):
    container_id = str(uuid.uuid4())

    # TODO: Switching to a new PID namespace (using unshare) would only affect
    #       the children of a process (because we can't change the PID of a
    #       running process), so we'll have to unshare here OR replace
    #       os.fork() with linux.clone()
    linux.unshare(linux.CLONE_NEWPID)
    pid = os.fork()
    if pid == 0:
        # This is the child, we'll try to do some containment here
        try:
            contain(command, image_name, image_dir, container_id,
                    container_dir)
        except Exception:
            traceback.print_exc()
            os._exit(1)  # something went wrong in contain()

    # This is the parent, pid contains the PID of the forked process
    # wait for the forked child, fetch the exit status
    _, status = os.waitpid(pid, 0)
    print('{} exited with status {}'.format(pid, status))
Ejemplo n.º 11
0
def contain(command, image_name, image_dir, container_id, container_dir):
    new_root = create_container_root(image_name, image_dir, container_id,
                                     container_dir)
    print('Created a new root fs for our container: {}'.format(new_root))

    # TODO: time to say goodbye to the old mount namespace,
    #       see "man 2 unshare" to get some help
    #   HINT 1: there is no os.unshare(), time to use the linux module we made
    #           just for you!
    #   HINT 2: the linux module includes both functions and constants!
    #           e.g. linux.CLONE_NEWNS
    linux.unshare(linux.CLONE_NEWNS)

    # TODO: remember shared subtrees?
    # (https://www.kernel.org/doc/Documentation/filesystems/sharedsubtree.txt)
    # Make / a private mount to avoid littering our host mount table.
    linux.mount('/', os.path.join(new_root, '/'), 'proc', linux.MS_PRIVATE, '')

    # Create mounts (/proc, /sys, /dev) under new_root
    linux.mount('proc', os.path.join(new_root, 'proc'), 'proc', 0, '')
    linux.mount('sysfs', os.path.join(new_root, 'sys'), 'sysfs', 0, '')
    linux.mount('tmpfs', os.path.join(new_root, 'dev'), 'tmpfs',
                linux.MS_NOSUID | linux.MS_STRICTATIME, 'mode=755')
    # Add some basic devices
    devpts_path = os.path.join(new_root, 'dev', 'pts')
    if not os.path.exists(devpts_path):
        os.makedirs(devpts_path)
        linux.mount('devpts', devpts_path, 'devpts', 0, '')
    for i, dev in enumerate(['stdin', 'stdout', 'stderr']):
        os.symlink('/proc/self/fd/%d' % i, os.path.join(new_root, 'dev', dev))

    # TODO: add more devices (e.g. null, zero, random, urandom) using os.mknod.

    os.chroot(new_root)

    os.chdir('/')

    os.execvp(command[0], command)
Ejemplo n.º 12
0
def contain(cmd, cid):
    _set_cgroup_cpu(cid)
    _set_cgroup_memory(cid)

    linux.unshare(linux.CLONE_NEWNS)  # create a new mount namespace
    linux.unshare(linux.CLONE_NEWUTS)  # create a new uts namespace
    linux.unshare(linux.CLONE_NEWNET)  # create a new n/w namespace

    linux.sethostname(cid)

    # Use linux.clone in run() before fork and uncomment the above lines

    linux.mount(None, '/', None, linux.MS_REC | linux.MS_PRIVATE, None)

    new_root = create_container_root()

    print("New Root created.")

    # When using an already extracted image
    # linux.umount(os.path.join(new_root, 'proc'))
    # linux.umount(os.path.join(new_root, 'sys'))

    linux.mount('proc', os.path.join(new_root, 'proc'), 'proc', 0, '')
    linux.mount('sysfs', os.path.join(new_root, 'sys'), 'sysfs', 0, '')
    linux.mount('tmpfs', os.path.join(new_root, 'dev'), 'tmpfs',
                linux.MS_STRICTATIME | linux.MS_NOSUID, 'mode=755')

    # Add Basic Devices
    devs = os.path.join(new_root, 'dev', 'pts')
    if os.path.exists:
        pass
    else:
        os.makedirs(devs)
        linux.mount('devpts', devs, 'devpts', 0, '')

    _makedev(os.path.join(new_root, 'dev'))

    os.chroot(new_root)
    os.chdir("/")

    os.execvp(cmd[0], cmd)
Ejemplo n.º 13
0
def contain(command, image_name, image_dir, container_id, container_dir):
    linux.unshare(linux.CLONE_NEWNS)  # create a new mount namespace
Ejemplo n.º 14
0
    pass


def contain(command, image_name, image_dir, container_id, container_dir):
    new_root = create_container_root(
        image_name, image_dir, container_id, container_dir)
    print('Created a new root fs for our container: {}'.format(new_root))

    # TODO: time to say goodbye to the old mount namespace,
    #       see "man 2 unshare" to get some help
    #   HINT 1: there is no os.unshare(), time to use the linux module we made
    #           just for you!
    #   HINT 2: the linux module includes both functions and constants!
    #           e.g. linux.CLONE_NEWNS
   try:
       linux.unshare(linux.CLONE_NEWNS)  # create a new mount namespace
   except RuntimeError as e:
       if getattr(e, 'args', '') == (1, 'Operation not permitted'):
            print('Error: Use of CLONE_NEWNS with unshare(2) requires the '
                  'CAP_SYS_ADMIN capability (i.e. you probably want to retry '
                  'this with sudo)')
        raise e
    linux.mount(None, "/", None, linux.MS_REC | linux.MS_PRIVATE)
    # TODO: remember shared subtrees?
    # (https://www.kernel.org/doc/Documentation/filesystems/sharedsubtree.txt)
    # Make / a private mount to avoid littering our host mount table.

    # Create mounts (/proc, /sys, /dev) under new_root
    linux.mount('proc', os.path.join(new_root, 'proc'), 'proc', 0, '')
    linux.mount('sysfs', os.path.join(new_root, 'sys'), 'sysfs', 0, '')
    linux.mount('tmpfs', os.path.join(new_root, 'dev'), 'tmpfs',