@@ -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,
@@ -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);
}