Implement hierarchical processing of file accesses in IMA namespaces by walking the list of IMA namespaces towards the init_ima_ns. This way file accesses can be audited in an IMA namespace and also be evaluated against the IMA policies of parent IMA namespaces. Signed-off-by: Stefan Berger <stefanb@xxxxxxxxxxxxx> --- security/integrity/ima/ima_main.c | 29 +++++++++++++++++++++++++---- 1 file changed, 25 insertions(+), 4 deletions(-) diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c index 2121a831f38a..e9fa46eedd27 100644 --- a/security/integrity/ima/ima_main.c +++ b/security/integrity/ima/ima_main.c @@ -200,10 +200,10 @@ void ima_file_free(struct file *file) ima_check_last_writer(iint, inode, file); } -static int process_measurement(struct ima_namespace *ns, - struct file *file, const struct cred *cred, - u32 secid, char *buf, loff_t size, int mask, - enum ima_hooks func) +static int _process_measurement(struct ima_namespace *ns, + struct file *file, const struct cred *cred, + u32 secid, char *buf, loff_t size, int mask, + enum ima_hooks func) { struct inode *inode = file_inode(file); struct integrity_iint_cache *iint = NULL; @@ -405,6 +405,27 @@ static int process_measurement(struct ima_namespace *ns, return 0; } +static int process_measurement(struct ima_namespace *ns, + struct file *file, const struct cred *cred, + u32 secid, char *buf, loff_t size, int mask, + enum ima_hooks func) +{ + int ret = 0; + struct user_namespace *user_ns; + + do { + ret = _process_measurement(ns, file, cred, secid, buf, size, mask, func); + if (ret) + break; + user_ns = ns->user_ns->parent; + if (!user_ns) + break; + ns = user_ns->ima_ns; + } while (1); + + return ret; +} + /** * ima_file_mmap - based on policy, collect/store measurement. * @file: pointer to the file to be measured (May be NULL) -- 2.31.1