From 3c3e44171146c5c78287635e71c7adaea26fab3e Mon Sep 17 00:00:00 2001 From: Roberto Sassu Date: Thu, 11 Mar 2021 11:59:45 +0100 Subject: [PATCH 10/13] Remove digest list from the kernel during package reinstallation Signed-off-by: luhuaxin --- plugins/digest_list.c | 36 +++++++++++++++++------------------- 1 file changed, 17 insertions(+), 19 deletions(-) diff --git a/plugins/digest_list.c b/plugins/digest_list.c index ca77282..63f8f1c 100644 --- a/plugins/digest_list.c +++ b/plugins/digest_list.c @@ -27,9 +27,6 @@ #define DIGEST_LIST_DEFAULT_PATH "/etc/ima/digest_lists" #define RPM_PARSER "/usr/libexec/rpm_parser" -#define DIGEST_LIST_OP_ADD 0 -#define DIGEST_LIST_OP_DEL 1 - enum hash_algo { HASH_ALGO_MD4, HASH_ALGO_MD5, @@ -372,12 +369,13 @@ out: return ret; } -static int process_digest_list(rpmte te, int parser) +static int process_digest_list(rpmte te, int parser, int pre) { char *path = NULL, *path_sig = NULL; int digest_list_signed = 0; struct stat st; ssize_t size; + int type = rpmteType(te); struct __user_cap_header_struct cap_header_data; cap_user_header_t cap_header = &cap_header_data; struct __user_cap_data_struct cap_data_data; @@ -431,15 +429,7 @@ static int process_digest_list(rpmte te, int parser) size = lgetxattr(path, XATTR_NAME_IMA, NULL, 0); - /* Don't upload again if digest list was already processed */ - if ((rpmteType(te) == TR_ADDED && size > 0) || - (rpmteType(te) == TR_REMOVED && size < 0)) { - rpmlog(RPMLOG_DEBUG, "digest_list: '%s' already processed, " - "nothing to do\n", path); - goto out; - } - - if (rpmteType(te) == TR_ADDED) { + if (type == TR_ADDED && !pre && size < 0) { if (!digest_list_signed) { /* Write RPM header to the disk */ ret = write_rpm_digest_list(te, path); @@ -472,12 +462,18 @@ static int process_digest_list(rpmte te, int parser) ret = RPMRC_FAIL; goto out; } + } else if (type == TR_ADDED && pre) { + if (size < 0) + goto out; + + /* rpm is overwriting the digest list, remove from the kernel */ + type = TR_REMOVED; } /* Upload digest list to securityfs */ - upload_digest_list(path, rpmteType(te), digest_list_signed); + upload_digest_list(path, type, digest_list_signed); - if (rpmteType(te) == TR_REMOVED) { + if (type == TR_REMOVED) { if (!digest_list_signed) { unlink(path); goto out; @@ -552,8 +548,10 @@ static rpmRC digest_list_file_common(rpmPlugin plugin, rpmfi fi, if (!pre && res != RPMRC_OK) return res; - if ((pre && action != FA_ERASE) || - (!pre && action != FA_CREATE)) + if (!pre && rpmteType(cur_te) != TR_ADDED) + return RPMRC_OK; + + if (pre && action == FA_SKIP) return RPMRC_OK; if (strncmp(path, DIGEST_LIST_DEFAULT_PATH, @@ -564,9 +562,9 @@ static rpmRC digest_list_file_common(rpmPlugin plugin, rpmfi fi, if (!pre && --digest_list_counter) return RPMRC_OK; - process_digest_list(cur_te, 0); + process_digest_list(cur_te, 0, pre); if (!strcmp(rpmteN(cur_te), "digest-list-tools")) - process_digest_list(cur_te, 1); + process_digest_list(cur_te, 1, pre); return RPMRC_OK; } -- 2.33.0