Skip to content

Commit 365dc57

Browse files
committed
linux: new mount option "rro"
if the option is present, make the mount ro recursively using the mount_setattr syscall. Signed-off-by: Giuseppe Scrivano <[email protected]>
1 parent cd8730d commit 365dc57

3 files changed

Lines changed: 96 additions & 28 deletions

File tree

crun.1

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -624,8 +624,8 @@ container using libkrun.
624624
.SH \fB\fCrun.oci.handler=wasm\fR
625625
.PP
626626
If specified, run the wasm handler for container.
627-
Allows running wasm workload natively. Accepts a \fB\fC.wasm\fR binary as input
628-
and if \fB\fC.wat\fR is provided it will automatically compiled into a wasm module.
627+
Allows running wasm workload natively. Accepts a \fB\fC\&.wasm\fR binary as input
628+
and if \fB\fC\&.wat\fR is provided it will automatically compiled into a wasm module.
629629
Stdout of wasm module is relayed back via crun.
630630

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

637+
.SH rro mount options
638+
.PP
639+
If the \fB\fCrro\fR option is specified then the mount is made recursively read-only.
640+
637641
.SH Automatically create user namespace
638642
.PP
639643
When running as user different than root, an user namespace is

crun.1.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -503,6 +503,10 @@ If the `tmpcopyup` option is specified for a tmpfs, then the path that
503503
is shadowed by the tmpfs mount is recursively copied up to the tmpfs
504504
itself.
505505

506+
## rro mount options
507+
508+
If the `rro` option is specified then the mount is made recursively read-only.
509+
506510
## Automatically create user namespace
507511

508512
When running as user different than root, an user namespace is

src/libcrun/linux.c

Lines changed: 86 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -262,6 +262,34 @@ syscall_open_tree (int dfd, const char *pathname, unsigned int flags)
262262
#endif
263263
}
264264

