diff mbox series

[v3,17/25] security: Introduce inode_post_create_tmpfile hook

Message ID 20230904133415.1799503-18-roberto.sassu@huaweicloud.com (mailing list archive)
State Superseded
Delegated to: Paul Moore
Headers show
Series security: Move IMA and EVM to the LSM infrastructure | expand

Commit Message

Roberto Sassu Sept. 4, 2023, 1:34 p.m. UTC
From: Roberto Sassu <roberto.sassu@huawei.com>

In preparation for moving IMA and EVM to the LSM infrastructure, introduce
the inode_post_create_tmpfile hook.

It is useful for IMA to mark new temp files as successfully appraised and
let them be subsequently opened for further modification.

LSMs can benefit from this hook to update the inode state after a temp file
has been successfully created. The new hook cannot return an error and
cannot cause the operation to be canceled.

Signed-off-by: Roberto Sassu <roberto.sassu@huawei.com>
---
 fs/namei.c                    |  1 +
 include/linux/lsm_hook_defs.h |  2 ++
 include/linux/security.h      |  8 ++++++++
 security/security.c           | 18 ++++++++++++++++++
 4 files changed, 29 insertions(+)

Comments

Stefan Berger Sept. 5, 2023, 6:52 p.m. UTC | #1
On 9/4/23 09:34, Roberto Sassu wrote:
> From: Roberto Sassu <roberto.sassu@huawei.com>
>
> In preparation for moving IMA and EVM to the LSM infrastructure, introduce
> the inode_post_create_tmpfile hook.
>
> It is useful for IMA to mark new temp files as successfully appraised and
> let them be subsequently opened for further modification.
>
> LSMs can benefit from this hook to update the inode state after a temp file
> has been successfully created. The new hook cannot return an error and
> cannot cause the operation to be canceled.
>
> Signed-off-by: Roberto Sassu <roberto.sassu@huawei.com>
> ---
>   fs/namei.c                    |  1 +
>   include/linux/lsm_hook_defs.h |  2 ++
>   include/linux/security.h      |  8 ++++++++
>   security/security.c           | 18 ++++++++++++++++++
>   4 files changed, 29 insertions(+)
>
> diff --git a/fs/namei.c b/fs/namei.c
> index c8c4ab26b52a..efed0e1e93f5 100644
> --- a/fs/namei.c
> +++ b/fs/namei.c
> @@ -3700,6 +3700,7 @@ static int vfs_tmpfile(struct mnt_idmap *idmap,
>   		inode->i_state |= I_LINKABLE;
>   		spin_unlock(&inode->i_lock);
>   	}
> +	security_inode_post_create_tmpfile(idmap, dir, file, mode);
>   	ima_post_create_tmpfile(idmap, dir, file, mode);
>   	return 0;
>   }
> diff --git a/include/linux/lsm_hook_defs.h b/include/linux/lsm_hook_defs.h
> index b1634b5de98c..9ae573b83737 100644
> --- a/include/linux/lsm_hook_defs.h
> +++ b/include/linux/lsm_hook_defs.h
> @@ -121,6 +121,8 @@ LSM_HOOK(int, 0, inode_init_security_anon, struct inode *inode,
>   	 const struct qstr *name, const struct inode *context_inode)
>   LSM_HOOK(int, 0, inode_create, struct inode *dir, struct dentry *dentry,
>   	 umode_t mode)
> +LSM_HOOK(void, LSM_RET_VOID, inode_post_create_tmpfile, struct mnt_idmap *idmap,
> +	 struct inode *dir, struct file *file, umode_t mode)
>   LSM_HOOK(int, 0, inode_link, struct dentry *old_dentry, struct inode *dir,
>   	 struct dentry *new_dentry)
>   LSM_HOOK(int, 0, inode_unlink, struct inode *dir, struct dentry *dentry)
> diff --git a/include/linux/security.h b/include/linux/security.h
> index f210bd66e939..5f296761883f 100644
> --- a/include/linux/security.h
> +++ b/include/linux/security.h
> @@ -338,6 +338,9 @@ int security_inode_init_security_anon(struct inode *inode,
>   				      const struct qstr *name,
>   				      const struct inode *context_inode);
>   int security_inode_create(struct inode *dir, struct dentry *dentry, umode_t mode);
> +void security_inode_post_create_tmpfile(struct mnt_idmap *idmap,
> +					struct inode *dir, struct file *file,
> +					umode_t mode);
>   int security_inode_link(struct dentry *old_dentry, struct inode *dir,
>   			 struct dentry *new_dentry);
>   int security_inode_unlink(struct inode *dir, struct dentry *dentry);
> @@ -788,6 +791,11 @@ static inline int security_inode_create(struct inode *dir,
>   	return 0;
>   }
>   
> +static inline void
> +security_inode_post_create_tmpfile(struct mnt_idmap *idmap, struct inode *dir,
> +				   struct file *file, umode_t mode)
> +{ }
> +
>   static inline int security_inode_link(struct dentry *old_dentry,
>   				       struct inode *dir,
>   				       struct dentry *new_dentry)
> diff --git a/security/security.c b/security/security.c
> index 78aeb24efedb..aa6274c90147 100644
> --- a/security/security.c
> +++ b/security/security.c
> @@ -1920,6 +1920,24 @@ int security_inode_create(struct inode *dir, struct dentry *dentry,
>   }
>   EXPORT_SYMBOL_GPL(security_inode_create);
>   
> +/**
> + * security_inode_post_create_tmpfile() - Update inode security field after creation of tmpfile
> + * @idmap: idmap of the mount
> + * @dir: the inode of the base directory
> + * @file: file descriptor of the new tmpfile
> + * @mode: the mode of the new tmpfile
> + *
> + * Update inode security field after a tmpfile has been created.
> + */
> +void security_inode_post_create_tmpfile(struct mnt_idmap *idmap,
> +					struct inode *dir,
> +					struct file *file, umode_t mode)
> +{
> +	if (unlikely(IS_PRIVATE(dir)))
> +		return;
> +	call_void_hook(inode_post_create_tmpfile, idmap, dir, file, mode);
> +}
> +
>   /**
>    * security_inode_link() - Check if creating a hard link is allowed
>    * @old_dentry: existing file


Reviewed-by: Stefan Berger <stefanb@linux.ibm.com>
Mimi Zohar Oct. 13, 2023, 1:18 p.m. UTC | #2
On Mon, 2023-09-04 at 15:34 +0200, Roberto Sassu wrote:
> From: Roberto Sassu <roberto.sassu@huawei.com>
> 
> In preparation for moving IMA and EVM to the LSM infrastructure, introduce
> the inode_post_create_tmpfile hook.
> 
> It is useful for IMA to mark new temp files as successfully appraised and
> let them be subsequently opened for further modification.

As tmp files can be made persistent, treat new tmp files like other new
files, so that the file hash is calculated and stored in the security
xattr.
diff mbox series

Patch

diff --git a/fs/namei.c b/fs/namei.c
index c8c4ab26b52a..efed0e1e93f5 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -3700,6 +3700,7 @@  static int vfs_tmpfile(struct mnt_idmap *idmap,
 		inode->i_state |= I_LINKABLE;
 		spin_unlock(&inode->i_lock);
 	}
+	security_inode_post_create_tmpfile(idmap, dir, file, mode);
 	ima_post_create_tmpfile(idmap, dir, file, mode);
 	return 0;
 }
diff --git a/include/linux/lsm_hook_defs.h b/include/linux/lsm_hook_defs.h
index b1634b5de98c..9ae573b83737 100644
--- a/include/linux/lsm_hook_defs.h
+++ b/include/linux/lsm_hook_defs.h
@@ -121,6 +121,8 @@  LSM_HOOK(int, 0, inode_init_security_anon, struct inode *inode,
 	 const struct qstr *name, const struct inode *context_inode)
 LSM_HOOK(int, 0, inode_create, struct inode *dir, struct dentry *dentry,
 	 umode_t mode)
+LSM_HOOK(void, LSM_RET_VOID, inode_post_create_tmpfile, struct mnt_idmap *idmap,
+	 struct inode *dir, struct file *file, umode_t mode)
 LSM_HOOK(int, 0, inode_link, struct dentry *old_dentry, struct inode *dir,
 	 struct dentry *new_dentry)
 LSM_HOOK(int, 0, inode_unlink, struct inode *dir, struct dentry *dentry)
diff --git a/include/linux/security.h b/include/linux/security.h
index f210bd66e939..5f296761883f 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -338,6 +338,9 @@  int security_inode_init_security_anon(struct inode *inode,
 				      const struct qstr *name,
 				      const struct inode *context_inode);
 int security_inode_create(struct inode *dir, struct dentry *dentry, umode_t mode);
+void security_inode_post_create_tmpfile(struct mnt_idmap *idmap,
+					struct inode *dir, struct file *file,
+					umode_t mode);
 int security_inode_link(struct dentry *old_dentry, struct inode *dir,
 			 struct dentry *new_dentry);
 int security_inode_unlink(struct inode *dir, struct dentry *dentry);
@@ -788,6 +791,11 @@  static inline int security_inode_create(struct inode *dir,
 	return 0;
 }
 
+static inline void
+security_inode_post_create_tmpfile(struct mnt_idmap *idmap, struct inode *dir,
+				   struct file *file, umode_t mode)
+{ }
+
 static inline int security_inode_link(struct dentry *old_dentry,
 				       struct inode *dir,
 				       struct dentry *new_dentry)
diff --git a/security/security.c b/security/security.c
index 78aeb24efedb..aa6274c90147 100644
--- a/security/security.c
+++ b/security/security.c
@@ -1920,6 +1920,24 @@  int security_inode_create(struct inode *dir, struct dentry *dentry,
 }
 EXPORT_SYMBOL_GPL(security_inode_create);
 
+/**
+ * security_inode_post_create_tmpfile() - Update inode security field after creation of tmpfile
+ * @idmap: idmap of the mount
+ * @dir: the inode of the base directory
+ * @file: file descriptor of the new tmpfile
+ * @mode: the mode of the new tmpfile
+ *
+ * Update inode security field after a tmpfile has been created.
+ */
+void security_inode_post_create_tmpfile(struct mnt_idmap *idmap,
+					struct inode *dir,
+					struct file *file, umode_t mode)
+{
+	if (unlikely(IS_PRIVATE(dir)))
+		return;
+	call_void_hook(inode_post_create_tmpfile, idmap, dir, file, mode);
+}
+
 /**
  * security_inode_link() - Check if creating a hard link is allowed
  * @old_dentry: existing file