From: Roberto Sassu roberto.sassu@huawei.com
hulk inclusion category: feature feature: digest-lists
---------------------------
IMA supports direct uploading of digest lists without specifying the path of the digest list. This feature allows software vendors to provide a digest list in an alternative format (e.g. RPM). A user space parser converts it to the native format and directly uploads it to the kernel.
This feature requires additional protection for the kernel, to ensure that digest lists are converted only by legitimate parsers and to ensure that any file accessed by the parser itself is measured and appraised.
The first protection is provided by ima_check_current_is_parser(), ima_set/unset_parser() and ima_current_is_parser(). The first function checks the digest of the executable of the process accessing the securityfs interface. The second and third set/unset the current process as the parser process and the last tells whether the current process is the parser process.
The second protection is provided by ima_check_measured_appraised(). If ima_current_is_parser() returns true, the current process is the parser process, it checks whether or not IMA evaluated the files accessed by that process and if not, disables digest list lookup.
Unfortunately, ima_set_parser() is called too late, during a write operation, while some files could have been already accessed by the parser. This patch moves ima_set_parser() to ima_open_data_upload() so that more files can be evaluated. A parser should be written in a way that the securityfs interface is opened first before any other file operation.
Signed-off-by: Roberto Sassu roberto.sassu@huawei.com Signed-off-by: Yang Yingliang yangyingliang@huawei.com --- security/integrity/ima/ima_fs.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-)
diff --git a/security/integrity/ima/ima_fs.c b/security/integrity/ima/ima_fs.c index a5f87fcdf731..2866a0967a1d 100644 --- a/security/integrity/ima/ima_fs.c +++ b/security/integrity/ima/ima_fs.c @@ -393,18 +393,16 @@ static ssize_t ima_write_data(struct file *file, const char __user *buf, result = ima_parse_add_rule(data); } } else if (dentry == digest_list_data) { - if (!ima_check_current_is_parser()) { + if (!ima_current_is_parser()) { result = -EACCES; } else { - ima_set_parser(); result = ima_parse_compact_list(datalen, data, DIGEST_LIST_OP_ADD); } } else if (dentry == digest_list_data_del) { - if (!ima_check_current_is_parser()) { + if (!ima_current_is_parser()) { result = -EACCES; } else { - ima_set_parser(); result = ima_parse_compact_list(datalen, data, DIGEST_LIST_OP_DEL); } @@ -479,6 +477,11 @@ static int ima_open_data_upload(struct inode *inode, struct file *filp) } if (test_and_set_bit(flag, &ima_fs_flags)) return -EBUSY; + + if (dentry == digest_list_data || dentry == digest_list_data_del) + if (ima_check_current_is_parser()) + ima_set_parser(); + return 0; }