hulk inclusion category: feature feature: digest-lists
---------------------------
The EVM ignore mode works similarly to the metadata modification mode. They both allow an operation to be performed even if the operation causes metadata to become invalid.
Currently, evm_reset_status() notifies to IMA that an operation modified metadata only when the metadata modification mode was chosen. With this patch, evm_reset_status() does the same also when the EVM ignore mode is selected.
Signed-off-by: Roberto Sassu roberto.sassu@huawei.com --- security/integrity/evm/evm_main.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/security/integrity/evm/evm_main.c b/security/integrity/evm/evm_main.c index 5155ff4c4ef2..2d3c1670d8d3 100644 --- a/security/integrity/evm/evm_main.c +++ b/security/integrity/evm/evm_main.c @@ -570,7 +570,8 @@ static void evm_reset_status(struct inode *inode, int bit)
iint = integrity_iint_find(inode); if (iint) { - if (evm_initialized & EVM_ALLOW_METADATA_WRITES) + if ((evm_initialized & EVM_ALLOW_METADATA_WRITES) || + evm_ignoremode) set_bit(bit, &iint->atomic_flags);
iint->evm_status = INTEGRITY_UNKNOWN;
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.
Since the parser process is already checked and set in ima_open_data_upload(), this patch also replaces ima_check_current_is_parser() with ima_current_is_parser() in ima_write_data() to check if the write is performed by the parser.
Signed-off-by: Roberto Sassu roberto.sassu@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; }