Florian Festi 94360a
From ac7b0dbd5a18d2c57a942ca14ac856b8047425ff Mon Sep 17 00:00:00 2001
Florian Festi 94360a
From: Panu Matilainen <pmatilai@redhat.com>
Florian Festi 94360a
Date: Tue, 15 Feb 2022 10:43:13 +0200
Florian Festi 94360a
Subject: [PATCH] Pass file descriptor to file prepare plugin hook, use when
Florian Festi 94360a
 possible
Florian Festi 94360a
Florian Festi 94360a
Sadly the thing that allegedly makes things better mostly just makes
Florian Festi 94360a
things more complicated as symlinks can't be opened, so we'll now have
Florian Festi 94360a
to deal with both cases in plugins too. To make matters worse, most
Florian Festi 94360a
APIs out there support either an fd or a path, but very few support
Florian Festi 94360a
the *at() style dirfd + basename approach so plugins are stuck with
Florian Festi 94360a
absolute paths for now.
Florian Festi 94360a
Florian Festi 94360a
This is of course a plugin API/ABI change too.
Florian Festi 94360a
---
Florian Festi 94360a
 lib/rpmplugin.h   |  2 +-
Florian Festi 94360a
 lib/rpmplugins.c  |  4 ++--
Florian Festi 94360a
 lib/rpmplugins.h  |  3 ++-
Florian Festi 94360a
 plugins/ima.c     |  9 +++++++--
Florian Festi 94360a
 plugins/selinux.c | 13 ++++++++-----
Florian Festi 94360a
 5 files changed, 20 insertions(+), 11 deletions(-)
Florian Festi 94360a
Florian Festi 94360a
diff --git a/lib/rpmplugin.h b/lib/rpmplugin.h
Florian Festi 94360a
index fd81aec8d..fab4b3e83 100644
Florian Festi 94360a
--- a/lib/rpmplugin.h
Florian Festi 94360a
+++ b/lib/rpmplugin.h
Florian Festi 94360a
@@ -57,7 +57,7 @@ typedef rpmRC (*plugin_fsm_file_post_func)(rpmPlugin plugin, rpmfi fi,
Florian Festi 94360a
 					   const char* path, mode_t file_mode,
Florian Festi 94360a
 					   rpmFsmOp op, int res);
Florian Festi 94360a
 typedef rpmRC (*plugin_fsm_file_prepare_func)(rpmPlugin plugin, rpmfi fi,
Florian Festi 94360a
-					      const char* path,
Florian Festi 94360a
+					      int fd, const char* path,
Florian Festi 94360a
 					      const char *dest,
Florian Festi 94360a
 					      mode_t file_mode, rpmFsmOp op);
Florian Festi 94360a
 
Florian Festi 94360a
diff --git a/lib/rpmplugins.c b/lib/rpmplugins.c
Florian Festi 94360a
index 65e684e84..923084b78 100644
Florian Festi 94360a
--- a/lib/rpmplugins.c
Florian Festi 94360a
+++ b/lib/rpmplugins.c
Florian Festi 94360a
@@ -384,7 +384,7 @@ rpmRC rpmpluginsCallFsmFilePost(rpmPlugins plugins, rpmfi fi, const char *path,
Florian Festi 94360a
 }
Florian Festi 94360a
 
Florian Festi 94360a
 rpmRC rpmpluginsCallFsmFilePrepare(rpmPlugins plugins, rpmfi fi,
Florian Festi 94360a
-				   const char *path, const char *dest,
Florian Festi 94360a
+				   int fd, const char *path, const char *dest,
Florian Festi 94360a
 				   mode_t file_mode, rpmFsmOp op)
