[v9,15/25] security: Introduce inode_post_create_tmpfile hook

Message ID 20240115181809.885385-16-roberto.sassu@huaweicloud.com
State New
Headers
Series security: Move IMA and EVM to the LSM infrastructure |

Commit Message

Roberto Sassu Jan. 15, 2024, 6:17 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.

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

LSMs could also take some action after temp files have been 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>
Acked-by: Casey Schaufler <casey@schaufler-ca.com>
Reviewed-by: Mimi Zohar <zohar@linux.ibm.com>
---
 fs/namei.c                    |  1 +
 include/linux/lsm_hook_defs.h |  2 ++
 include/linux/security.h      |  6 ++++++
 security/security.c           | 15 +++++++++++++++
 4 files changed, 24 insertions(+)
  

Comments

Paul Moore Feb. 8, 2024, 3:18 a.m. UTC | #1
On Jan 15, 2024 Roberto Sassu <roberto.sassu@huaweicloud.com> wrote:
> 
> In preparation for moving IMA and EVM to the LSM infrastructure, introduce
> the inode_post_create_tmpfile hook.
> 
> As temp files can be made persistent, treat new temp files like other new
> files, so that the file hash is calculated and stored in the security
> xattr.
> 
> LSMs could also take some action after temp files have been 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>
> Acked-by: Casey Schaufler <casey@schaufler-ca.com>
> Reviewed-by: Mimi Zohar <zohar@linux.ibm.com>
> ---
>  fs/namei.c                    |  1 +
>  include/linux/lsm_hook_defs.h |  2 ++
>  include/linux/security.h      |  6 ++++++
>  security/security.c           | 15 +++++++++++++++
>  4 files changed, 24 insertions(+)

Acked-by: Paul Moore <paul@paul-moore.com>

--
paul-moore.com
  
Christian Brauner Feb. 9, 2024, 9:53 a.m. UTC | #2
On Mon, Jan 15, 2024 at 07:17:59PM +0100, 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.
> 
> As temp files can be made persistent, treat new temp files like other new
> files, so that the file hash is calculated and stored in the security
> xattr.
> 
> LSMs could also take some action after temp files have been 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>
> Acked-by: Casey Schaufler <casey@schaufler-ca.com>
> Reviewed-by: Mimi Zohar <zohar@linux.ibm.com>
> ---
>  fs/namei.c                    |  1 +

Acked-by: Christian Brauner <brauner@kernel.org>
  
Stefan Berger Feb. 12, 2024, 5:26 p.m. UTC | #3
On 1/15/24 13:17, 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.
> 
> As temp files can be made persistent, treat new temp files like other new
> files, so that the file hash is calculated and stored in the security
> xattr.
> 
> LSMs could also take some action after temp files have been 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>
> Acked-by: Casey Schaufler <casey@schaufler-ca.com>
> Reviewed-by: Mimi Zohar <zohar@linux.ibm.com>

Reviewed-by: Stefan Berger <stefanb@linux.ibm.com>

> ---
>   fs/namei.c                    |  1 +
>   include/linux/lsm_hook_defs.h |  2 ++
>   include/linux/security.h      |  6 ++++++
>   security/security.c           | 15 +++++++++++++++
>   4 files changed, 24 insertions(+)
> 
> diff --git a/fs/namei.c b/fs/namei.c
> index b7f433720b1e..adb3ab27951a 100644
> --- a/fs/namei.c
> +++ b/fs/namei.c
> @@ -3686,6 +3686,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, inode);
>   	ima_post_create_tmpfile(idmap, inode);
>   	return 0;
>   }
> diff --git a/include/linux/lsm_hook_defs.h b/include/linux/lsm_hook_defs.h
> index e08b9091350d..5f90914d23e0 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 *inode)
>   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 977dd9f7f51a..1cb604282617 100644
> --- a/include/linux/security.h
> +++ b/include/linux/security.h
> @@ -344,6 +344,8 @@ 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 *inode);
>   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);
> @@ -811,6 +813,10 @@ 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 *inode)
> +{ }
> +
>   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 750bfe2768d5..5bc7edc22923 100644
> --- a/security/security.c
> +++ b/security/security.c
> @@ -2013,6 +2013,21 @@ int security_inode_create(struct inode *dir, struct dentry *dentry,
>   }
>   EXPORT_SYMBOL_GPL(security_inode_create);
>   
> +/**
> + * security_inode_post_create_tmpfile() - Update inode security of new tmpfile
> + * @idmap: idmap of the mount
> + * @inode: inode of the new tmpfile
> + *
> + * Update inode security data after a tmpfile has been created.
> + */
> +void security_inode_post_create_tmpfile(struct mnt_idmap *idmap,
> +					struct inode *inode)
> +{
> +	if (unlikely(IS_PRIVATE(inode)))
> +		return;
> +	call_void_hook(inode_post_create_tmpfile, idmap, inode);
> +}
> +
>   /**
>    * security_inode_link() - Check if creating a hard link is allowed
>    * @old_dentry: existing file
  

Patch

diff --git a/fs/namei.c b/fs/namei.c
index b7f433720b1e..adb3ab27951a 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -3686,6 +3686,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, inode);
 	ima_post_create_tmpfile(idmap, inode);
 	return 0;
 }
diff --git a/include/linux/lsm_hook_defs.h b/include/linux/lsm_hook_defs.h
index e08b9091350d..5f90914d23e0 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 *inode)
 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 977dd9f7f51a..1cb604282617 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -344,6 +344,8 @@  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 *inode);
 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);
@@ -811,6 +813,10 @@  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 *inode)
+{ }
+
 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 750bfe2768d5..5bc7edc22923 100644
--- a/security/security.c
+++ b/security/security.c
@@ -2013,6 +2013,21 @@  int security_inode_create(struct inode *dir, struct dentry *dentry,
 }
 EXPORT_SYMBOL_GPL(security_inode_create);
 
+/**
+ * security_inode_post_create_tmpfile() - Update inode security of new tmpfile
+ * @idmap: idmap of the mount
+ * @inode: inode of the new tmpfile
+ *
+ * Update inode security data after a tmpfile has been created.
+ */
+void security_inode_post_create_tmpfile(struct mnt_idmap *idmap,
+					struct inode *inode)
+{
+	if (unlikely(IS_PRIVATE(inode)))
+		return;
+	call_void_hook(inode_post_create_tmpfile, idmap, inode);
+}
+
 /**
  * security_inode_link() - Check if creating a hard link is allowed
  * @old_dentry: existing file