Re: [PATCH v22 05/12] LSM: Infrastructure management of the superblock

2020-10-28 Thread James Morris
On Tue, 27 Oct 2020, Mickaël Salaün wrote:

> From: Casey Schaufler 
> 
> Move management of the superblock->sb_security blob out of the
> individual security modules and into the security infrastructure.
> Instead of allocating the blobs from within the modules, the modules
> tell the infrastructure how much space is required, and the space is
> allocated there.
> 
> Cc: Kees Cook 
> Cc: John Johansen 
> Signed-off-by: Casey Schaufler 
> Signed-off-by: Mickaël Salaün 
> Reviewed-by: Stephen Smalley 

It would be good to see review from JJ here.

-- 
James Morris



[PATCH v22 05/12] LSM: Infrastructure management of the superblock

2020-10-27 Thread Mickaël Salaün
From: Casey Schaufler 

Move management of the superblock->sb_security blob out of the
individual security modules and into the security infrastructure.
Instead of allocating the blobs from within the modules, the modules
tell the infrastructure how much space is required, and the space is
allocated there.

Cc: Kees Cook 
Cc: John Johansen 
Signed-off-by: Casey Schaufler 
Signed-off-by: Mickaël Salaün 
Reviewed-by: Stephen Smalley 
---

Changes since v20:
* Remove all Reviewed-by except Stephen Smalley:
  
https://lore.kernel.org/lkml/CAEjxPJ7ARJO57MBW66=xsBzMMRb=9ulgqock5eskhcaivmx...@mail.gmail.com/
* Cosmetic fix in the commit message.

Changes since v17:
* Rebase the original LSM stacking patch from v5.3 to v5.7: I fixed some
  diff conflicts caused by code moves and function renames in
  selinux/include/objsec.h and selinux/hooks.c .  I checked that it
  builds but I didn't test the changes for SELinux nor SMACK.
  https://lore.kernel.org/r/20190829232935.7099-2-ca...@schaufler-ca.com
---
 include/linux/lsm_hooks.h |  1 +
 security/security.c   | 46 
 security/selinux/hooks.c  | 58 ---
 security/selinux/include/objsec.h |  6 
 security/selinux/ss/services.c|  3 +-
 security/smack/smack.h|  6 
 security/smack/smack_lsm.c| 35 +--
 7 files changed, 85 insertions(+), 70 deletions(-)

diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h
index c503f7ab8afb..ff0f03a45c56 100644
--- a/include/linux/lsm_hooks.h
+++ b/include/linux/lsm_hooks.h
@@ -1563,6 +1563,7 @@ struct lsm_blob_sizes {
int lbs_cred;
int lbs_file;
int lbs_inode;
+   int lbs_superblock;
int lbs_ipc;
int lbs_msg_msg;
int lbs_task;
diff --git a/security/security.c b/security/security.c
index a28045dc9e7f..4ffd6c3af9d7 100644
--- a/security/security.c
+++ b/security/security.c
@@ -202,6 +202,7 @@ static void __init lsm_set_blob_sizes(struct lsm_blob_sizes 
*needed)
lsm_set_blob_size(>lbs_inode, _sizes.lbs_inode);
lsm_set_blob_size(>lbs_ipc, _sizes.lbs_ipc);
lsm_set_blob_size(>lbs_msg_msg, _sizes.lbs_msg_msg);
+   lsm_set_blob_size(>lbs_superblock, _sizes.lbs_superblock);
lsm_set_blob_size(>lbs_task, _sizes.lbs_task);
 }
 
@@ -332,12 +333,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
@@ -669,6 +671,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:
@@ -866,12 +889,21 @@ 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_free(struct super_block *sb)
 {
call_void_hook(sb_free_security, sb);
+   kfree(sb->s_security);
+   sb->s_security = NULL;
 }
 
 void