diff --git a/arch/arm64/configs/openeuler_defconfig b/arch/arm64/configs/openeuler_defconfig index fbaa20639d81e34f33b075a40d7ad63d6bf1ae66..7325fd69e4f4207423b89de04db427734875e421 100644 --- a/arch/arm64/configs/openeuler_defconfig +++ b/arch/arm64/configs/openeuler_defconfig @@ -6432,7 +6432,6 @@ CONFIG_IMA_X509_PATH="/etc/keys/x509_ima.der" # CONFIG_IMA_APPRAISE_SIGNED_INIT is not set CONFIG_IMA_DIGEST_LIST=y CONFIG_IMA_DIGEST_LISTS_DIR="/etc/ima/digest_lists" -# CONFIG_IMA_MIN_DIGEST_DB_SIZE is not set CONFIG_IMA_STANDARD_DIGEST_DB_SIZE=y # CONFIG_IMA_MAX_DIGEST_DB_SIZE is not set # CONFIG_IMA_CUSTOM_DIGEST_DB_SIZE is not set diff --git a/arch/x86/configs/openeuler_defconfig b/arch/x86/configs/openeuler_defconfig index 471d5c5faabb7373c24bb36b6163437fd0c7157a..a25f9210c4beda5cf7dd9cf89d991bf0dc4e84d6 100644 --- a/arch/x86/configs/openeuler_defconfig +++ b/arch/x86/configs/openeuler_defconfig @@ -7789,7 +7789,6 @@ CONFIG_IMA_X509_PATH="/etc/keys/x509_ima.der" # CONFIG_IMA_APPRAISE_SIGNED_INIT is not set CONFIG_IMA_DIGEST_LIST=y CONFIG_IMA_DIGEST_LISTS_DIR="/etc/ima/digest_lists" -# CONFIG_IMA_MIN_DIGEST_DB_SIZE is not set CONFIG_IMA_STANDARD_DIGEST_DB_SIZE=y # CONFIG_IMA_MAX_DIGEST_DB_SIZE is not set # CONFIG_IMA_CUSTOM_DIGEST_DB_SIZE is not set diff --git a/security/integrity/ima/Kconfig b/security/integrity/ima/Kconfig index c36156b3df5e521830ae3c589874afe6aac2226e..cf120fc71a7eade7fc54feee3b561f586cdb0f4c 100644 --- a/security/integrity/ima/Kconfig +++ b/security/integrity/ima/Kconfig @@ -362,8 +362,6 @@ choice database. The compiled default limit can be overwritten using the kernel command line "ima_digest_db_size". - config IMA_MIN_DIGEST_DB_SIZE - bool "minimum" config IMA_STANDARD_DIGEST_DB_SIZE bool "standard (default)" config IMA_MAX_DIGEST_DB_SIZE @@ -375,8 +373,7 @@ endchoice config IMA_DIGEST_DB_MEGABYTES int depends on IMA_DIGEST_LIST - range 8 64 - default 8 if IMA_MIN_DIGEST_DB_SIZE + range 0 64 default 16 if IMA_STANDARD_DIGEST_DB_SIZE default 64 if IMA_MAX_DIGEST_DB_SIZE diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h index acdc8ee6e53d69b1b0a56904f674007188c39cbf..6ab515592c624eb9c1817715245b65691f2f2e9e 100644 --- a/security/integrity/ima/ima.h +++ b/security/integrity/ima/ima.h @@ -55,8 +55,8 @@ extern bool ima_plus_standard_pcr; extern const char boot_aggregate_name[]; extern int ima_digest_list_actions; #ifdef CONFIG_IMA_DIGEST_LIST -extern size_t ima_digest_db_max_size __ro_after_init; -extern size_t ima_digest_db_size; +extern int ima_digest_db_max_size __ro_after_init; +extern int ima_digest_db_size; #endif /* IMA policy setup data */ diff --git a/security/integrity/ima/ima_digest_list.c b/security/integrity/ima/ima_digest_list.c index 3ffaffe8d064718afcb4ee09fc10bdd15bc754ed..5ed0c076895818dedaa40450447b2b017f868d7e 100644 --- a/security/integrity/ima/ima_digest_list.c +++ b/security/integrity/ima/ima_digest_list.c @@ -14,7 +14,6 @@ */ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt -#define MIN_DB_SIZE (8 * 1024 * 1024) #define MAX_DB_SIZE (64 * 1024 * 1024) #define DEFAULT_DB_SIZE (CONFIG_IMA_DIGEST_DB_MEGABYTES * 1024 * 1024) @@ -29,8 +28,8 @@ #include "ima.h" #include "ima_digest_list.h" -size_t ima_digest_db_max_size __ro_after_init = DEFAULT_DB_SIZE; -size_t ima_digest_db_size; +int ima_digest_db_max_size __ro_after_init = DEFAULT_DB_SIZE; +int ima_digest_db_size; struct ima_h_table ima_digests_htable = { .len = ATOMIC_LONG_INIT(0), @@ -43,12 +42,13 @@ static int __init digest_db_max_size_setup(char *str) char *retptr; size = memparse(str, &retptr); - if (size < MIN_DB_SIZE || size > MAX_DB_SIZE || *retptr != '\0') { - pr_err("DB size should range from 8M to 64M\n"); + if (size < 0 || size > MAX_DB_SIZE || *retptr != '\0') { + pr_err("digest DB size should range from 0M to 64M\n"); return 0; } ima_digest_db_max_size = size; + pr_info_once("parse reserve digest DB memory: %s\n", str); return 1; } @@ -121,6 +121,9 @@ static int ima_add_digest_data_entry(u8 *digest, enum hash_algo algo, if (d == NULL) return -ENOMEM; + ima_digest_db_size += sizeof(struct ima_digest); + ima_digest_db_size += digest_len; + d->algo = algo; d->type = type; d->modifiers = modifiers; @@ -144,6 +147,9 @@ static void ima_del_digest_data_entry(u8 *digest, enum hash_algo algo, if (--d->count > 0) return; + ima_digest_db_size -= sizeof(struct ima_digest); + ima_digest_db_size -= hash_digest_size[algo]; + hlist_del_rcu(&d->hnext); atomic_long_dec(&ima_digests_htable.len); kfree(d); @@ -361,6 +367,11 @@ static int __init load_digest_list(struct dir_context *__ctx, const char *name, size = ret; + if (size > ima_digest_db_max_size - ima_digest_db_size) { + pr_err_once("digest DB is full: %d\n", ima_digest_db_size); + goto out_fput; + } + ima_check_measured_appraised(file); ret = ima_parse_compact_list(size, datap, DIGEST_LIST_OP_ADD); diff --git a/security/integrity/ima/ima_fs.c b/security/integrity/ima/ima_fs.c index dd0b0f431a233fb1c6ea2f9de33372f1c4f62363..00cd8095d3461702bc997ff4efad7484a02cc364 100644 --- a/security/integrity/ima/ima_fs.c +++ b/security/integrity/ima/ima_fs.c @@ -380,12 +380,15 @@ static ssize_t ima_read_sfs_file(char *path, struct dentry *dentry, rc = ima_parse_add_rule(p, ima_ns); } else if (dentry == digest_list_data || dentry == digest_list_data_del) { +#ifdef CONFIG_IMA_DIGEST_LIST /* Only check size when adding digest lists */ if (dentry == digest_list_data && size > ima_digest_db_max_size - ima_digest_db_size) { + pr_err("digest DB is full: %d\n", ima_digest_db_size); rc = -ENOMEM; break; } +#endif /* * Disable usage of digest lists if not measured * or appraised. @@ -400,12 +403,13 @@ static ssize_t ima_read_sfs_file(char *path, struct dentry *dentry, if (rc < 0) break; +#ifdef CONFIG_IMA_DIGEST_LIST + else if (dentry == digest_list_data) + pr_debug("digest imported, current DB size: %d\n", ima_digest_db_size); + else if (dentry == digest_list_data_del) + pr_debug("digest deleted, current DB size: %d\n", ima_digest_db_size); +#endif size -= rc; - - if (dentry == digest_list_data) - ima_digest_db_size += rc; - if (dentry == digest_list_data_del) - ima_digest_db_size -= rc; } vfree(data);