Skip to content

Commit

Permalink
Merge pull request containers#872 from giuseppe/open-bind-mounts-host
Browse files Browse the repository at this point in the history
linux: open source bind mount in the host
  • Loading branch information
rhatdan authored Feb 14, 2022
2 parents 72cf1a6 + bb5bc67 commit af00681
Show file tree
Hide file tree
Showing 4 changed files with 103 additions and 23 deletions.
57 changes: 52 additions & 5 deletions src/libcrun/linux.c
Original file line number Diff line number Diff line change
Expand Up @@ -409,6 +409,27 @@ do_mount_setattr (const char *target, int targetfd, uint64_t clear, uint64_t set
return 0;
}

static int
get_bind_mount (const char *src, libcrun_error_t *err)
{
cleanup_close int open_tree_fd = -1;
struct mount_attr_s attr = {
0,
};
int ret;

open_tree_fd = syscall_open_tree (-1, src,
AT_NO_AUTOMOUNT | AT_SYMLINK_NOFOLLOW | OPEN_TREE_CLOEXEC | OPEN_TREE_CLONE);
if (UNLIKELY (open_tree_fd < 0))
return crun_make_error (err, errno, "open `%s`", src);

ret = syscall_mount_setattr (open_tree_fd, "", AT_EMPTY_PATH, &attr);
if (UNLIKELY (ret < 0))
return crun_make_error (err, errno, "mount_setattr `%s`", src);

return get_and_reset (&open_tree_fd);
}

static int
get_idmapped_mount (const char *src, pid_t pid, libcrun_error_t *err)
{
Expand Down Expand Up @@ -1627,7 +1648,15 @@ do_mounts (libcrun_container_t *container, int rootfsfd, const char *rootfs, con

if (def->mounts[i]->source && (flags & MS_BIND))
{
is_dir = crun_dir_p (def->mounts[i]->source, false, err);
char proc_buf[64];
const char *path = def->mounts[i]->source;
if (mount_fds->fds[i] >= 0)
{
sprintf (proc_buf, "/proc/self/fd/%d", mount_fds->fds[i]);
path = proc_buf;
}

is_dir = crun_dir_p (path, false, err);
if (UNLIKELY (is_dir < 0))
return is_dir;

Expand Down Expand Up @@ -3332,11 +3361,27 @@ is_idmapped (runtime_spec_schema_defs_mount *mnt)
return false;
}

static bool
is_bind_mount (runtime_spec_schema_defs_mount *mnt)
{
size_t i;

for (i = 0; i < mnt->options_len; i++)
{
if (strcmp (mnt->options[i], "bind") == 0)
return true;
if (strcmp (mnt->options[i], "rbind") == 0)
return true;
}
return false;
}

static int
prepare_and_send_mounts (libcrun_container_t *container, pid_t pid, int sync_socket_host, libcrun_error_t *err)
{
runtime_spec_schema_config_schema *def = container->container_def;
cleanup_close_map struct libcrun_fd_map *mount_fds = NULL;
bool has_userns = (get_private_data (container)->unshare_flags & CLONE_NEWUSER) ? true : false;
size_t how_many = 0;
size_t i;
int ret;
Expand All @@ -3358,6 +3403,12 @@ prepare_and_send_mounts (libcrun_container_t *container, pid_t pid, int sync_soc

mount_fds->fds[i] = fd;
}
else if (has_userns && is_bind_mount (def->mounts[i]))
{
mount_fds->fds[i] = get_bind_mount (def->mounts[i]->source, err);
if (UNLIKELY (mount_fds->fds[i] < 0))
crun_error_release (err);
}

if (mount_fds->fds[i] >= 0)
how_many++;
Expand Down Expand Up @@ -3650,10 +3701,6 @@ init_container (libcrun_container_t *container, int sync_socket_container, struc
if (UNLIKELY (ret < 0))
return ret;

/* Move ownership. */
get_private_data (container)->mount_fds = mount_fds;
mount_fds = NULL;

return 0;
}

Expand Down
2 changes: 1 addition & 1 deletion src/libcrun/utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ cleanup_pidp (void *p)
}

struct
libcrun_fd_map
libcrun_fd_map
{
size_t nfds;
int fds[];
Expand Down
64 changes: 49 additions & 15 deletions tests/test_mounts.py
Original file line number Diff line number Diff line change
Expand Up @@ -178,22 +178,56 @@ def test_mount_dev():
return -1
return 0


def test_userns_bind_mount():
if is_rootless():
return 77
conf = base_config()
add_all_namespaces(conf, userns=True)

fullMapping = [
{
"containerID": 0,
"hostID": 1,
"size": 10
}
]
conf['linux']['uidMappings'] = fullMapping
conf['linux']['gidMappings'] = fullMapping

bind_dir_parent = os.path.join(get_tests_root(), "bind-mount-userns")
bind_dir = os.path.join(bind_dir_parent, "m")
try:
os.makedirs(bind_dir)
mount_opt = {"destination": "/foo", "type": "bind", "source": bind_dir, "options": ["bind", "ro"]}
conf['mounts'].append(mount_opt)
os.chown(bind_dir_parent, 0, 0)
os.chmod(bind_dir_parent, 0o000)

conf['process']['args'] = ['/init', 'true']
run_and_get_output(conf, chown_rootfs_to=1)
finally:
shutil.rmtree(bind_dir)

return 0

all_tests = {
"test-mount-ro" : test_mount_ro,
"test-mount-rw" : test_mount_rw,
"test-mount-relatime" : test_mount_relatime,
"test-mount-strictatime" : test_mount_strictatime,
"test-mount-exec" : test_mount_exec,
"test-mount-noexec" : test_mount_noexec,
"test-mount-suid" : test_mount_suid,
"test-mount-nosuid" : test_mount_nosuid,
"test-mount-sync" : test_mount_sync,
"test-mount-dirsync" : test_mount_dirsync,
"test-mount-symlink" : test_mount_symlink,
"test-mount-symlink-not-existing" : test_mount_symlink_not_existing,
"test-mount-dev" : test_mount_dev,
"test-mount-nodev" : test_mount_nodev,
"test-mount-path-with-multiple-slashes" : test_mount_path_with_multiple_slashes,
"mount-ro" : test_mount_ro,
"mount-rw" : test_mount_rw,
"mount-relatime" : test_mount_relatime,
"mount-strictatime" : test_mount_strictatime,
"mount-exec" : test_mount_exec,
"mount-noexec" : test_mount_noexec,
"mount-suid" : test_mount_suid,
"mount-nosuid" : test_mount_nosuid,
"mount-sync" : test_mount_sync,
"mount-dirsync" : test_mount_dirsync,
"mount-symlink" : test_mount_symlink,
"mount-symlink-not-existing" : test_mount_symlink_not_existing,
"mount-dev" : test_mount_dev,
"mount-nodev" : test_mount_nodev,
"mount-path-with-multiple-slashes" : test_mount_path_with_multiple_slashes,
"mount-userns-bind-mount" : test_userns_bind_mount,
}

if __name__ == "__main__":
Expand Down
3 changes: 1 addition & 2 deletions tests/test_uid_gid.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ def test_userns_full_mapping():
if is_rootless():
return 77
conf = base_config()
add_all_namespaces(conf)
add_all_namespaces(conf, userns=True)

fullMapping = [
{
Expand All @@ -45,7 +45,6 @@ def test_userns_full_mapping():

return 0


def test_uid():
if is_rootless():
return 77
Expand Down

0 comments on commit af00681

Please sign in to comment.