From: Daan De Meyer Date: Sun, 26 Mar 2023 16:20:41 +0000 (+0200) Subject: label: Introduce LabelOps to do pre/post labelling operations X-Git-Tag: v254-rc1~331^2~1 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=a452c807a447121ce4ba100863cdc4fb81cde047;p=thirdparty%2Fsystemd.git label: Introduce LabelOps to do pre/post labelling operations By default, label_ops is initialized with a NULL pointer which translates to noop labelling operations. In mac_selinux_init() and the new mac_smack_init(), we initialize label_ops with a MAC specific LabelOps pointer. We also introduce mac_init() to initialize any configured MACs and replace all usages of mac_selinux_init() with mac_init(). --- diff --git a/src/basic/label.c b/src/basic/label.c new file mode 100644 index 00000000000..f134e775896 --- /dev/null +++ b/src/basic/label.c @@ -0,0 +1,30 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ + +#include +#include + +#include "label.h" + +static const LabelOps *label_ops = NULL; + +int label_ops_set(const LabelOps *ops) { + if (label_ops) + return -EBUSY; + + label_ops = ops; + return 0; +} + +int label_ops_pre(int dir_fd, const char *path, mode_t mode) { + if (!label_ops || !label_ops->pre) + return 0; + + return label_ops->pre(dir_fd, path, mode); +} + +int label_ops_post(int dir_fd, const char *path) { + if (!label_ops || !label_ops->post) + return 0; + + return label_ops->post(dir_fd, path); +} diff --git a/src/basic/label.h b/src/basic/label.h new file mode 100644 index 00000000000..9644e435a36 --- /dev/null +++ b/src/basic/label.h @@ -0,0 +1,14 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +#pragma once + +#include + +typedef struct LabelOps { + int (*pre)(int dir_fd, const char *path, mode_t mode); + int (*post)(int dir_fd, const char *path); +} LabelOps; + +int label_ops_set(const LabelOps *label_ops); + +int label_ops_pre(int dir_fd, const char *path, mode_t mode); +int label_ops_post(int dir_fd, const char *path); diff --git a/src/basic/meson.build b/src/basic/meson.build index ee943371401..9358a400014 100644 --- a/src/basic/meson.build +++ b/src/basic/meson.build @@ -44,6 +44,7 @@ basic_sources = files( 'inotify-util.c', 'io-util.c', 'ioprio-util.c', + 'label.c', 'limits-util.c', 'locale-util.c', 'lock-util.c', diff --git a/src/core/main.c b/src/core/main.c index 08d416bc149..c69f9b9afee 100644 --- a/src/core/main.c +++ b/src/core/main.c @@ -2849,8 +2849,8 @@ int main(int argc, char *argv[]) { goto finish; } - if (mac_selinux_init() < 0) { - error_message = "Failed to initialize SELinux support"; + if (mac_init() < 0) { + error_message = "Failed to initialize MAC support"; goto finish; } @@ -2922,8 +2922,8 @@ int main(int argc, char *argv[]) { * operate. */ capability_ambient_set_apply(0, /* also_inherit= */ false); - if (mac_selinux_init() < 0) { - error_message = "Failed to initialize SELinux support"; + if (mac_init() < 0) { + error_message = "Failed to initialize MAC support"; goto finish; } } diff --git a/src/hostname/hostnamed.c b/src/hostname/hostnamed.c index 36ab0148b9b..97b1c61748a 100644 --- a/src/hostname/hostnamed.c +++ b/src/hostname/hostnamed.c @@ -1524,7 +1524,7 @@ static int run(int argc, char *argv[]) { umask(0022); - r = mac_selinux_init(); + r = mac_init(); if (r < 0) return r; diff --git a/src/hwdb/hwdb.c b/src/hwdb/hwdb.c index edc5dfc1f5f..4287b1f0660 100644 --- a/src/hwdb/hwdb.c +++ b/src/hwdb/hwdb.c @@ -124,7 +124,7 @@ static int run(int argc, char *argv[]) { if (r <= 0) return r; - r = mac_selinux_init(); + r = mac_init(); if (r < 0) return r; diff --git a/src/locale/localed.c b/src/locale/localed.c index 63ff69d7d3f..9e5b7b03c03 100644 --- a/src/locale/localed.c +++ b/src/locale/localed.c @@ -657,7 +657,7 @@ static int run(int argc, char *argv[]) { umask(0022); - r = mac_selinux_init(); + r = mac_init(); if (r < 0) return r; diff --git a/src/login/logind.c b/src/login/logind.c index cfb3ef500c6..8323bcc0cb2 100644 --- a/src/login/logind.c +++ b/src/login/logind.c @@ -1194,7 +1194,7 @@ static int run(int argc, char *argv[]) { umask(0022); - r = mac_selinux_init(); + r = mac_init(); if (r < 0) return r; diff --git a/src/login/user-runtime-dir.c b/src/login/user-runtime-dir.c index 7513f657568..ed8a80e6ed5 100644 --- a/src/login/user-runtime-dir.c +++ b/src/login/user-runtime-dir.c @@ -202,7 +202,7 @@ static int run(int argc, char *argv[]) { umask(0022); - r = mac_selinux_init(); + r = mac_init(); if (r < 0) return r; diff --git a/src/machine/machinectl.c b/src/machine/machinectl.c index 197d0cfa1c2..8d7d464a4a2 100644 --- a/src/machine/machinectl.c +++ b/src/machine/machinectl.c @@ -1462,7 +1462,7 @@ static int edit_settings(int argc, char *argv[], void *userdata) { return log_error_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "Edit is only supported on the host machine."); - r = mac_selinux_init(); + r = mac_init(); if (r < 0) return r; diff --git a/src/resolve/resolved.c b/src/resolve/resolved.c index f9d3281509d..1625c5189d0 100644 --- a/src/resolve/resolved.c +++ b/src/resolve/resolved.c @@ -38,7 +38,7 @@ static int run(int argc, char *argv[]) { umask(0022); - r = mac_selinux_init(); + r = mac_init(); if (r < 0) return r; diff --git a/src/shared/label-util.c b/src/shared/label-util.c index c0639e3a888..3316c9ed37b 100644 --- a/src/shared/label-util.c +++ b/src/shared/label-util.c @@ -6,6 +6,7 @@ #include "btrfs-util.h" #include "fs-util.h" +#include "label.h" #include "label-util.h" #include "macro.h" #include "selinux-util.h" @@ -115,3 +116,15 @@ int btrfs_subvol_make_label(const char *path) { return mac_smack_fix(path, 0); } + +int mac_init(void) { + int r; + + assert(!(mac_selinux_use() && mac_smack_use())); + + r = mac_selinux_init(); + if (r < 0) + return r; + + return mac_smack_init(); +} diff --git a/src/shared/label-util.h b/src/shared/label-util.h index 2f899e2bddc..2f8c5396189 100644 --- a/src/shared/label-util.h +++ b/src/shared/label-util.h @@ -24,3 +24,5 @@ static inline int symlink_atomic_label(const char *from, const char *to) { int mknod_label(const char *pathname, mode_t mode, dev_t dev); int btrfs_subvol_make_label(const char *path); + +int mac_init(void); diff --git a/src/shared/selinux-util.c b/src/shared/selinux-util.c index cc00a85952c..a38a56f4349 100644 --- a/src/shared/selinux-util.c +++ b/src/shared/selinux-util.c @@ -20,6 +20,7 @@ #include "alloc-util.h" #include "errno-util.h" #include "fd-util.h" +#include "label.h" #include "log.h" #include "macro.h" #include "mallinfo-util.h" @@ -54,6 +55,15 @@ static bool have_status_page = false; : -ERRNO_VALUE(_e); \ _enforcing ? _r : 0; \ }) + +static int mac_selinux_label_pre(int dir_fd, const char *path, mode_t mode) { + return mac_selinux_create_file_prepare_at(dir_fd, path, mode); +} + +static int mac_selinux_label_post(int dir_fd, const char *path) { + mac_selinux_create_file_clear(); + return 0; +} #endif bool mac_selinux_use(void) { @@ -128,6 +138,10 @@ static int open_label_db(void) { int mac_selinux_init(void) { #if HAVE_SELINUX + static const LabelOps label_ops = { + .pre = mac_selinux_label_pre, + .post = mac_selinux_label_post, + }; int r; if (initialized) @@ -152,6 +166,10 @@ int mac_selinux_init(void) { return r; } + r = label_ops_set(&label_ops); + if (r < 0) + return r; + /* Save the current policyload sequence number, so mac_selinux_maybe_reload() does not trigger on * first call without any actual change. */ last_policyload = selinux_status_policyload(); diff --git a/src/shared/smack-util.c b/src/shared/smack-util.c index 8c28dd91d75..1f88e724d00 100644 --- a/src/shared/smack-util.c +++ b/src/shared/smack-util.c @@ -15,6 +15,7 @@ #include "errno-util.h" #include "fd-util.h" #include "fileio.h" +#include "label.h" #include "log.h" #include "macro.h" #include "path-util.h" @@ -288,3 +289,23 @@ int renameat_and_apply_smack_floor_label(int fdf, const char *from, int fdt, con return 0; #endif } + +static int mac_smack_label_pre(int dir_fd, const char *path, mode_t mode) { + return 0; +} + +static int mac_smack_label_post(int dir_fd, const char *path) { + return mac_smack_fix_full(dir_fd, path, NULL, 0); +} + +int mac_smack_init(void) { + static const LabelOps label_ops = { + .pre = mac_smack_label_pre, + .post = mac_smack_label_post, + }; + + if (!mac_smack_use()) + return 0; + + return label_ops_set(&label_ops); +} diff --git a/src/shared/smack-util.h b/src/shared/smack-util.h index 953bf913583..f6ed2ece38a 100644 --- a/src/shared/smack-util.h +++ b/src/shared/smack-util.h @@ -28,6 +28,7 @@ typedef enum SmackAttr { } SmackAttr; bool mac_smack_use(void); +int mac_smack_init(void); int mac_smack_fix_full(int atfd, const char *inode_path, const char *label_path, LabelFixFlags flags); static inline int mac_smack_fix(const char *path, LabelFixFlags flags) { diff --git a/src/systemctl/systemctl-edit.c b/src/systemctl/systemctl-edit.c index 561b01a67a4..aff823d773d 100644 --- a/src/systemctl/systemctl-edit.c +++ b/src/systemctl/systemctl-edit.c @@ -333,7 +333,7 @@ int verb_edit(int argc, char *argv[], void *userdata) { if (r < 0) return r; - r = mac_selinux_init(); + r = mac_init(); if (r < 0) return r; diff --git a/src/sysusers/sysusers.c b/src/sysusers/sysusers.c index 12adad516e9..cfa4823df71 100644 --- a/src/sysusers/sysusers.c +++ b/src/sysusers/sysusers.c @@ -2178,7 +2178,7 @@ static int run(int argc, char *argv[]) { umask(0022); - r = mac_selinux_init(); + r = mac_init(); if (r < 0) return r; diff --git a/src/test/udev-rule-runner.c b/src/test/udev-rule-runner.c index 0b5938802a5..f7ba143325a 100644 --- a/src/test/udev-rule-runner.c +++ b/src/test/udev-rule-runner.c @@ -117,7 +117,7 @@ static int run(int argc, char *argv[]) { log_debug("version %s", GIT_VERSION); - r = mac_selinux_init(); + r = mac_init(); if (r < 0) return r; diff --git a/src/timedate/timedated.c b/src/timedate/timedated.c index ad483301ef1..ad1d492d6bb 100644 --- a/src/timedate/timedated.c +++ b/src/timedate/timedated.c @@ -392,7 +392,7 @@ static int context_write_data_local_rtc(Context *c) { } } - r = mac_selinux_init(); + r = mac_init(); if (r < 0) return r; diff --git a/src/tmpfiles/tmpfiles.c b/src/tmpfiles/tmpfiles.c index add3f07cb27..b58c595e6b0 100644 --- a/src/tmpfiles/tmpfiles.c +++ b/src/tmpfiles/tmpfiles.c @@ -4326,7 +4326,7 @@ static int run(int argc, char *argv[]) { umask(0022); - r = mac_selinux_init(); + r = mac_init(); if (r < 0) return r; diff --git a/src/udev/udevadm.c b/src/udev/udevadm.c index b803f7bb0f5..51dc041a29c 100644 --- a/src/udev/udevadm.c +++ b/src/udev/udevadm.c @@ -130,7 +130,7 @@ static int run(int argc, char *argv[]) { if (r <= 0) return r; - r = mac_selinux_init(); + r = mac_init(); if (r < 0) return r; diff --git a/src/udev/udevd.c b/src/udev/udevd.c index b3aabcaa1f1..cf00576cfbe 100644 --- a/src/udev/udevd.c +++ b/src/udev/udevd.c @@ -2019,7 +2019,7 @@ int run_udevd(int argc, char *argv[]) { /* set umask before creating any file/directory */ umask(022); - r = mac_selinux_init(); + r = mac_init(); if (r < 0) return r; diff --git a/src/update-done/update-done.c b/src/update-done/update-done.c index 6518830717e..f448b3b1d17 100644 --- a/src/update-done/update-done.c +++ b/src/update-done/update-done.c @@ -48,7 +48,7 @@ int main(int argc, char *argv[]) { return EXIT_FAILURE; } - r = mac_selinux_init(); + r = mac_init(); if (r < 0) return EXIT_FAILURE; diff --git a/src/user-sessions/user-sessions.c b/src/user-sessions/user-sessions.c index 37867ee3ed1..58054f89fb3 100644 --- a/src/user-sessions/user-sessions.c +++ b/src/user-sessions/user-sessions.c @@ -25,7 +25,7 @@ static int run(int argc, char *argv[]) { umask(0022); - r = mac_selinux_init(); + r = mac_init(); if (r < 0) return r;