Skip to content

Commit

Permalink
linux: new mount option "rro"
Browse files Browse the repository at this point in the history
if the option is present, make the mount ro recursively using the
mount_setattr syscall.

Signed-off-by: Giuseppe Scrivano <[email protected]>
  • Loading branch information
giuseppe committed Nov 11, 2021
1 parent cd8730d commit 365dc57
Show file tree
Hide file tree
Showing 3 changed files with 96 additions and 28 deletions.
8 changes: 6 additions & 2 deletions crun.1
Original file line number Diff line number Diff line change
Expand Up @@ -624,8 +624,8 @@ container using libkrun.
.SH \fB\fCrun.oci.handler=wasm\fR
.PP
If specified, run the wasm handler for container.
Allows running wasm workload natively. Accepts a \fB\fC.wasm\fR binary as input
and if \fB\fC.wat\fR is provided it will automatically compiled into a wasm module.
Allows running wasm workload natively. Accepts a \fB\fC\&.wasm\fR binary as input
and if \fB\fC\&.wat\fR is provided it will automatically compiled into a wasm module.
Stdout of wasm module is relayed back via crun.

.SH tmpcopyup mount options
Expand All @@ -634,6 +634,10 @@ If the \fB\fCtmpcopyup\fR option is specified for a tmpfs, then the path that
is shadowed by the tmpfs mount is recursively copied up to the tmpfs
itself.

.SH rro mount options
.PP
If the \fB\fCrro\fR option is specified then the mount is made recursively read-only.

.SH Automatically create user namespace
.PP
When running as user different than root, an user namespace is
Expand Down
4 changes: 4 additions & 0 deletions crun.1.md
Original file line number Diff line number Diff line change
Expand Up @@ -503,6 +503,10 @@ If the `tmpcopyup` option is specified for a tmpfs, then the path that
is shadowed by the tmpfs mount is recursively copied up to the tmpfs
itself.

## rro mount options

If the `rro` option is specified then the mount is made recursively read-only.

## Automatically create user namespace

When running as user different than root, an user namespace is
Expand Down
112 changes: 86 additions & 26 deletions src/libcrun/linux.c
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,34 @@ syscall_open_tree (int dfd, const char *pathname, unsigned int flags)
#endif
}

struct mount_attr_s
{
uint64_t attr_set;
uint64_t attr_clr;
uint64_t propagation;
uint64_t userns_fd;
};

#ifndef MOUNT_ATTR_RDONLY
# define MOUNT_ATTR_RDONLY 0x00000001 /* Mount read-only */
#endif

static int
syscall_mount_setattr (int dfd, const char *path, unsigned int flags,
struct mount_attr_s *attr)
{
#ifdef __NR_mount_setattr
return (int) syscall (__NR_mount_setattr, dfd, path, flags, attr, sizeof (*attr));
#else
(void) dfd;
(void) path;
(void) flags;
(void) attr;
errno = ENOSYS;
return -1;
#endif
}

static int
syscall_keyctl_join (const char *name)
{
Expand Down Expand Up @@ -297,6 +325,23 @@ syscall_pidfd_send_signal (int pidfd, int sig, siginfo_t *info, unsigned int fla
#endif
}

static int
make_mount_rro (const char *target, int targetfd, libcrun_error_t *err)
{
struct mount_attr_s attr = {
0,
};
int ret;

attr.attr_set = MOUNT_ATTR_RDONLY;

ret = syscall_mount_setattr (targetfd, "", AT_RECURSIVE | AT_EMPTY_PATH, &attr);
if (UNLIKELY (ret < 0))
return crun_make_error (err, errno, "mount_setattr `/%s`", target);

return 0;
}

int
libcrun_create_keyring (const char *name, const char *label, libcrun_error_t *err)
{
Expand Down Expand Up @@ -368,7 +413,8 @@ struct propagation_flags_s

enum
{
OPTION_TMPCOPYUP = 1
OPTION_TMPCOPYUP = (1 << 0),
OPTION_RRO = (1 << 1),
};

static struct propagation_flags_s propagation_flags[] = { { "defaults", 0, 0, 0 },
Expand Down Expand Up @@ -406,6 +452,7 @@ static struct propagation_flags_s propagation_flags[] = { { "defaults", 0, 0, 0
{ "runbindable", 0, MS_REC | MS_UNBINDABLE, 0 },

{ "tmpcopyup", 0, 0, OPTION_TMPCOPYUP },
{ "rro", 0, 0, OPTION_RRO },

{ NULL, 0, 0, 0 } };

Expand Down Expand Up @@ -1608,34 +1655,34 @@ do_mounts (libcrun_container_t *container, int rootfsfd, const char *rootfs, con
break;
}

if (mounted)
continue;

if (systemd_cgroup_v1 && strcmp (def->mounts[i]->destination, systemd_cgroup_v1) == 0)
{
/* Override the cgroup mount with a single named cgroup name=systemd. */
ret = do_mount_cgroup_systemd_v1 (container, source, targetfd, target, flags, err);
if (UNLIKELY (ret < 0))
return ret;
}
else if (strcmp (type, "cgroup") == 0)
{
ret = do_mount_cgroup (container, source, targetfd, target, flags, unified_cgroup_path, err);
if (UNLIKELY (ret < 0))
return ret;
}
else
if (! mounted)
{
int label_how = LABEL_MOUNT;
if (systemd_cgroup_v1 && strcmp (def->mounts[i]->destination, systemd_cgroup_v1) == 0)
{
/* Override the cgroup mount with a single named cgroup name=systemd. */
ret = do_mount_cgroup_systemd_v1 (container, source, targetfd, target, flags, err);
if (UNLIKELY (ret < 0))
return ret;
}
else if (strcmp (type, "cgroup") == 0)
{
ret = do_mount_cgroup (container, source, targetfd, target, flags, unified_cgroup_path, err);
if (UNLIKELY (ret < 0))
return ret;
}
else
{
int label_how = LABEL_MOUNT;

if (is_sysfs_or_proc)
label_how = LABEL_NONE;
else if (strcmp (type, "mqueue") == 0)
label_how = LABEL_XATTR;
if (is_sysfs_or_proc)
label_how = LABEL_NONE;
else if (strcmp (type, "mqueue") == 0)
label_how = LABEL_XATTR;

ret = do_mount (container, source, targetfd, target, type, flags, data, label_how, err);
if (UNLIKELY (ret < 0))
return ret;
ret = do_mount (container, source, targetfd, target, type, flags, data, label_how, err);
if (UNLIKELY (ret < 0))
return ret;
}
}

if (copy_from_fd >= 0)
Expand All @@ -1653,6 +1700,19 @@ do_mounts (libcrun_container_t *container, int rootfsfd, const char *rootfs, con
if (UNLIKELY (ret < 0))
return ret;
}

if (extra_flags & OPTION_RRO)
{
cleanup_close int dfd = -1;

dfd = safe_openat (rootfsfd, rootfs, rootfs_len, target, O_DIRECTORY, 0, err);
if (UNLIKELY (dfd < 0))
return crun_make_error (err, errno, "open mount target `/%s`", target);

ret = make_mount_rro (target, dfd, err);
if (UNLIKELY (ret < 0))
return ret;
}
}
return 0;
}
Expand Down

0 comments on commit 365dc57

Please sign in to comment.