From 1bd9aa64617d986763a09fc1d2e5e9575258f5a3 Mon Sep 17 00:00:00 2001 From: Misaki Kasumi Date: Wed, 18 Dec 2024 23:48:41 +0800 Subject: [PATCH 1/2] chore: Use geteuid() instead of getuid() to check privilege --- src/libostree/ostree-bootloader-zipl.c | 2 +- src/libostree/ostree-repo-commit.c | 2 +- src/libostree/ostree-sysroot.c | 2 +- src/libotutil/ot-unix-utils.c | 7 +++++++ src/libotutil/ot-unix-utils.h | 2 ++ src/ostree/ot-main.c | 4 ++-- 6 files changed, 14 insertions(+), 5 deletions(-) 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..7a3192fe54 100644 --- a/src/libotutil/ot-unix-utils.c +++ b/src/libotutil/ot-unix-utils.c @@ -102,3 +102,10 @@ 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) +{ + return geteuid() == 0; +} 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"); From f9bf9ac5606961e5386a0eabe6b156a8a18d83ee Mon Sep 17 00:00:00 2001 From: Misaki Kasumi Date: Fri, 20 Dec 2024 20:35:08 +0800 Subject: [PATCH 2/2] chore: Check CAP_SYS_ADMIN in ot_util_process_privileged --- src/libotutil/ot-unix-utils.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/libotutil/ot-unix-utils.c b/src/libotutil/ot-unix-utils.c index 7a3192fe54..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 @@ -107,5 +110,12 @@ ot_util_path_split_validate (const char *path, GPtrArray **out_components, GErro gboolean ot_util_process_privileged (void) { - return geteuid() == 0; + 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; }