Merge tag 'rtc-5.13' of git://git.kernel.org/pub/scm/linux/kernel/git/abelloni/linux
[linux-2.6-microblaze.git] / security / security.c
index 94383f8..b38155b 100644 (file)
@@ -203,6 +203,7 @@ static void __init lsm_set_blob_sizes(struct lsm_blob_sizes *needed)
        lsm_set_blob_size(&needed->lbs_inode, &blob_sizes.lbs_inode);
        lsm_set_blob_size(&needed->lbs_ipc, &blob_sizes.lbs_ipc);
        lsm_set_blob_size(&needed->lbs_msg_msg, &blob_sizes.lbs_msg_msg);
+       lsm_set_blob_size(&needed->lbs_superblock, &blob_sizes.lbs_superblock);
        lsm_set_blob_size(&needed->lbs_task, &blob_sizes.lbs_task);
 }
 
@@ -333,12 +334,13 @@ static void __init ordered_lsm_init(void)
        for (lsm = ordered_lsms; *lsm; lsm++)
                prepare_lsm(*lsm);
 
-       init_debug("cred blob size     = %d\n", blob_sizes.lbs_cred);
-       init_debug("file blob size     = %d\n", blob_sizes.lbs_file);
-       init_debug("inode blob size    = %d\n", blob_sizes.lbs_inode);
-       init_debug("ipc blob size      = %d\n", blob_sizes.lbs_ipc);
-       init_debug("msg_msg blob size  = %d\n", blob_sizes.lbs_msg_msg);
-       init_debug("task blob size     = %d\n", blob_sizes.lbs_task);
+       init_debug("cred blob size       = %d\n", blob_sizes.lbs_cred);
+       init_debug("file blob size       = %d\n", blob_sizes.lbs_file);
+       init_debug("inode blob size      = %d\n", blob_sizes.lbs_inode);
+       init_debug("ipc blob size        = %d\n", blob_sizes.lbs_ipc);
+       init_debug("msg_msg blob size    = %d\n", blob_sizes.lbs_msg_msg);
+       init_debug("superblock blob size = %d\n", blob_sizes.lbs_superblock);
+       init_debug("task blob size       = %d\n", blob_sizes.lbs_task);
 
        /*
         * Create any kmem_caches needed for blobs
@@ -670,6 +672,27 @@ static void __init lsm_early_task(struct task_struct *task)
                panic("%s: Early task alloc failed.\n", __func__);
 }
 
+/**
+ * lsm_superblock_alloc - allocate a composite superblock blob
+ * @sb: the superblock that needs a blob
+ *
+ * Allocate the superblock blob for all the modules
+ *
+ * Returns 0, or -ENOMEM if memory can't be allocated.
+ */
+static int lsm_superblock_alloc(struct super_block *sb)
+{
+       if (blob_sizes.lbs_superblock == 0) {
+               sb->s_security = NULL;
+               return 0;
+       }
+
+       sb->s_security = kzalloc(blob_sizes.lbs_superblock, GFP_KERNEL);
+       if (sb->s_security == NULL)
+               return -ENOMEM;
+       return 0;
+}
+
 /*
  * The default value of the LSM hook is defined in linux/lsm_hook_defs.h and
  * can be accessed with:
@@ -867,12 +890,26 @@ int security_fs_context_parse_param(struct fs_context *fc, struct fs_parameter *
 
 int security_sb_alloc(struct super_block *sb)
 {
-       return call_int_hook(sb_alloc_security, 0, sb);
+       int rc = lsm_superblock_alloc(sb);
+
+       if (unlikely(rc))
+               return rc;
+       rc = call_int_hook(sb_alloc_security, 0, sb);
+       if (unlikely(rc))
+               security_sb_free(sb);
+       return rc;
+}
+
+void security_sb_delete(struct super_block *sb)
+{
+       call_void_hook(sb_delete, sb);
 }
 
 void security_sb_free(struct super_block *sb)
 {
        call_void_hook(sb_free_security, sb);
+       kfree(sb->s_security);
+       sb->s_security = NULL;
 }
 
 void security_free_mnt_opts(void **mnt_opts)