Laszlo Ersek
2022-May-11 12:23 UTC
[Libguestfs] [libguestfs PATCH 0/2] daemon/selinux-relabel: tolerate relabeling errors
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1794518 In the "selinux-relabel" API, utilize the "-C" option of setfiles(8), if it is available. (It's going to be part of the policycoreutils-3.4 release.) See patch#2 for a bit longer explanation. Thanks Laszlo Laszlo Ersek (2): daemon/selinux-relabel: generalize setfiles_has_m_option() daemon/selinux-relabel: tolerate relabeling errors daemon/selinux-relabel.c | 36 +++++++++++++------- 1 file changed, 24 insertions(+), 12 deletions(-) base-commit: 08c4ac90f5a3c08b48444e2faf3d0f58d6ddc206 -- 2.19.1.3.g30247aa5d201
Laszlo Ersek
2022-May-11 12:23 UTC
[Libguestfs] [libguestfs PATCH 1/2] daemon/selinux-relabel: generalize setfiles_has_m_option()
Allow the caller to pass in the option to check for, and to store the result in a (usually static) variable of their choice. Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1794518 Signed-off-by: Laszlo Ersek <lersek at redhat.com> --- daemon/selinux-relabel.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/daemon/selinux-relabel.c b/daemon/selinux-relabel.c index 5679a29cf141..a34287fe27cb 100644 --- a/daemon/selinux-relabel.c +++ b/daemon/selinux-relabel.c @@ -38,17 +38,19 @@ optgroup_selinuxrelabel_available (void) } static int -setfiles_has_m_option (void) +setfiles_has_option (int *flag, char opt_char) { - static int flag = -1; CLEANUP_FREE char *err = NULL; - if (flag == -1) { - ignore_value (command (NULL, &err, "setfiles", "-m", NULL)); - flag = err && strstr (err, /* "invalid option -- " */ "'m'") == NULL; + if (*flag == -1) { + char option[] = { '-', opt_char, '\0' }; /* "-X" */ + char err_opt[] = { '\'', opt_char, '\'', '\0'}; /* "'X'" */ + + ignore_value (command (NULL, &err, "setfiles", option, NULL)); + *flag = err && strstr (err, /* "invalid option -- " */ err_opt) == NULL; } - return flag; + return *flag; } /* Takes optional arguments, consult optargs_bitmask. */ @@ -56,6 +58,7 @@ int do_selinux_relabel (const char *specfile, const char *path, int force) { + static int flag_m = -1; const char *argv[MAX_ARGS]; CLEANUP_FREE char *s_dev = NULL, *s_proc = NULL, *s_selinux = NULL, *s_sys = NULL, *s_specfile = NULL, *s_path = NULL; @@ -101,7 +104,7 @@ do_selinux_relabel (const char *specfile, const char *path, * setfiles puts all the mountpoints on the excludes list for no * useful reason (RHBZ#1433577). */ - if (setfiles_has_m_option ()) + if (setfiles_has_option (&flag_m, 'm')) ADD_ARG (argv, i, "-m"); /* Relabelling in a chroot. */ -- 2.19.1.3.g30247aa5d201
Laszlo Ersek
2022-May-11 12:23 UTC
[Libguestfs] [libguestfs PATCH 2/2] daemon/selinux-relabel: tolerate relabeling errors
Option "-C" of setfiles(8) causes setfiles(8) to exit with status 1 rather than status 255 if it encounters relabeling errors, but no other (fatal) error. Pass "-C" to setfiles(8) in "selinux-relabel", because we don't want the "selinux-relabel" API to fail if setfiles(8) only encounters relabeling errors. (NB even without "-C", setfiles(8) continues traversing the directory tree(s) and relabeling files across relabeling errors, so this change is specifically about the exit status.) Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1794518 Signed-off-by: Laszlo Ersek <lersek at redhat.com> --- daemon/selinux-relabel.c | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/daemon/selinux-relabel.c b/daemon/selinux-relabel.c index a34287fe27cb..976cffe37261 100644 --- a/daemon/selinux-relabel.c +++ b/daemon/selinux-relabel.c @@ -59,11 +59,13 @@ do_selinux_relabel (const char *specfile, const char *path, int force) { static int flag_m = -1; + static int flag_C = -1; const char *argv[MAX_ARGS]; CLEANUP_FREE char *s_dev = NULL, *s_proc = NULL, *s_selinux = NULL, *s_sys = NULL, *s_specfile = NULL, *s_path = NULL; CLEANUP_FREE char *err = NULL; size_t i = 0; + int setfiles_status; s_dev = sysroot_path ("/dev"); if (!s_dev) { @@ -107,6 +109,13 @@ do_selinux_relabel (const char *specfile, const char *path, if (setfiles_has_option (&flag_m, 'm')) ADD_ARG (argv, i, "-m"); + /* Not only do we want setfiles to trudge through individual relabeling + * errors, we also want the setfiles exit status to differentiate a fatal + * error from "relabeling errors only". See RHBZ#1794518. + */ + if (setfiles_has_option (&flag_C, 'C')) + ADD_ARG (argv, i, "-C"); + /* Relabelling in a chroot. */ if (STRNEQ (sysroot, "/")) { ADD_ARG (argv, i, "-r"); @@ -124,10 +133,10 @@ do_selinux_relabel (const char *specfile, const char *path, ADD_ARG (argv, i, s_path); ADD_ARG (argv, i, NULL); - if (commandv (NULL, &err, argv) == -1) { - reply_with_error ("%s", err); - return -1; - } + setfiles_status = commandrv (NULL, &err, argv); + if ((setfiles_status == 0) || (setfiles_status == 1 && flag_C)) + return 0; - return 0; + reply_with_error ("%s", err); + return -1; } -- 2.19.1.3.g30247aa5d201