]> git.proxmox.com Git - mirror_ubuntu-jammy-kernel.git/commitdiff
fs,security: Add sb_delete hook
authorMickaël Salaün <mic@linux.microsoft.com>
Thu, 22 Apr 2021 15:41:16 +0000 (17:41 +0200)
committerJames Morris <jamorris@linux.microsoft.com>
Thu, 22 Apr 2021 19:22:11 +0000 (12:22 -0700)
The sb_delete security hook is called when shutting down a superblock,
which may be useful to release kernel objects tied to the superblock's
lifetime (e.g. inodes).

This new hook is needed by Landlock to release (ephemerally) tagged
struct inodes.  This comes from the unprivileged nature of Landlock
described in the next commit.

Cc: Al Viro <viro@zeniv.linux.org.uk>
Cc: James Morris <jmorris@namei.org>
Signed-off-by: Mickaël Salaün <mic@linux.microsoft.com>
Reviewed-by: Jann Horn <jannh@google.com>
Acked-by: Serge Hallyn <serge@hallyn.com>
Reviewed-by: Kees Cook <keescook@chromium.org>
Link: https://lore.kernel.org/r/20210422154123.13086-7-mic@digikod.net
Signed-off-by: James Morris <jamorris@linux.microsoft.com>
fs/super.c
include/linux/lsm_hook_defs.h
include/linux/lsm_hooks.h
include/linux/security.h
security/security.c

index 8c1baca35c160b08d5d2d474a95cc2cb5f181fd6..11b7e7213fd115b91f7c17cea52f1ba9a200056c 100644 (file)
@@ -454,6 +454,7 @@ void generic_shutdown_super(struct super_block *sb)
                evict_inodes(sb);
                /* only nonzero refcount inodes can have marks */
                fsnotify_sb_delete(sb);
+               security_sb_delete(sb);
 
                if (sb->s_dio_done_wq) {
                        destroy_workqueue(sb->s_dio_done_wq);
index 477a597db0130534b3b1c61b379e84d7e1f24c76..e8adadbf95814223d265290fca3078f9cf8f2020 100644 (file)
@@ -59,6 +59,7 @@ LSM_HOOK(int, 0, fs_context_dup, struct fs_context *fc,
 LSM_HOOK(int, -ENOPARAM, fs_context_parse_param, struct fs_context *fc,
         struct fs_parameter *param)
 LSM_HOOK(int, 0, sb_alloc_security, struct super_block *sb)
+LSM_HOOK(void, LSM_RET_VOID, sb_delete, struct super_block *sb)
 LSM_HOOK(void, LSM_RET_VOID, sb_free_security, struct super_block *sb)
 LSM_HOOK(void, LSM_RET_VOID, sb_free_mnt_opts, void *mnt_opts)
 LSM_HOOK(int, 0, sb_eat_lsm_opts, char *orig, void **mnt_opts)
index 75715998a95f1b9381b76b8e8835b6c4f8ff46ab..cc2eaaaec0e4ffd6388d79310435db4a3be9fd9e 100644 (file)
  *     allocated.
  *     @sb contains the super_block structure to be modified.
  *     Return 0 if operation was successful.
+ * @sb_delete:
+ *     Release objects tied to a superblock (e.g. inodes).
+ *     @sb contains the super_block structure being released.
  * @sb_free_security:
  *     Deallocate and clear the sb->s_security field.
  *     @sb contains the super_block structure to be modified.
index 8aeebd6646dcfcde1270a59fb8da7e04e2d15379..90298baa455147802fe71cb31f4ee6a6ffb544f7 100644 (file)
@@ -291,6 +291,7 @@ void security_bprm_committed_creds(struct linux_binprm *bprm);
 int security_fs_context_dup(struct fs_context *fc, struct fs_context *src_fc);
 int security_fs_context_parse_param(struct fs_context *fc, struct fs_parameter *param);
 int security_sb_alloc(struct super_block *sb);
+void security_sb_delete(struct super_block *sb);
 void security_sb_free(struct super_block *sb);
 void security_free_mnt_opts(void **mnt_opts);
 int security_sb_eat_lsm_opts(char *options, void **mnt_opts);
@@ -631,6 +632,9 @@ static inline int security_sb_alloc(struct super_block *sb)
        return 0;
 }
 
+static inline void security_sb_delete(struct super_block *sb)
+{ }
+
 static inline void security_sb_free(struct super_block *sb)
 { }
 
index e9c29480eb1822557eb950637e01ebdd3beda4e5..bb666f992497ede2bcfaabb110d3b268cbea45f4 100644 (file)
@@ -900,6 +900,11 @@ int security_sb_alloc(struct super_block *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);