Setup securityfs with symlinks, directories, and files for IMA namespacing support. The same directory structure that IMA uses on the host is also created for the namespacing case. The securityfs file and directory ownerships cannot be set when the IMA namespace is initialized. Therefore, delay the setup of the file system to a later point when securityfs initializes the fs_context. Use securityfs_register_ns_notifier() to register a notifier for populating the filsystem late. This filesystem can now be mounted as follows: mount -t securityfs /sys/kernel/security/ /sys/kernel/security/ The following directories, symlinks, and files are then available. $ ls -l sys/kernel/security/ total 0 lr--r--r--. 1 root root 0 Dec 2 00:18 ima -> integrity/ima drwxr-xr-x. 3 root root 0 Dec 2 00:18 integrity $ ls -l sys/kernel/security/ima/ total 0 -r--r-----. 1 root root 0 Dec 2 00:18 ascii_runtime_measurements -r--r-----. 1 root root 0 Dec 2 00:18 binary_runtime_measurements -rw-------. 1 root root 0 Dec 2 00:18 policy -r--r-----. 1 root root 0 Dec 2 00:18 runtime_measurements_count -r--r-----. 1 root root 0 Dec 2 00:18 violations Signed-off-by: Stefan Berger <stefanb@xxxxxxxxxxxxx> Signed-off-by: James Bottomley <James.Bottomley@xxxxxxxxxxxxxxxxxxxxx> --- include/linux/ima.h | 3 ++- security/integrity/ima/ima_fs.c | 46 ++++++++++++++++++++++++++++++--- 2 files changed, 45 insertions(+), 4 deletions(-) diff --git a/include/linux/ima.h b/include/linux/ima.h index bfb978a7f8d5..cab5fc6caeb3 100644 --- a/include/linux/ima.h +++ b/include/linux/ima.h @@ -221,7 +221,8 @@ struct ima_h_table { }; enum { - IMAFS_DENTRY_DIR = 0, + IMAFS_DENTRY_INTEGRITY_DIR = 0, + IMAFS_DENTRY_DIR, IMAFS_DENTRY_SYMLINK, IMAFS_DENTRY_BINARY_RUNTIME_MEASUREMENTS, IMAFS_DENTRY_ASCII_RUNTIME_MEASUREMENTS, diff --git a/security/integrity/ima/ima_fs.c b/security/integrity/ima/ima_fs.c index c2a886c00ac2..c17a6b7eeb95 100644 --- a/security/integrity/ima/ima_fs.c +++ b/security/integrity/ima/ima_fs.c @@ -456,12 +456,25 @@ static void ima_fs_ns_free_dentries(struct ima_namespace *ns) memset(ns->dentry, 0, sizeof(ns->dentry)); } -static int __init ima_fs_ns_init(struct user_namespace *user_ns) +static int ima_fs_ns_init(struct user_namespace *user_ns) { struct ima_namespace *ns = user_ns->ima_ns; struct dentry *ima_dir; - ns->dentry[IMAFS_DENTRY_DIR] = securityfs_create_dir("ima", integrity_dir); + /* already initialized? */ + if (ns->dentry[IMAFS_DENTRY_INTEGRITY_DIR]) + return 0; + + /* FIXME: update when evm and integrity are namespaced */ + if (user_ns != &init_user_ns) + ns->dentry[IMAFS_DENTRY_INTEGRITY_DIR] = + securityfs_create_dir("integrity", NULL); + else + ns->dentry[IMAFS_DENTRY_INTEGRITY_DIR] = integrity_dir; + + ns->dentry[IMAFS_DENTRY_DIR] = + securityfs_create_dir("ima", + ns->dentry[IMAFS_DENTRY_INTEGRITY_DIR]); if (IS_ERR(ns->dentry[IMAFS_DENTRY_DIR])) return -1; ima_dir = ns->dentry[IMAFS_DENTRY_DIR]; @@ -511,7 +524,34 @@ static int __init ima_fs_ns_init(struct user_namespace *user_ns) return -1; } -int __init ima_fs_init(void) +static int ima_ns_notify(struct notifier_block *this, unsigned long msg, + void *data) { + int rc = 0; + struct user_namespace *user_ns = data; + + switch (msg) { + case SECURITYFS_NS_ADD: + rc = ima_fs_ns_init(user_ns); + break; + case SECURITYFS_NS_REMOVE: + ima_fs_ns_free_dentries(user_ns->ima_ns); + break; + } + return rc; +} + +static struct notifier_block ima_ns_notifier = { + .notifier_call = ima_ns_notify, +}; + +int ima_fs_init() +{ + int rc; + + rc = securityfs_register_ns_notifier(&ima_ns_notifier); + if (rc) + return rc; + return ima_fs_ns_init(&init_user_ns); } -- 2.31.1