diff --git a/src/libostree/ostree-bootloader-zipl.c b/src/libostree/ostree-bootloader-zipl.c index 2804ed2644..f0c18cbcfc 100644 --- a/src/libostree/ostree-bootloader-zipl.c +++ b/src/libostree/ostree-bootloader-zipl.c @@ -432,7 +432,7 @@ _ostree_bootloader_zipl_post_bls_sync (OstreeBootloader *bootloader, int bootver // This can happen in a unit testing environment; at some point what we want to do here // is move all of the zipl logic to a systemd unit instead that's keyed of // ostree-finalize-staged.service. - if (getuid () != 0) + if (!ot_util_process_privileged ()) return TRUE; // If we're in a booted deployment, we don't need to spawn a container. diff --git a/src/libostree/ostree-repo-commit.c b/src/libostree/ostree-repo-commit.c index 17b8a97f4e..18b2562c8a 100644 --- a/src/libostree/ostree-repo-commit.c +++ b/src/libostree/ostree-repo-commit.c @@ -1658,7 +1658,7 @@ ostree_repo_prepare_transaction (OstreeRepo *self, gboolean *out_transaction_res self->reserved_blocks = reserved_bytes / self->txn.blocksize; /* Use the appropriate free block count if we're unprivileged */ - guint64 bfree = (getuid () != 0 ? stvfsbuf.f_bavail : stvfsbuf.f_bfree); + guint64 bfree = (ot_util_process_privileged () ? stvfsbuf.f_bfree : stvfsbuf.f_bavail); if (bfree > self->reserved_blocks) self->txn.max_blocks = bfree - self->reserved_blocks; else diff --git a/src/libostree/ostree-sysroot.c b/src/libostree/ostree-sysroot.c index 925c66a7e3..3968c38fed 100644 --- a/src/libostree/ostree-sysroot.c +++ b/src/libostree/ostree-sysroot.c @@ -285,7 +285,7 @@ ostree_sysroot_initialize_with_mount_namespace (OstreeSysroot *self, GCancellabl return FALSE; /* Do nothing if we're not privileged */ - if (getuid () != 0) + if (!ot_util_process_privileged ()) return TRUE; /* We also assume operating on non-booted roots won't have a readonly sysroot */ diff --git a/src/libotutil/ot-unix-utils.c b/src/libotutil/ot-unix-utils.c index 33cd1c029c..bf2310de03 100644 --- a/src/libotutil/ot-unix-utils.c +++ b/src/libotutil/ot-unix-utils.c @@ -32,6 +32,9 @@ #include #include #include +#include +#include +#include #include /* Ensure that a pathname component @name does not contain the special Unix @@ -102,3 +105,17 @@ ot_util_path_split_validate (const char *path, GPtrArray **out_components, GErro ot_transfer_out_value (out_components, &ret_components); return TRUE; } + +/* Check if current process is privileged */ +gboolean +ot_util_process_privileged (void) +{ + if (geteuid() != 0) + return FALSE; + + // https://github.com/containers/bootc/blob/c88fcfd6e145863408bde7d4706937dd323f64e2/lib/src/cli.rs#L621 + if (prctl (PR_CAPBSET_READ, CAP_SYS_ADMIN) != 1) + return FALSE; + + return TRUE; +} diff --git a/src/libotutil/ot-unix-utils.h b/src/libotutil/ot-unix-utils.h index 3e4be2f9ad..38f73e4981 100644 --- a/src/libotutil/ot-unix-utils.h +++ b/src/libotutil/ot-unix-utils.h @@ -39,4 +39,6 @@ gboolean ot_util_filename_validate (const char *name, GError **error); gboolean ot_util_path_split_validate (const char *path, GPtrArray **out_components, GError **error); +gboolean ot_util_process_privileged (void); + G_END_DECLS diff --git a/src/ostree/ot-main.c b/src/ostree/ot-main.c index fa4eb53f2a..d47a59cad5 100644 --- a/src/ostree/ot-main.c +++ b/src/ostree/ot-main.c @@ -116,7 +116,7 @@ maybe_setup_mount_namespace (gboolean *out_ns, GError **error) *out_ns = FALSE; /* If we're not root, then we almost certainly can't be remounting anything */ - if (getuid () != 0) + if (!ot_util_process_privileged ()) return TRUE; /* If the system isn't booted via libostree, also nothing to do */ @@ -580,7 +580,7 @@ ostree_admin_sysroot_load (OstreeSysroot *sysroot, OstreeAdminBuiltinFlags flags /* Only require root if we're manipulating a booted sysroot. (Mostly * useful for the test suite) */ - if (booted && getuid () != 0) + if (booted && !ot_util_process_privileged ()) { g_set_error (error, G_IO_ERROR, G_IO_ERROR_PERMISSION_DENIED, "You must be root to perform this command");