Blame SOURCES/0094-mlcustomize-Refactor-SELinux_relabel-code.patch

da373f
From 3bceb391d14aeebb21dd9742108fa98945a32c5c Mon Sep 17 00:00:00 2001
da373f
From: "Richard W.M. Jones" <rjones@redhat.com>
da373f
Date: Tue, 5 May 2020 16:44:14 +0100
da373f
Subject: [PATCH] mlcustomize: Refactor SELinux_relabel code.
da373f
da373f
This shouldn't change the effect of this code.
da373f
da373f
Cherry picked from libguestfs-common
da373f
commit 3493d9fcaab6de1c09528e55a01bc24f0fb6c03c and backported
da373f
to libguestfs 1.40 branch (which predates the common submodule).
da373f
---
da373f
 customize/SELinux_relabel.ml | 127 +++++++++++++++++++----------------
da373f
 1 file changed, 68 insertions(+), 59 deletions(-)
da373f
da373f
diff --git a/customize/SELinux_relabel.ml b/customize/SELinux_relabel.ml
da373f
index 44995df6b..5df1f0895 100644
da373f
--- a/customize/SELinux_relabel.ml
da373f
+++ b/customize/SELinux_relabel.ml
da373f
@@ -28,65 +28,74 @@ module G = Guestfs
da373f
 let array_find a l =
da373f
   List.mem a (Array.to_list l)
da373f
 
