提交 b2cf80eb 编写于 作者: Z Zhang Tianxing 提交者: Zheng Zengkai

ima: fix db size overflow and Kconfig issues

hulk inclusion
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/I4BMOM
CVE: NA

-----------------------------------------------------------------

This patch fixes some issues involved with IMA digest db size patches:
- use CONFIG_IMA_DIGEST_LIST to seperate db size check in ima_fs.c
- remove minimum digest db size limit in Kconfig
- change ima_digest_db_size data type from size_t to int, to avoid
  overflow
- change ima_digest_db_size in ima_add_digest_data_entry and
  ima_del_digest_data_entry
- add some debug messages

Fixes: 7c9d18bc ("ima: Add max size for IMA digest database")
Signed-off-by: NZhang Tianxing <zhangtianxing3@huawei.com>
Reviewed-by: Nzhujianwei <zhujianwei7@huawei.com>
Signed-off-by: NZheng Zengkai <zhengzengkai@huawei.com>
上级 1e093364
......@@ -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
......
......@@ -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
......
......@@ -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
......
......@@ -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 */
......
......@@ -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);
......
......@@ -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);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册