File 0001-dracut_install-Copy-necessary-digest-lists-to-the-in.patch of Package dracut

From da5c26256d5fe71f9bc63f8c8a6e67835c248752 Mon Sep 17 00:00:00 2001
From: Roberto Sassu <roberto.sassu@huawei.com>
Date: Wed, 28 Feb 2024 10:39:33 +0100
Subject: [PATCH] dracut_install: Copy necessary digest lists to the initial
 ram disk

Check if a file being copied to the initial ram disk has the
security.digest_list xattr and, in that case, copy the digest list too.

Use /etc/digest_lists as the predefined digest list directory, and allow it
to be overridden with the DRACUT_DIGEST_LIST_PATH environment variable.

Signed-off-by: Roberto Sassu <roberto.sassu@huawei.com>
---
 man/dracut.8.asc             |  6 ++++++
 src/install/dracut-install.c | 39 ++++++++++++++++++++++++++++++++++++
 2 files changed, 45 insertions(+)

diff --git a/man/dracut.8.asc b/man/dracut.8.asc
index 5c2b147ab268..f41493349c04 100644
--- a/man/dracut.8.asc
+++ b/man/dracut.8.asc
@@ -707,6 +707,12 @@ _DRACUT_INSTALL_LOG_LEVEL_::
 Default:
     _DRACUT_LOG_LEVEL_
 
+_DRACUT_DIGEST_LIST_PATH_::
+    override the default digest list directory path /etc/digest_lists.
++
+Default:
+    /etc/digest_lists
+
 FILES
 -----
 _/var/log/dracut.log_::
diff --git a/src/install/dracut-install.c b/src/install/dracut-install.c
index 96b20e916d35..a70b6d1c5cf8 100644
--- a/src/install/dracut-install.c
+++ b/src/install/dracut-install.c
@@ -19,6 +19,8 @@
 
 #define PROGRAM_VERSION_STRING "2"
 
+#define DIGEST_LIST_PATH "/etc/digest_lists"
+
 #ifndef _GNU_SOURCE
 #define _GNU_SOURCE
 #endif
@@ -43,6 +45,8 @@
 #include <fts.h>
 #include <regex.h>
 #include <sys/utsname.h>
+#include <sys/xattr.h>
+#include <linux/xattr.h>
 
 #include "log.h"
 #include "hashmap.h"
@@ -93,6 +97,8 @@ static bool arg_mod_filter_nopath = false;
 static bool arg_mod_filter_symbol = false;
 static bool arg_mod_filter_nosymbol = false;
 static bool arg_mod_filter_noname = false;
+static char digest_list_path[PATH_MAX] = DIGEST_LIST_PATH;
+static int digest_list_path_len = sizeof(DIGEST_LIST_PATH) - 1;
 
 static int dracut_install(const char *src, const char *dst, bool isdir, bool resolvedeps, bool hashdst);
 
@@ -273,6 +279,29 @@ static inline int clone_file(int dest_fd, int src_fd)
 
 static bool use_clone = true;
 
+static int dracut_install_digest_list(const char *src)
+{
+        char digest_list_filename[NAME_MAX + 1];
+        struct stat st;
+        int ret, len;
+
+        len = getxattr(src, XATTR_NAME_DIGEST_LIST, digest_list_filename,
+                       sizeof(digest_list_filename) - 1);
+        if (len <= 0)
+                return 0;
+
+        digest_list_filename[len] = '\0';
+        snprintf(digest_list_path + digest_list_path_len,
+                 sizeof(digest_list_path) - digest_list_path_len, "/%s",
+                 digest_list_filename);
+
+        if (stat(digest_list_path, &st) == -1)
+                return 0;
+
+        dracut_install(digest_list_path, digest_list_path, false, false, true);
+        return 0;
+}
+
 static int cp(const char *src, const char *dst)
 {
         int pid;
@@ -798,6 +827,9 @@ static int dracut_install(const char *orig_src, const char *orig_dst, bool isdir
                 src_mode = sb.st_mode;
         }
 
+        if (!src_isdir)
+                dracut_install_digest_list(fullsrcpath);
+
         _asprintf(&fulldstpath, "%s/%s", destrootdir, (dst[0] == '/' ? (dst + 1) : dst));
 
         ret = stat(fulldstpath, &sb);
@@ -1970,6 +2002,7 @@ int main(int argc, char **argv)
         char *i;
         char *path = NULL;
         char *env_no_xattr = NULL;
+        char *custom_digest_list_path = NULL;
 
         log_set_target(LOG_TARGET_CONSOLE);
         log_parse_environment();
@@ -1979,6 +2012,12 @@ int main(int argc, char **argv)
         if (r <= 0)
                 return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
 
+        custom_digest_list_path = getenv("DRACUT_DIGEST_LIST_PATH");
+        if (custom_digest_list_path)
+                digest_list_path_len = snprintf(digest_list_path,
+                                                sizeof(digest_list_path), "%s",
+                                                custom_digest_list_path);
+
         modules_loaded = hashmap_new(string_hash_func, string_compare_func);
         if (arg_modalias) {
                 Iterator i;
-- 
2.34.1

openSUSE Build Service is sponsored by