diff options
author | Colin Walters <walters@verbum.org> | 2022-11-21 15:16:04 -0500 |
---|---|---|
committer | Colin Walters <walters@verbum.org> | 2022-11-22 08:45:13 -0500 |
commit | 599ffefe7f069712d54f63f67e4a6f92570c554e (patch) | |
tree | 7d3a79a87ede87708d79172502a26e5c8db0061f /src/libostree | |
parent | 9d652be3b18d5899d3aa36868551dc5af5ceef2e (diff) | |
download | ostree-599ffefe7f069712d54f63f67e4a6f92570c554e.tar.gz |
sysroot: Add an API to initialize with mountns
This lowers down into the C library some logic we
have in the binary/app logic, in prep for having more Rust-native
CLI code in https://github.com/ostreedev/ostree-rs-ext/pull/412
Basically we want to *ensure* a mount namespace by invoking
`unshare()` if necessary, instead of requiring our callers
to do this dance.
This also helps fix e.g.
Closes: https://github.com/ostreedev/ostree/issues/2769
Diffstat (limited to 'src/libostree')
-rw-r--r-- | src/libostree/libostree-devel.sym | 1 | ||||
-rw-r--r-- | src/libostree/ostree-sysroot.c | 57 | ||||
-rw-r--r-- | src/libostree/ostree-sysroot.h | 3 |
3 files changed, 61 insertions, 0 deletions
diff --git a/src/libostree/libostree-devel.sym b/src/libostree/libostree-devel.sym index 6a82433a..8f374bbe 100644 --- a/src/libostree/libostree-devel.sym +++ b/src/libostree/libostree-devel.sym @@ -24,6 +24,7 @@ LIBOSTREE_2022.7 { global: ostree_kernel_args_contains; ostree_kernel_args_delete_if_present; + ostree_sysroot_initialize_with_mount_namespace; } LIBOSTREE_2022.5; /* Stub section for the stable release *after* this development one; don't diff --git a/src/libostree/ostree-sysroot.c b/src/libostree/ostree-sysroot.c index b15265f5..4c63a657 100644 --- a/src/libostree/ostree-sysroot.c +++ b/src/libostree/ostree-sysroot.c @@ -260,6 +260,63 @@ ostree_sysroot_set_mount_namespace_in_use (OstreeSysroot *self) } /** + * ostree_sysroot_initialize_with_mount_namespace: + * + * Prepare the current process for modifying a booted sysroot, if applicable. + * This function subsumes the functionality of `ostree_sysroot_initialize` + * and may be invoked wherever that function is. + * + * If the sysroot does not appear to be booted, or where the current process is not uid 0, + * this function returns successfully. + * + * Otherwise, if the process is in the same mount namespace as pid 1, create + * a new namespace. + * + * If you invoke this function, it must be before ostree_sysroot_load(); it may + * be invoked before or after ostree_sysroot_initialize(). + * + * Since: 2022.7 + */ +gboolean +ostree_sysroot_initialize_with_mount_namespace (OstreeSysroot *self, GCancellable *cancellable, GError **error) +{ + GLNX_AUTO_PREFIX_ERROR ("Initializing with mountns", error); + /* Must be before we're loaded, as otherwise we'd have to close/reopen all our + fds, e.g. the repo */ + g_assert (self->loadstate < OSTREE_SYSROOT_LOAD_STATE_LOADED); + + if (!ostree_sysroot_initialize (self, error)) + return FALSE; + + /* Do nothing if we're not privileged */ + if (getuid () != 0) + return TRUE; + + /* We also assume operating on non-booted roots won't have a readonly sysroot */ + if (!self->root_is_ostree_booted) + return TRUE; + + g_autofree char *mntns_pid1 = + glnx_readlinkat_malloc (AT_FDCWD, "/proc/1/ns/mnt", cancellable, error); + if (!mntns_pid1) + return glnx_prefix_error (error, "Reading /proc/1/ns/mnt"); + g_autofree char *mntns_self = + glnx_readlinkat_malloc (AT_FDCWD, "/proc/self/ns/mnt", cancellable, error); + if (!mntns_self) + return glnx_prefix_error (error, "Reading /proc/self/ns/mnt"); + + // If the mount namespaces are the same, we need to unshare(). + if (strcmp (mntns_pid1, mntns_self) == 0) + { + if (unshare (CLONE_NEWNS) < 0) + return glnx_throw_errno_prefix (error, "Failed to invoke unshare(CLONE_NEWNS)"); + } + + ostree_sysroot_set_mount_namespace_in_use (self); + return TRUE; +} + +/** * ostree_sysroot_get_path: * @self: Sysroot * diff --git a/src/libostree/ostree-sysroot.h b/src/libostree/ostree-sysroot.h index 0cde9e44..23c7139a 100644 --- a/src/libostree/ostree-sysroot.h +++ b/src/libostree/ostree-sysroot.h @@ -51,6 +51,9 @@ _OSTREE_PUBLIC void ostree_sysroot_set_mount_namespace_in_use (OstreeSysroot *self); _OSTREE_PUBLIC +gboolean ostree_sysroot_initialize_with_mount_namespace (OstreeSysroot *self, GCancellable *cancellable, GError **error); + +_OSTREE_PUBLIC GFile *ostree_sysroot_get_path (OstreeSysroot *self); _OSTREE_PUBLIC |