da373f
-let relabel (g : G.guestfs) =
da373f
-  (* Is the guest using SELinux? *)
da373f
-  if g#is_file ~followsymlinks:true "/usr/sbin/load_policy" &&
da373f
-     g#is_file ~followsymlinks:true "/etc/selinux/config" then (
da373f
-    (* Is setfiles / SELinux relabelling functionality available? *)
da373f
-    if g#feature_available [| "selinuxrelabel" |] then (
da373f
-      (* Use Augeas to parse /etc/selinux/config. *)
da373f
-      g#aug_init "/" (16+32) (* AUG_SAVE_NOOP | AUG_NO_LOAD *);
da373f
-      (* See: https://bugzilla.redhat.com/show_bug.cgi?id=975412#c0 *)
da373f
-      ignore (g#aug_rm "/augeas/load/*[\"/etc/selinux/config/\" !~ regexp('^') + glob(incl) + regexp('/.*')]");
da373f
-      g#aug_load ();
da373f
-      debug_augeas_errors g;
da373f
-
da373f
-      (* Get the SELinux policy name, eg. "targeted", "minimum".
da373f
-       * Use "targeted" if not specified, just like libselinux does.
da373f
-       *)
da373f
-      let policy =
da373f
-        let config_path = "/files/etc/selinux/config" in
da373f
-        let selinuxtype_path = config_path ^ "/SELINUXTYPE" in
da373f
-        let keys = g#aug_ls config_path in
da373f
-        if array_find selinuxtype_path keys then
da373f
-          g#aug_get selinuxtype_path
da373f
-        else
da373f
-          "targeted" in
da373f
-
da373f
-      g#aug_close ();
da373f
-
da373f
-      (* Get the spec file name. *)
da373f
-      let specfile =
da373f
-        sprintf "/etc/selinux/%s/contexts/files/file_contexts" policy in
da373f
-
da373f
-      (* RHEL 6.2 - 6.5 had a malformed specfile that contained the
da373f
-       * invalid regular expression "/var/run/spice-vdagentd.\pid"
da373f
-       * (instead of "\.p").  This stops setfiles from working on
da373f
-       * the guest.
da373f
-       *
da373f
-       * Because an SELinux relabel writes all over the filesystem,
da373f
-       * it seems reasonable to fix this problem in the specfile
da373f
-       * at the same time.  (RHBZ#1374232)
da373f
-       *)
da373f
-      if g#grep ~fixed:true "vdagentd.\\pid" specfile <> [||] then (
da373f
-        debug "fixing invalid regular expression in %s" specfile;
da373f
-        let old_specfile = specfile ^ "~" in
da373f
-        g#mv specfile old_specfile;
da373f
-        let content = g#read_file old_specfile in
da373f
-        let content =
da373f
-          String.replace content "vdagentd.\\pid" "vdagentd\\.pid" in
da373f
-        g#write specfile content;
da373f
-        g#copy_attributes ~all:true old_specfile specfile
da373f
-      );
da373f
-
da373f
-      (* Relabel everything. *)
da373f
-      g#selinux_relabel ~force:true specfile "/";
da373f
-
da373f
-      (* If that worked, we don't need to autorelabel. *)
da373f
+let rec relabel (g : G.guestfs) =
da373f
+  (* Is the guest using SELinux?  (Otherwise this is a no-op). *)
da373f
+  if is_selinux_guest g then (
da373f
+    try
da373f
+      use_setfiles g;
da373f
+      (* That worked, so we don't need to autorelabel. *)
da373f
       g#rm_f "/.autorelabel"
da373f
-    )
da373f
-    else (
da373f
-      (* SELinux guest, but not SELinux host.  Fallback to this. *)
da373f
+    with Failure _ ->
da373f
+      (* This is the fallback in case something in the setfiles
da373f
+       * method didn't work.  That includes the case where a non-SELinux
da373f
+       * host is processing an SELinux guest, and other things.
da373f
+       *)
da373f
       g#touch "/.autorelabel"
da373f
-    )
da373f
   )
da373f
+
da373f
+and is_selinux_guest g =
da373f
+  g#is_file ~followsymlinks:true "/usr/sbin/load_policy" &&
da373f
+  g#is_file ~followsymlinks:true "/etc/selinux/config"
da373f
+
da373f
+and use_setfiles g =
da373f
+  (* Is setfiles / SELinux relabelling functionality available? *)
da373f
+  if not (g#feature_available [| "selinuxrelabel" |]) then
da373f
+    failwith "no selinux relabel feature";
da373f
+
da373f
+  (* Use Augeas to parse /etc/selinux/config. *)
da373f
+  g#aug_init "/" (16+32) (* AUG_SAVE_NOOP | AUG_NO_LOAD *);
da373f
+  (* See: https://bugzilla.redhat.com/show_bug.cgi?id=975412#c0 *)
da373f
+  ignore (g#aug_rm "/augeas/load/*[\"/etc/selinux/config/\" !~ regexp('^') + glob(incl) + regexp('/.*')]");
da373f
+  g#aug_load ();
da373f
+  debug_augeas_errors g;
da373f
+
da373f
+  (* Get the SELinux policy name, eg. "targeted", "minimum".
da373f
+   * Use "targeted" if not specified, just like libselinux does.
da373f
+   *)
da373f
+  let policy =
da373f
+    let config_path = "/files/etc/selinux/config" in
da373f
+    let selinuxtype_path = config_path ^ "/SELINUXTYPE" in
da373f
+    let keys = g#aug_ls config_path in
da373f
+    if array_find selinuxtype_path keys then
da373f
+      g#aug_get selinuxtype_path
da373f
+    else
da373f
+      "targeted" in
da373f
+
da373f
+  g#aug_close ();
da373f
+
da373f
+  (* Get the spec file name. *)
da373f
+  let specfile =
da373f
+    sprintf "/etc/selinux/%s/contexts/files/file_contexts" policy in
da373f
+
da373f
+  (* RHEL 6.2 - 6.5 had a malformed specfile that contained the
da373f
+   * invalid regular expression "/var/run/spice-vdagentd.\pid"
da373f
+   * (instead of "\.p").  This stops setfiles from working on
da373f
+   * the guest.
da373f
+   *
da373f
+   * Because an SELinux relabel writes all over the filesystem,
da373f
+   * it seems reasonable to fix this problem in the specfile
da373f
+   * at the same time.  (RHBZ#1374232)
da373f
+   *)
da373f
+  if g#grep ~fixed:true "vdagentd.\\pid" specfile <> [||] then (
da373f
+    debug "fixing invalid regular expression in %s" specfile;
da373f
+    let old_specfile = specfile ^ "~" in
da373f
+    g#mv specfile old_specfile;
da373f
+    let content = g#read_file old_specfile in
da373f
+    let content =
da373f
+      String.replace content "vdagentd.\\pid" "vdagentd\\.pid" in
da373f
+    g#write specfile content;
da373f
+    g#copy_attributes ~all:true old_specfile specfile
da373f
+  );
da373f
+
da373f
+  (* Relabel everything. *)
da373f
+  g#selinux_relabel ~force:true specfile "/"
da373f
-- 
da373f
2.18.4
da373f