security: Introduce file_release hook
authorRoberto Sassu <roberto.sassu@huawei.com>
Thu, 15 Feb 2024 10:31:01 +0000 (11:31 +0100)
committerPaul Moore <paul@paul-moore.com>
Fri, 16 Feb 2024 04:43:43 +0000 (23:43 -0500)
In preparation for moving IMA and EVM to the LSM infrastructure, introduce
the file_release hook.

IMA calculates at file close the new digest of the file content and writes
it to security.ima, so that appraisal at next file access succeeds.

The new hook cannot return an error and cannot cause the operation to be
reverted.

Signed-off-by: Roberto Sassu <roberto.sassu@huawei.com>
Acked-by: Christian Brauner <brauner@kernel.org>
Reviewed-by: Stefan Berger <stefanb@linux.ibm.com>
Reviewed-by: Mimi Zohar <zohar@linux.ibm.com>
Signed-off-by: Paul Moore <paul@paul-moore.com>
fs/file_table.c
include/linux/lsm_hook_defs.h
include/linux/security.h
security/security.c

index b991f90571b4d3089a0c00884fea3e38f317b1da..725407f374faf82d8109ea3b7e84c3a5b9c130a5 100644 (file)
@@ -367,6 +367,7 @@ static void __fput(struct file *file)
        eventpoll_release(file);
        locks_remove_file(file);
 
+       security_file_release(file);
        ima_file_free(file);
        if (unlikely(file->f_flags & FASYNC)) {
                if (file->f_op->fasync)
index 3c84942d28186b7271c2d368830105cfd1b6ed4c..7f9e9240606edf5ed690f31dcc22e4ff233e0ace 100644 (file)
@@ -173,6 +173,7 @@ LSM_HOOK(int, 0, kernfs_init_security, struct kernfs_node *kn_dir,
         struct kernfs_node *kn)
 LSM_HOOK(int, 0, file_permission, struct file *file, int mask)
 LSM_HOOK(int, 0, file_alloc_security, struct file *file)
+LSM_HOOK(void, LSM_RET_VOID, file_release, struct file *file)
 LSM_HOOK(void, LSM_RET_VOID, file_free_security, struct file *file)
 LSM_HOOK(int, 0, file_ioctl, struct file *file, unsigned int cmd,
         unsigned long arg)
index 97f2212c13b601f940ff985686b24cb89f441911..2997348afcb7068daec5d3786946e34328779909 100644 (file)
@@ -395,6 +395,7 @@ int security_kernfs_init_security(struct kernfs_node *kn_dir,
                                  struct kernfs_node *kn);
 int security_file_permission(struct file *file, int mask);
 int security_file_alloc(struct file *file);
+void security_file_release(struct file *file);
 void security_file_free(struct file *file);
 int security_file_ioctl(struct file *file, unsigned int cmd, unsigned long arg);
 int security_file_ioctl_compat(struct file *file, unsigned int cmd,
@@ -1008,6 +1009,9 @@ static inline int security_file_alloc(struct file *file)
        return 0;
 }
 
+static inline void security_file_release(struct file *file)
+{ }
+
 static inline void security_file_free(struct file *file)
 { }
 
index 207405a84902f47155ee8c243dfb54aeff9a32f2..99004c44ce551fd8cda947b1984414b8cb1ca062 100644 (file)
@@ -2718,6 +2718,17 @@ int security_file_alloc(struct file *file)
        return rc;
 }
 
+/**
+ * security_file_release() - Perform actions before releasing the file ref
+ * @file: the file
+ *
+ * Perform actions before releasing the last reference to a file.
+ */
+void security_file_release(struct file *file)
+{
+       call_void_hook(file_release, file);
+}
+
 /**
  * security_file_free() - Free a file's LSM blob
  * @file: the file