mrc0mmand / rpms / libguestfs

Forked from rpms/libguestfs 3 years ago
Clone

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

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