|
|
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 |
|