265+
struct mount_attr_s
266+
{
267+
uint64_t attr_set;
268+
uint64_t attr_clr;
269+
uint64_t propagation;
270+
uint64_t userns_fd;
271+
};
272+
273+
#ifndef MOUNT_ATTR_RDONLY
274+
# define MOUNT_ATTR_RDONLY 0x00000001 /* Mount read-only */
275+
#endif
276+
277+
static int
278+
syscall_mount_setattr (int dfd, const char *path, unsigned int flags,
279+
struct mount_attr_s *attr)
280+
{
281+
#ifdef __NR_mount_setattr
282+
return (int) syscall (__NR_mount_setattr, dfd, path, flags, attr, sizeof (*attr));
283+
#else
284+
(void) dfd;
285+
(void) path;
286+
(void) flags;
287+
(void) attr;
288+
errno = ENOSYS;
289+
return -1;
290+
#endif
291+
}
292+
265293
static int
266294
syscall_keyctl_join (const char *name)
267295
{
@@ -297,6 +325,23 @@ syscall_pidfd_send_signal (int pidfd, int sig, siginfo_t *info, unsigned int fla
297325
#endif
298326
}
299327

328+
static int
329+
make_mount_rro (const char *target, int targetfd, libcrun_error_t *err)
330+
{
331+
struct mount_attr_s attr = {
332+
0,
333+
};
334+
int ret;
335+
336+
attr.attr_set = MOUNT_ATTR_RDONLY;
337+
338+
ret = syscall_mount_setattr (targetfd, "", AT_RECURSIVE | AT_EMPTY_PATH, &attr);
339+
if (UNLIKELY (ret < 0))
340+
return crun_make_error (err, errno, "mount_setattr `/%s`", target);
341+
342+
return 0;
343+
}
344+
300345
int
301346
libcrun_create_keyring (const char *name, const char *label, libcrun_error_t *err)
302347
{
@@ -368,7 +413,8 @@ struct propagation_flags_s
368413

369414
enum
370415
{
371-
OPTION_TMPCOPYUP = 1
416+
OPTION_TMPCOPYUP = (1 << 0),
417+
OPTION_RRO = (1 << 1),
372418
};
373419

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

408454
{ "tmpcopyup", 0, 0, OPTION_TMPCOPYUP },
455+
{ "rro", 0, 0, OPTION_RRO },
409456

410457
{ NULL, 0, 0, 0 } };
411458

@@ -1608,34 +1655,34 @@ do_mounts (libcrun_container_t *container, int rootfsfd, const char *rootfs, con
16081655
break;
16091656
}
16101657

1611-
if (mounted)
1612-
continue;
1613-
1614-
if (systemd_cgroup_v1 && strcmp (def->mounts[i]->destination, systemd_cgroup_v1) == 0)
1615-
{
1616-
/* Override the cgroup mount with a single named cgroup name=systemd. */
1617-
ret = do_mount_cgroup_systemd_v1 (container, source, targetfd, target, flags, err);
1618-
if (UNLIKELY (ret < 0))
1619-
return ret;
1620-
}
1621-
else if (strcmp (type, "cgroup") == 0)
1622-
{
1623-
ret = do_mount_cgroup (container, source, targetfd, target, flags, unified_cgroup_path, err);
1624-
if (UNLIKELY (ret < 0))
1625-
return ret;
1626-
}
1627-
else
1658+
if (! mounted)
16281659
{
1629-
int label_how = LABEL_MOUNT;
1660+
if (systemd_cgroup_v1 && strcmp (def->mounts[i]->destination, systemd_cgroup_v1) == 0)
1661+
{
1662+
/* Override the cgroup mount with a single named cgroup name=systemd. */
1663+
ret = do_mount_cgroup_systemd_v1 (container, source, targetfd, target, flags, err);
1664+
if (UNLIKELY (ret < 0))
1665+
return ret;
1666+
}
1667+
else if (strcmp (type, "cgroup") == 0)
1668+
{
1669+
ret = do_mount_cgroup (container, source, targetfd, target, flags, unified_cgroup_path, err);
1670+
if (UNLIKELY (ret < 0))
1671+
return ret;
1672+
}
1673+
else
1674+
{
1675+
int label_how = LABEL_MOUNT;
16301676

1631-
if (is_sysfs_or_proc)
1632-
label_how = LABEL_NONE;
1633-
else if (strcmp (type, "mqueue") == 0)
1634-
label_how = LABEL_XATTR;
1677+
if (is_sysfs_or_proc)
1678+
label_how = LABEL_NONE;
1679+
else if (strcmp (type, "mqueue") == 0)
1680+
label_how = LABEL_XATTR;
16351681

1636-
ret = do_mount (container, source, targetfd, target, type, flags, data, label_how, err);
1637-
if (UNLIKELY (ret < 0))
1638-
return ret;
1682+
ret = do_mount (container, source, targetfd, target, type, flags, data, label_how, err);
1683+
if (UNLIKELY (ret < 0))
1684+
return ret;
1685+
}
16391686
}
16401687

16411688
if (copy_from_fd >= 0)
@@ -1653,6 +1700,19 @@ do_mounts (libcrun_container_t *container, int rootfsfd, const char *rootfs, con
16531700
if (UNLIKELY (ret < 0))
16541701
return ret;
16551702
}
1703+
1704+
if (extra_flags & OPTION_RRO)
1705+
{
1706+
cleanup_close int dfd = -1;
1707+
1708+
dfd = safe_openat (rootfsfd, rootfs, rootfs_len, target, O_DIRECTORY, 0, err);
1709+
if (UNLIKELY (dfd < 0))
1710+
return crun_make_error (err, errno, "open mount target `/%s`", target);
1711+
1712+
ret = make_mount_rro (target, dfd, err);
1713+
if (UNLIKELY (ret < 0))
1714+
return ret;
1715+
}
16561716
}
16571717
return 0;
16581718
}

0 commit comments

Comments
 (0)