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> --- include/linux/ima.h | 9 +++++++++ security/integrity/ima/ima_main.c | 29 +++++++++++++++++++++++++---- 2 files changed, 34 insertions(+), 4 deletions(-) diff --git a/include/linux/ima.h b/include/linux/ima.h index 85903f40acfd..fda371cbde50 100644 --- a/include/linux/ima.h +++ b/include/linux/ima.h @@ -66,6 +66,15 @@ static inline const char * const *arch_get_ima_policy(void) } #endif +static inline struct user_namespace *ima_user_ns(struct ima_namespace *ns) +{ + struct user_namespace *user_ns; + + user_ns = current_user_ns(); + WARN_ON(user_ns->ima_ns != ns); + return user_ns; +} + #else static inline enum hash_algo ima_get_current_hash_algo(void) { diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c index 2121a831f38a..6ebc57cd91d3 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) +{ + struct user_namespace *user_ns = ima_user_ns(ns); + int ret = 0; + + while (user_ns) { + ns = user_ns->ima_ns; + + ret = __process_measurement(ns, file, cred, secid, buf, size, mask, func); + if (ret) + break; + + user_ns = user_ns->parent; + }; + + 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