提交 694330e9 编写于 作者: 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>
上级 30918aeb
...@@ -6432,7 +6432,6 @@ CONFIG_IMA_X509_PATH="/etc/keys/x509_ima.der" ...@@ -6432,7 +6432,6 @@ CONFIG_IMA_X509_PATH="/etc/keys/x509_ima.der"
# CONFIG_IMA_APPRAISE_SIGNED_INIT is not set # CONFIG_IMA_APPRAISE_SIGNED_INIT is not set
CONFIG_IMA_DIGEST_LIST=y CONFIG_IMA_DIGEST_LIST=y
CONFIG_IMA_DIGEST_LISTS_DIR="/etc/ima/digest_lists" 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_STANDARD_DIGEST_DB_SIZE=y
# CONFIG_IMA_MAX_DIGEST_DB_SIZE is not set # CONFIG_IMA_MAX_DIGEST_DB_SIZE is not set
# CONFIG_IMA_CUSTOM_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" ...@@ -7789,7 +7789,6 @@ CONFIG_IMA_X509_PATH="/etc/keys/x509_ima.der"
# CONFIG_IMA_APPRAISE_SIGNED_INIT is not set # CONFIG_IMA_APPRAISE_SIGNED_INIT is not set
CONFIG_IMA_DIGEST_LIST=y CONFIG_IMA_DIGEST_LIST=y
CONFIG_IMA_DIGEST_LISTS_DIR="/etc/ima/digest_lists" 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_STANDARD_DIGEST_DB_SIZE=y
# CONFIG_IMA_MAX_DIGEST_DB_SIZE is not set # CONFIG_IMA_MAX_DIGEST_DB_SIZE is not set
# CONFIG_IMA_CUSTOM_DIGEST_DB_SIZE is not set # CONFIG_IMA_CUSTOM_DIGEST_DB_SIZE is not set
......
...@@ -362,8 +362,6 @@ choice ...@@ -362,8 +362,6 @@ choice
database. The compiled default limit can be overwritten using the database. The compiled default limit can be overwritten using the
kernel command line "ima_digest_db_size". kernel command line "ima_digest_db_size".
config IMA_MIN_DIGEST_DB_SIZE
bool "minimum"
config IMA_STANDARD_DIGEST_DB_SIZE config IMA_STANDARD_DIGEST_DB_SIZE
bool "standard (default)" bool "standard (default)"
config IMA_MAX_DIGEST_DB_SIZE config IMA_MAX_DIGEST_DB_SIZE
...@@ -375,8 +373,7 @@ endchoice ...@@ -375,8 +373,7 @@ endchoice
config IMA_DIGEST_DB_MEGABYTES config IMA_DIGEST_DB_MEGABYTES
int int
depends on IMA_DIGEST_LIST depends on IMA_DIGEST_LIST
range 8 64 range 0 64
default 8 if IMA_MIN_DIGEST_DB_SIZE
default 16 if IMA_STANDARD_DIGEST_DB_SIZE default 16 if IMA_STANDARD_DIGEST_DB_SIZE
default 64 if IMA_MAX_DIGEST_DB_SIZE default 64 if IMA_MAX_DIGEST_DB_SIZE
......
...@@ -55,8 +55,8 @@ extern bool ima_plus_standard_pcr; ...@@ -55,8 +55,8 @@ extern bool ima_plus_standard_pcr;
extern const char boot_aggregate_name[]; extern const char boot_aggregate_name[];
extern int ima_digest_list_actions; extern int ima_digest_list_actions;
#ifdef CONFIG_IMA_DIGEST_LIST #ifdef CONFIG_IMA_DIGEST_LIST
extern size_t ima_digest_db_max_size __ro_after_init; extern int ima_digest_db_max_size __ro_after_init;
extern size_t ima_digest_db_size; extern int ima_digest_db_size;
#endif #endif
/* IMA policy setup data */ /* IMA policy setup data */
......
...@@ -14,7 +14,6 @@ ...@@ -14,7 +14,6 @@
*/ */
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#define MIN_DB_SIZE (8 * 1024 * 1024)
#define MAX_DB_SIZE (64 * 1024 * 1024) #define MAX_DB_SIZE (64 * 1024 * 1024)
#define DEFAULT_DB_SIZE (CONFIG_IMA_DIGEST_DB_MEGABYTES * 1024 * 1024) #define DEFAULT_DB_SIZE (CONFIG_IMA_DIGEST_DB_MEGABYTES * 1024 * 1024)
...@@ -29,8 +28,8 @@ ...@@ -29,8 +28,8 @@
#include "ima.h" #include "ima.h"
#include "ima_digest_list.h" #include "ima_digest_list.h"
size_t ima_digest_db_max_size __ro_after_init = DEFAULT_DB_SIZE; int ima_digest_db_max_size __ro_after_init = DEFAULT_DB_SIZE;
size_t ima_digest_db_size; int ima_digest_db_size;
struct ima_h_table ima_digests_htable = { struct ima_h_table ima_digests_htable = {
.len = ATOMIC_LONG_INIT(0), .len = ATOMIC_LONG_INIT(0),
...@@ -43,12 +42,13 @@ static int __init digest_db_max_size_setup(char *str) ...@@ -43,12 +42,13 @@ static int __init digest_db_max_size_setup(char *str)
char *retptr; char *retptr;
size = memparse(str, &retptr); size = memparse(str, &retptr);
if (size < MIN_DB_SIZE || size > MAX_DB_SIZE || *retptr != '\0') { if (size < 0 || size > MAX_DB_SIZE || *retptr != '\0') {
pr_err("DB size should range from 8M to 64M\n"); pr_err("digest DB size should range from 0M to 64M\n");
return 0; return 0;
} }
ima_digest_db_max_size = size; ima_digest_db_max_size = size;
pr_info_once("parse reserve digest DB memory: %s\n", str);
return 1; return 1;
} }
...@@ -121,6 +121,9 @@ static int ima_add_digest_data_entry(u8 *digest, enum hash_algo algo, ...@@ -121,6 +121,9 @@ static int ima_add_digest_data_entry(u8 *digest, enum hash_algo algo,
if (d == NULL) if (d == NULL)
return -ENOMEM; return -ENOMEM;
ima_digest_db_size += sizeof(struct ima_digest);
ima_digest_db_size += digest_len;
d->algo = algo; d->algo = algo;
d->type = type; d->type = type;
d->modifiers = modifiers; d->modifiers = modifiers;
...@@ -144,6 +147,9 @@ static void ima_del_digest_data_entry(u8 *digest, enum hash_algo algo, ...@@ -144,6 +147,9 @@ static void ima_del_digest_data_entry(u8 *digest, enum hash_algo algo,
if (--d->count > 0) if (--d->count > 0)
return; return;
ima_digest_db_size -= sizeof(struct ima_digest);
ima_digest_db_size -= hash_digest_size[algo];
hlist_del_rcu(&d->hnext); hlist_del_rcu(&d->hnext);
atomic_long_dec(&ima_digests_htable.len); atomic_long_dec(&ima_digests_htable.len);
kfree(d); kfree(d);
...@@ -361,6 +367,11 @@ static int __init load_digest_list(struct dir_context *__ctx, const char *name, ...@@ -361,6 +367,11 @@ static int __init load_digest_list(struct dir_context *__ctx, const char *name,
size = ret; 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); ima_check_measured_appraised(file);
ret = ima_parse_compact_list(size, datap, DIGEST_LIST_OP_ADD); 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, ...@@ -380,12 +380,15 @@ static ssize_t ima_read_sfs_file(char *path, struct dentry *dentry,
rc = ima_parse_add_rule(p, ima_ns); rc = ima_parse_add_rule(p, ima_ns);
} else if (dentry == digest_list_data || } else if (dentry == digest_list_data ||
dentry == digest_list_data_del) { dentry == digest_list_data_del) {
#ifdef CONFIG_IMA_DIGEST_LIST
/* Only check size when adding digest lists */ /* Only check size when adding digest lists */
if (dentry == digest_list_data && if (dentry == digest_list_data &&
size > ima_digest_db_max_size - ima_digest_db_size) { size > ima_digest_db_max_size - ima_digest_db_size) {
pr_err("digest DB is full: %d\n", ima_digest_db_size);
rc = -ENOMEM; rc = -ENOMEM;
break; break;
} }
#endif
/* /*
* Disable usage of digest lists if not measured * Disable usage of digest lists if not measured
* or appraised. * or appraised.
...@@ -400,12 +403,13 @@ static ssize_t ima_read_sfs_file(char *path, struct dentry *dentry, ...@@ -400,12 +403,13 @@ static ssize_t ima_read_sfs_file(char *path, struct dentry *dentry,
if (rc < 0) if (rc < 0)
break; 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; 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); vfree(data);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册