Florian Festi 94360a
 {
Florian Festi 94360a
     plugin_fsm_file_prepare_func hookFunc;
Florian Festi 94360a
@@ -394,7 +394,7 @@ rpmRC rpmpluginsCallFsmFilePrepare(rpmPlugins plugins, rpmfi fi,
Florian Festi 94360a
     for (i = 0; i < plugins->count; i++) {
Florian Festi 94360a
 	rpmPlugin plugin = plugins->plugins[i];
Florian Festi 94360a
 	RPMPLUGINS_SET_HOOK_FUNC(fsm_file_prepare);
Florian Festi 94360a
-	if (hookFunc && hookFunc(plugin, fi, path, dest, file_mode, op) == RPMRC_FAIL) {
Florian Festi 94360a
+	if (hookFunc && hookFunc(plugin, fi, fd, path, dest, file_mode, op) == RPMRC_FAIL) {
Florian Festi 94360a
 	    rpmlog(RPMLOG_ERR, "Plugin %s: hook fsm_file_prepare failed\n", plugin->name);
Florian Festi 94360a
 	    rc = RPMRC_FAIL;
Florian Festi 94360a
 	}
Florian Festi 94360a
diff --git a/lib/rpmplugins.h b/lib/rpmplugins.h
Florian Festi 94360a
index 39762c376..ddf5d7048 100644
Florian Festi 94360a
--- a/lib/rpmplugins.h
Florian Festi 94360a
+++ b/lib/rpmplugins.h
Florian Festi 94360a
@@ -156,6 +156,7 @@ rpmRC rpmpluginsCallFsmFilePost(rpmPlugins plugins, rpmfi fi, const char* path,
Florian Festi 94360a
  * permissions etc, but before committing file to destination path.
Florian Festi 94360a
  * @param plugins	plugins structure
Florian Festi 94360a
  * @param fi		file info iterator (or NULL)
Florian Festi 94360a
+ * @param fd		file descriptor (or -1 if not available)
Florian Festi 94360a
  * @param path		file object current path
Florian Festi 94360a
  * @param dest		file object destination path
Florian Festi 94360a
  * @param mode		file object mode
Florian Festi 94360a
@@ -164,7 +165,7 @@ rpmRC rpmpluginsCallFsmFilePost(rpmPlugins plugins, rpmfi fi, const char* path,
Florian Festi 94360a
  */
Florian Festi 94360a
 RPM_GNUC_INTERNAL
Florian Festi 94360a
 rpmRC rpmpluginsCallFsmFilePrepare(rpmPlugins plugins, rpmfi fi,
Florian Festi 94360a
-                                   const char *path, const char *dest,
Florian Festi 94360a
+                                   int fd, const char *path, const char *dest,
Florian Festi 94360a
                                    mode_t mode, rpmFsmOp op);
Florian Festi 94360a
 
Florian Festi 94360a
 #ifdef __cplusplus
Florian Festi 94360a
diff --git a/plugins/ima.c b/plugins/ima.c
Florian Festi 94360a
index fe6d3ad7f..9c28a41a3 100644
Florian Festi 94360a
--- a/plugins/ima.c
Florian Festi 94360a
+++ b/plugins/ima.c
Florian Festi 94360a
@@ -39,7 +39,7 @@ static int check_zero_hdr(const unsigned char *fsig, size_t siglen)
Florian Festi 94360a
 	return (memcmp(fsig, &zero_hdr, sizeof(zero_hdr)) == 0);
Florian Festi 94360a
 }
Florian Festi 94360a
 
Florian Festi 94360a
-static rpmRC ima_fsm_file_prepare(rpmPlugin plugin, rpmfi fi,
Florian Festi 94360a
+static rpmRC ima_fsm_file_prepare(rpmPlugin plugin, rpmfi fi, int fd,
Florian Festi 94360a
                                   const char *path,
Florian Festi 94360a
                                   const char *dest,
Florian Festi 94360a
                                   mode_t file_mode, rpmFsmOp op)
Florian Festi 94360a
@@ -68,8 +68,13 @@
Florian Festi 94360a
 
Florian Festi 94360a
 	fsig = rpmfiFSignature(fi, &len;;
Florian Festi 94360a
 	if (fsig && (check_zero_hdr(fsig, len) == 0)) {
Florian Festi 94360a
-	    if (lsetxattr(path, XATTR_NAME_IMA, fsig, len, 0) < 0) {
Florian Festi 94360a
-		int is_err = errno != EOPNOTSUPP; 
Florian Festi 94360a
+	    int xx;
Florian Festi 94360a
+	    if (fd >= 0)
Florian Festi 94360a
+		xx = fsetxattr(fd, XATTR_NAME_IMA, fsig, len, 0);
Florian Festi 94360a
+	    else
Florian Festi 94360a
+		xx = lsetxattr(path, XATTR_NAME_IMA, fsig, len, 0);
Florian Festi 94360a
+	    if (xx < 0) {
Florian Festi 94360a
+		int is_err = xx != EOPNOTSUPP;
Florian Festi 94360a
 	        rpmlog(is_err?RPMLOG_ERR:RPMLOG_DEBUG,
Florian Festi 94360a
 			"ima: could not apply signature on '%s': %s\n",
Florian Festi 94360a
 			path, strerror(errno));
Florian Festi 94360a
diff --git a/plugins/fapolicyd.c b/plugins/fapolicyd.c
Florian Festi 94360a
index 7ac44f0d0..1ff50c30f 100644
Florian Festi 94360a
--- a/plugins/fapolicyd.c
Florian Festi 94360a
+++ b/plugins/fapolicyd.c
Florian Festi 94360a
@@ -145,7 +145,8 @@ static rpmRC fapolicyd_scriptlet_pre(rpmPlugin plugin, const char *s_name,
Florian Festi 94360a
 }
Florian Festi 94360a
 
Florian Festi 94360a
 static rpmRC fapolicyd_fsm_file_prepare(rpmPlugin plugin, rpmfi fi,
Florian Festi 94360a
-                                        const char *path, const char *dest,
Florian Festi 94360a
+                                        int fd, const char *path,
Florian Festi 94360a
+					const char *dest,
Florian Festi 94360a
                                         mode_t file_mode, rpmFsmOp op)
Florian Festi 94360a
 {
Florian Festi 94360a
     /* not ready  */
Florian Festi 94360a
diff --git a/plugins/selinux.c b/plugins/selinux.c
Florian Festi 94360a
index 32c3b7529..a7f20aeca 100644
Florian Festi 94360a
--- a/plugins/selinux.c
Florian Festi 94360a
+++ b/plugins/selinux.c
Florian Festi 94360a
@@ -149,7 +149,7 @@ static rpmRC selinux_scriptlet_fork_post(rpmPlugin plugin,
Florian Festi 94360a
     return rc;
Florian Festi 94360a
 }
Florian Festi 94360a
 
Florian Festi 94360a
-static rpmRC selinux_fsm_file_prepare(rpmPlugin plugin, rpmfi fi,
Florian Festi 94360a
+static rpmRC selinux_fsm_file_prepare(rpmPlugin plugin, rpmfi fi, int fd,
Florian Festi 94360a
 					const char *path, const char *dest,
Florian Festi 94360a
 				        mode_t file_mode, rpmFsmOp op)
Florian Festi 94360a
 {
Florian Festi 94360a
@@ -194,13 +194,17 @@
Florian Festi 94360a
     if (sehandle && !XFA_SKIPPING(action)) {
Florian Festi 94360a
 	char *scon = NULL;
Florian Festi 94360a
 	if (selabel_lookup_raw(sehandle, &scon, dest, file_mode) == 0) {
Florian Festi 94360a
-	    int conrc = lsetfilecon(path, scon);
Florian Festi 94360a
+	    int conrc;
Florian Festi 94360a
+	    if (fd >= 0)
Florian Festi 94360a
+		conrc = fsetfilecon(fd, scon);
Florian Festi 94360a
+	    else
Florian Festi 94360a
+		conrc = lsetfilecon(path, scon);
Florian Festi 94360a
 
Florian Festi 94360a
 	    if (conrc == 0 || (conrc < 0 && errno == EOPNOTSUPP))
Florian Festi 94360a
 		rc = RPMRC_OK;
Florian Festi 94360a
 
Florian Festi 94360a
-	    rpmlog(loglvl(rc != RPMRC_OK), "lsetfilecon: (%s, %s) %s\n",
Florian Festi 94360a
-		       path, scon, (conrc < 0 ? strerror(errno) : ""));
Florian Festi 94360a
+	    rpmlog(loglvl(rc != RPMRC_OK), "lsetfilecon: (%d %s, %s) %s\n",
Florian Festi 94360a
+		   fd, path, scon, (conrc < 0 ? strerror(errno) : ""));
Florian Festi 94360a
 
Florian Festi 94360a
 	    freecon(scon);
Florian Festi 94360a
 	} else {
Florian Festi 94360a
-- 
Florian Festi 94360a
2.41.0
Florian Festi 94360a