73 lines
2.7 KiB
Diff
73 lines
2.7 KiB
Diff
|
From 931cb97455b01228c639ae8361e4553679b13d54 Mon Sep 17 00:00:00 2001
|
||
|
From: Panu Matilainen <pmatilai@redhat.com>
|
||
|
Date: Thu, 1 Aug 2024 13:54:25 +0300
|
||
|
Subject: [PATCH] Disable private mounts in chroot'ed operation in the unshare
|
||
|
plugin
|
||
|
|
||
|
mount(NULL, "/", NULL, MS_REC | MS_PRIVATE, NULL) inside a chroot
|
||
|
fails with EINVAL if the "/" inside the chroot is not an actual
|
||
|
mount point on the system - as it often isn't. For now, just disable
|
||
|
that functionality on chroot operation.
|
||
|
|
||
|
Related: #3187
|
||
|
---
|
||
|
docs/man/rpm-plugin-unshare.8.md | 5 +++++
|
||
|
plugins/unshare.c | 21 ++++++++++++++++-----
|
||
|
2 files changed, 21 insertions(+), 5 deletions(-)
|
||
|
|
||
|
diff --git a/docs/man/rpm-plugin-unshare.8.md b/docs/man/rpm-plugin-unshare.8.md
|
||
|
index d8a4222426..33073b872d 100644
|
||
|
--- a/docs/man/rpm-plugin-unshare.8.md
|
||
|
+++ b/docs/man/rpm-plugin-unshare.8.md
|
||
|
@@ -27,6 +27,11 @@ This plugin implements the following configurables:
|
||
|
execution. Typical examples would be `/tmp` to protect against
|
||
|
insecure temporary file usage inside scriptlets, and `/home` to
|
||
|
prevent scriptlets from accessing user home directories.
|
||
|
+ When path unsharing is enabled, any mounts made from scriptlets
|
||
|
+ are also private to the scriptlet (and vice versa, mount changes
|
||
|
+ on the host are not visible to the scriptlet).
|
||
|
+
|
||
|
+ Private mounts in chroot-operations is unimplemented.
|
||
|
|
||
|
`%__transaction_unshare_nonet`
|
||
|
|
||
|
diff --git a/plugins/unshare.c b/plugins/unshare.c
|
||
|
index bb02201e4a..50f60fad2f 100644
|
||
|
--- a/plugins/unshare.c
|
||
|
+++ b/plugins/unshare.c
|
||
|
@@ -19,8 +19,18 @@ static rpmRC unshare_init(rpmPlugin plugin, rpmts ts)
|
||
|
{
|
||
|
char *paths = rpmExpand("%{?__transaction_unshare_paths}", NULL);
|
||
|
private_mounts = argvSplitString(paths, ":", ARGV_SKIPEMPTY);
|
||
|
- if (private_mounts)
|
||
|
- unshare_flags |= CLONE_NEWNS;
|
||
|
+ if (private_mounts) {
|
||
|
+ /*
|
||
|
+ * Changing mount propagation from inside a chroot fails if the root
|
||
|
+ * is not also a mount point, disable for now.
|
||
|
+ */
|
||
|
+ if (strcmp(rpmtsRootDir(ts), "/")) {
|
||
|
+ rpmlog(RPMLOG_WARNING,
|
||
|
+ "private mounts in chroot not implemented\n");
|
||
|
+ } else {
|
||
|
+ unshare_flags |= CLONE_NEWNS;
|
||
|
+ }
|
||
|
+ }
|
||
|
free(paths);
|
||
|
|
||
|
if (rpmExpandNumeric("%{?__transaction_unshare_nonet}"))
|
||
|
@@ -47,9 +57,10 @@ static rpmRC unshare_scriptlet_fork_post(rpmPlugin plugin,
|
||
|
goto exit;
|
||
|
}
|
||
|
|
||
|
- if (private_mounts) {
|
||
|
- if (mount("/", "/", NULL, MS_REC | MS_PRIVATE, NULL) == -1) {
|
||
|
- rpmlog(RPMLOG_ERR, _("failed to mount private %s: %s\n"),
|
||
|
+ if (unshare_flags & CLONE_NEWNS) {
|
||
|
+ if (mount(NULL, "/", NULL, MS_REC | MS_PRIVATE, NULL) == -1) {
|
||
|
+ rpmlog(RPMLOG_ERR,
|
||
|
+ _("failed to change mount propagation %s: %s\n"),
|
||
|
"/", strerror(errno));
|
||
|
goto exit;
|
||
|
}
|