From: Roberto Sassu roberto.sassu@huawei.com
hulk inclusion category: feature feature: IMA Digest Lists extension bugzilla: 46797
---------------------------
This patch limits the digest lists processed by the kernel by excluding those that are not in the compact format. The patch then executes the user space parsers to process the skipped digest lists.
Signed-off-by: Roberto Sassu roberto.sassu@huawei.com Acked-by: Hanjun Guo guohanjun@huawei.com Signed-off-by: Yang Yingliang yangyingliang@huawei.com Reviewed-by: Jason Yan yanaijie@huawei.com Signed-off-by: Zheng Zengkai zhengzengkai@huawei.com Signed-off-by: zhoushuiqing zhoushuiqing2@huawei.com --- security/integrity/ima/Kconfig | 7 +++++ security/integrity/ima/ima_digest_list.c | 38 +++++++++++++++++++++--- 2 files changed, 41 insertions(+), 4 deletions(-)
diff --git a/security/integrity/ima/Kconfig b/security/integrity/ima/Kconfig index 73c582d97737..aa6a06f3e8b1 100644 --- a/security/integrity/ima/Kconfig +++ b/security/integrity/ima/Kconfig @@ -356,3 +356,10 @@ config IMA_DIGEST_LISTS_DIR help This option defines the path of the directory containing digest lists. + +config IMA_PARSER_BINARY_PATH + string "Path of the parser binary" + depends on IMA_DIGEST_LIST + default "/usr/bin/upload_digest_lists" + help + This option defines the path of the parser binary. diff --git a/security/integrity/ima/ima_digest_list.c b/security/integrity/ima/ima_digest_list.c index b5d1004e3040..0712023d6761 100644 --- a/security/integrity/ima/ima_digest_list.c +++ b/security/integrity/ima/ima_digest_list.c @@ -265,7 +265,7 @@ struct readdir_callback { struct path *path; };
-static int __init load_digest_list(struct dir_context *__ctx, const char *name, +static bool __init load_digest_list(struct dir_context *__ctx, const char *name, int namelen, loff_t offset, u64 ino, unsigned int d_type) { @@ -274,16 +274,33 @@ static int __init load_digest_list(struct dir_context *__ctx, const char *name, struct dentry *dentry; struct file *file; u8 *xattr_value = NULL; + char *type_start, *format_start, *format_end; void *datap = NULL; loff_t size; int ret;
if (!strcmp(name, ".") || !strcmp(name, "..")) - return 0; + return true; + + type_start = strchr(name, '-'); + if (!type_start) + return true; + + format_start = strchr(type_start + 1, '-'); + if (!format_start) + return true; + + format_end = strchr(format_start + 1, '-'); + if (!format_end) + return true; + + if (format_end - format_start - 1 != strlen("compact") || + strncmp(format_start + 1, "compact", format_end - format_start - 1)) + return true;
dentry = lookup_one_len(name, dir->dentry, strlen(name)); if (IS_ERR(dentry)) - return 0; + return true;
size = vfs_getxattr(&nop_mnt_idmap, dentry, XATTR_NAME_EVM, NULL, 0); if (size < 0) { @@ -319,7 +336,18 @@ static int __init load_digest_list(struct dir_context *__ctx, const char *name, fput(file); out: kfree(xattr_value); - return 0; + return true; +} + +static void ima_exec_parser(void) +{ + char *argv[4] = {NULL}, *envp[1] = {NULL}; + + argv[0] = (char *)CONFIG_IMA_PARSER_BINARY_PATH; + argv[1] = "add"; + argv[2] = (char *)CONFIG_IMA_DIGEST_LISTS_DIR; + + call_usermodehelper(argv[0], argv, envp, UMH_WAIT_PROC); }
void __init ima_load_digest_lists(void) @@ -347,6 +375,8 @@ void __init ima_load_digest_lists(void) fput(file); out: path_put(&path); + + ima_exec_parser(); }
/****************