From: Roberto Sassu <roberto.sassu@xxxxxxxxxx> In preparation for moving IMA and EVM to the LSM infrastructure, introduce the file_pre_free_security 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. LSMs could also take some action before the last reference of a file is released. The new hook cannot return an error and cannot cause the operation to be reverted. Signed-off-by: Roberto Sassu <roberto.sassu@xxxxxxxxxx> --- fs/file_table.c | 1 + include/linux/lsm_hook_defs.h | 1 + include/linux/security.h | 4 ++++ security/security.c | 11 +++++++++++ 4 files changed, 17 insertions(+) diff --git a/fs/file_table.c b/fs/file_table.c index ee21b3da9d08..ca36679adaa4 100644 --- a/fs/file_table.c +++ b/fs/file_table.c @@ -375,6 +375,7 @@ static void __fput(struct file *file) eventpoll_release(file); locks_remove_file(file); + security_file_pre_free(file); ima_file_free(file); if (unlikely(file->f_flags & FASYNC)) { if (file->f_op->fasync) diff --git a/include/linux/lsm_hook_defs.h b/include/linux/lsm_hook_defs.h index cab9c1265f4e..21da4cadcad3 100644 --- a/include/linux/lsm_hook_defs.h +++ b/include/linux/lsm_hook_defs.h @@ -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_pre_free_security, 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) diff --git a/include/linux/security.h b/include/linux/security.h index e0812da7f24d..47c3502d8600 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -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_pre_free(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_mmap_file(struct file *file, unsigned long prot, @@ -1006,6 +1007,9 @@ static inline int security_file_alloc(struct file *file) return 0; } +static inline void security_file_pre_free(struct file *file) +{ } + static inline void security_file_free(struct file *file) { } diff --git a/security/security.c b/security/security.c index d24a8f92d641..e3586a37d62c 100644 --- a/security/security.c +++ b/security/security.c @@ -2717,6 +2717,17 @@ int security_file_alloc(struct file *file) return rc; } +/** + * security_file_pre_free() - Perform actions before releasing the file ref + * @file: the file + * + * Perform actions before releasing the last reference to a file. + */ +void security_file_pre_free(struct file *file) +{ + call_void_hook(file_pre_free_security, file); +} + /** * security_file_free() - Free a file's LSM blob * @file: the file -- 2.34.1