keyrings.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 00/28] security: Move IMA and EVM to the LSM infrastructure
@ 2023-03-03 18:18 Roberto Sassu
  2023-03-03 18:18 ` [PATCH 01/28] ima: Align ima_inode_post_setattr() definition with " Roberto Sassu
                   ` (28 more replies)
  0 siblings, 29 replies; 79+ messages in thread
From: Roberto Sassu @ 2023-03-03 18:18 UTC (permalink / raw)
  To: viro, chuck.lever, jlayton, zohar, dmitry.kasatkin, paul,
	jmorris, serge, dhowells, jarkko, stephen.smalley.work, eparis,
	casey, brauner
  Cc: linux-fsdevel, linux-nfs, linux-integrity, linux-security-module,
	keyrings, selinux, linux-kernel, stefanb, Roberto Sassu

From: Roberto Sassu <roberto.sassu@huawei.com>

This patch set depends on:
- https://lore.kernel.org/linux-integrity/20221201104125.919483-1-roberto.sassu@huaweicloud.com/ (there will be a v8 shortly)
- https://lore.kernel.org/linux-security-module/20230217032625.678457-1-paul@paul-moore.com/

IMA and EVM are not effectively LSMs, especially due the fact that in the
past they could not provide a security blob while there is another LSM
active.

That changed in the recent years, the LSM stacking feature now makes it
possible to stack together multiple LSMs, and allows them to provide a
security blob for most kernel objects. While the LSM stacking feature has
some limitations being worked out, it is already suitable to make IMA and
EVM as LSMs.

In short, while this patch set is big, it does not make any functional
change to IMA and EVM. IMA and EVM functions are called by the LSM
infrastructure in the same places as before (except ima_post_path_mknod()),
rather being hardcoded calls, and the inode metadata pointer is directly
stored in the inode security blob rather than in a separate rbtree.

More specifically, patches 1-13 make IMA and EVM functions suitable to
be registered to the LSM infrastructure, by aligning function parameters.

Patches 14-22 add new LSM hooks in the same places where IMA and EVM
functions are called, if there is no LSM hook already.

Patch 23 adds the 'last' ordering strategy for LSMs, so that IMA and EVM
functions are called in the same order as of today. Also, like with the
'first' strategy, LSMs using it are always enabled, so IMA and EVM
functions will be always called (if IMA and EVM are compiled built-in).

Patches 24-27 do the bulk of the work, remove hardcoded calls to IMA and
EVM functions, register those functions in the LSM infrastructure, and let
the latter call them. In addition, they also reserve one slot for EVM to 
supply an xattr to the inode_init_security hook.

Finally, patch 28 removes the rbtree used to bind metadata to the inodes,
and instead reserve a space in the inode security blob to store the pointer
to metadata. This also brings performance improvements due to retrieving
metadata in constant time, as opposed to logarithmic.

Roberto Sassu (28):
  ima: Align ima_inode_post_setattr() definition with LSM infrastructure
  ima: Align ima_post_path_mknod() definition with LSM infrastructure
  ima: Align ima_post_create_tmpfile() definition with LSM
    infrastructure
  ima: Align ima_file_mprotect() definition with LSM infrastructure
  ima: Align ima_inode_setxattr() definition with LSM infrastructure
  ima: Align ima_inode_removexattr() definition with LSM infrastructure
  ima: Align ima_post_read_file() definition with LSM infrastructure
  evm: Align evm_inode_post_setattr() definition with LSM infrastructure
  evm: Align evm_inode_setxattr() definition with LSM infrastructure
  evm: Align evm_inode_post_setxattr() definition with LSM
    infrastructure
  evm: Complete description of evm_inode_setattr()
  fs: Fix description of vfs_tmpfile()
  security: Align inode_setattr hook definition with EVM
  security: Introduce inode_post_setattr hook
  security: Introduce inode_post_removexattr hook
  security: Introduce file_post_open hook
  security: Introduce file_pre_free_security hook
  security: Introduce path_post_mknod hook
  security: Introduce inode_post_create_tmpfile hook
  security: Introduce inode_post_set_acl hook
  security: Introduce inode_post_remove_acl hook
  security: Introduce key_post_create_or_update hook
  security: Introduce LSM_ORDER_LAST
  ima: Move to LSM infrastructure
  ima: Move IMA-Appraisal to LSM infrastructure
  evm: Move to LSM infrastructure
  integrity: Move integrity functions to the LSM infrastructure
  integrity: Switch from rbtree to LSM-managed blob for
    integrity_iint_cache

 fs/attr.c                             |   5 +-
 fs/file_table.c                       |   3 +-
 fs/namei.c                            |  13 +-
 fs/nfsd/vfs.c                         |   3 +-
 fs/open.c                             |   1 -
 fs/posix_acl.c                        |   5 +-
 fs/xattr.c                            |   3 +-
 include/linux/evm.h                   | 112 -----------
 include/linux/ima.h                   | 142 -------------
 include/linux/integrity.h             |  26 ---
 include/linux/lsm_hook_defs.h         |  21 +-
 include/linux/lsm_hooks.h             |   1 +
 include/linux/security.h              |  65 ++++++
 security/integrity/evm/evm_main.c     | 109 ++++++++--
 security/integrity/iint.c             |  90 +++------
 security/integrity/ima/ima.h          |  12 ++
 security/integrity/ima/ima_appraise.c |  38 +++-
 security/integrity/ima/ima_main.c     |  77 +++++--
 security/integrity/integrity.h        |  44 +++-
 security/keys/key.c                   |  10 +-
 security/security.c                   | 276 ++++++++++++++++----------
 security/selinux/hooks.c              |   3 +-
 security/smack/smack_lsm.c            |   4 +-
 23 files changed, 550 insertions(+), 513 deletions(-)

-- 
2.25.1


^ permalink raw reply	[flat|nested] 79+ messages in thread

* [PATCH 01/28] ima: Align ima_inode_post_setattr() definition with LSM infrastructure
  2023-03-03 18:18 [PATCH 00/28] security: Move IMA and EVM to the LSM infrastructure Roberto Sassu
@ 2023-03-03 18:18 ` Roberto Sassu
  2023-03-06 16:46   ` Stefan Berger
  2023-03-03 18:18 ` [PATCH 02/28] ima: Align ima_post_path_mknod() " Roberto Sassu
                   ` (27 subsequent siblings)
  28 siblings, 1 reply; 79+ messages in thread
From: Roberto Sassu @ 2023-03-03 18:18 UTC (permalink / raw)
  To: viro, chuck.lever, jlayton, zohar, dmitry.kasatkin, paul,
	jmorris, serge, dhowells, jarkko, stephen.smalley.work, eparis,
	casey, brauner
  Cc: linux-fsdevel, linux-nfs, linux-integrity, linux-security-module,
	keyrings, selinux, linux-kernel, stefanb, Roberto Sassu

From: Roberto Sassu <roberto.sassu@huawei.com>

Change ima_inode_post_setattr() definition, so that it can be registered as
implementation of the inode_post_setattr hook.

Signed-off-by: Roberto Sassu <roberto.sassu@huawei.com>
---
 fs/attr.c                             | 2 +-
 include/linux/ima.h                   | 4 ++--
 security/integrity/ima/ima_appraise.c | 3 ++-
 3 files changed, 5 insertions(+), 4 deletions(-)

diff --git a/fs/attr.c b/fs/attr.c
index aca9ff7aed3..5050ab4cc45 100644
--- a/fs/attr.c
+++ b/fs/attr.c
@@ -485,7 +485,7 @@ int notify_change(struct mnt_idmap *idmap, struct dentry *dentry,
 
 	if (!error) {
 		fsnotify_change(dentry, ia_valid);
-		ima_inode_post_setattr(idmap, dentry);
+		ima_inode_post_setattr(idmap, dentry, ia_valid);
 		evm_inode_post_setattr(dentry, ia_valid);
 	}
 
diff --git a/include/linux/ima.h b/include/linux/ima.h
index 86b57757c7b..910a2f11a90 100644
--- a/include/linux/ima.h
+++ b/include/linux/ima.h
@@ -186,7 +186,7 @@ static inline void ima_post_key_create_or_update(struct key *keyring,
 #ifdef CONFIG_IMA_APPRAISE
 extern bool is_ima_appraise_enabled(void);
 extern void ima_inode_post_setattr(struct mnt_idmap *idmap,
-				   struct dentry *dentry);
+				   struct dentry *dentry, int ia_valid);
 extern int ima_inode_setxattr(struct dentry *dentry, const char *xattr_name,
 		       const void *xattr_value, size_t xattr_value_len);
 extern int ima_inode_set_acl(struct mnt_idmap *idmap,
@@ -206,7 +206,7 @@ static inline bool is_ima_appraise_enabled(void)
 }
 
 static inline void ima_inode_post_setattr(struct mnt_idmap *idmap,
-					  struct dentry *dentry)
+					  struct dentry *dentry, int ia_valid)
 {
 	return;
 }
diff --git a/security/integrity/ima/ima_appraise.c b/security/integrity/ima/ima_appraise.c
index 491c1aca0b1..6b032bce4fe 100644
--- a/security/integrity/ima/ima_appraise.c
+++ b/security/integrity/ima/ima_appraise.c
@@ -627,6 +627,7 @@ void ima_update_xattr(struct integrity_iint_cache *iint, struct file *file)
  * ima_inode_post_setattr - reflect file metadata changes
  * @idmap:  idmap of the mount the inode was found from
  * @dentry: pointer to the affected dentry
+ * @ia_valid: for the UID and GID status
  *
  * Changes to a dentry's metadata might result in needing to appraise.
  *
@@ -634,7 +635,7 @@ void ima_update_xattr(struct integrity_iint_cache *iint, struct file *file)
  * to lock the inode's i_mutex.
  */
 void ima_inode_post_setattr(struct mnt_idmap *idmap,
-			    struct dentry *dentry)
+			    struct dentry *dentry, int ia_valid)
 {
 	struct inode *inode = d_backing_inode(dentry);
 	struct integrity_iint_cache *iint;
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 79+ messages in thread

* [PATCH 02/28] ima: Align ima_post_path_mknod() definition with LSM infrastructure
  2023-03-03 18:18 [PATCH 00/28] security: Move IMA and EVM to the LSM infrastructure Roberto Sassu
  2023-03-03 18:18 ` [PATCH 01/28] ima: Align ima_inode_post_setattr() definition with " Roberto Sassu
@ 2023-03-03 18:18 ` Roberto Sassu
  2023-03-06 16:52   ` Stefan Berger
  2023-03-03 18:18 ` [PATCH 03/28] ima: Align ima_post_create_tmpfile() " Roberto Sassu
                   ` (26 subsequent siblings)
  28 siblings, 1 reply; 79+ messages in thread
From: Roberto Sassu @ 2023-03-03 18:18 UTC (permalink / raw)
  To: viro, chuck.lever, jlayton, zohar, dmitry.kasatkin, paul,
	jmorris, serge, dhowells, jarkko, stephen.smalley.work, eparis,
	casey, brauner
  Cc: linux-fsdevel, linux-nfs, linux-integrity, linux-security-module,
	keyrings, selinux, linux-kernel, stefanb, Roberto Sassu

From: Roberto Sassu <roberto.sassu@huawei.com>

Change ima_post_path_mknod() definition, so that it can be registered as
implementation of the path_post_mknod hook.

Also, make sure that ima_post_path_mknod() is executed only if
(mode & S_IFMT) is equal to zero or S_IFREG.

Add this check to take into account the different placement of the
path_post_mknod hook (to be introduced) in do_mknodat(). Since the new hook
will be placed after the switch(), the check ensures that
ima_post_path_mknod() is invoked as originally intended when it is
registered as implementation of path_post_mknod.

Signed-off-by: Roberto Sassu <roberto.sassu@huawei.com>
---
 fs/namei.c                        |  3 ++-
 include/linux/ima.h               |  7 +++++--
 security/integrity/ima/ima_main.c | 10 +++++++++-
 3 files changed, 16 insertions(+), 4 deletions(-)

diff --git a/fs/namei.c b/fs/namei.c
index edfedfbccae..b5a1ec29193 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -3966,7 +3966,8 @@ static int do_mknodat(int dfd, struct filename *name, umode_t mode,
 			error = vfs_create(idmap, path.dentry->d_inode,
 					   dentry, mode, true);
 			if (!error)
-				ima_post_path_mknod(idmap, dentry);
+				ima_post_path_mknod(idmap, &path, dentry, mode,
+						    dev);
 			break;
 		case S_IFCHR: case S_IFBLK:
 			error = vfs_mknod(idmap, path.dentry->d_inode,
diff --git a/include/linux/ima.h b/include/linux/ima.h
index 910a2f11a90..179ce52013b 100644
--- a/include/linux/ima.h
+++ b/include/linux/ima.h
@@ -32,7 +32,8 @@ extern int ima_read_file(struct file *file, enum kernel_read_file_id id,
 extern int ima_post_read_file(struct file *file, void *buf, loff_t size,
 			      enum kernel_read_file_id id);
 extern void ima_post_path_mknod(struct mnt_idmap *idmap,
-				struct dentry *dentry);
+				const struct path *dir, struct dentry *dentry,
+				umode_t mode, unsigned int dev);
 extern int ima_file_hash(struct file *file, char *buf, size_t buf_size);
 extern int ima_inode_hash(struct inode *inode, char *buf, size_t buf_size);
 extern void ima_kexec_cmdline(int kernel_fd, const void *buf, int size);
@@ -114,7 +115,9 @@ static inline int ima_post_read_file(struct file *file, void *buf, loff_t size,
 }
 
 static inline void ima_post_path_mknod(struct mnt_idmap *idmap,
-				       struct dentry *dentry)
+				       const struct path *dir,
+				       struct dentry *dentry,
+				       umode_t mode, unsigned int dev)
 {
 	return;
 }
diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c
index d66a0a36415..8941305376b 100644
--- a/security/integrity/ima/ima_main.c
+++ b/security/integrity/ima/ima_main.c
@@ -692,18 +692,26 @@ void ima_post_create_tmpfile(struct mnt_idmap *idmap,
 /**
  * ima_post_path_mknod - mark as a new inode
  * @idmap: idmap of the mount the inode was found from
+ * @dir: path structure of parent of the new file
  * @dentry: newly created dentry
+ * @mode: mode of the new file
+ * @dev: undecoded device number
  *
  * Mark files created via the mknodat syscall as new, so that the
  * file data can be written later.
  */
 void ima_post_path_mknod(struct mnt_idmap *idmap,
-			 struct dentry *dentry)
+			 const struct path *dir, struct dentry *dentry,
+			 umode_t mode, unsigned int dev)
 {
 	struct integrity_iint_cache *iint;
 	struct inode *inode = dentry->d_inode;
 	int must_appraise;
 
+	/* See do_mknodat(), IMA is executed for case 0: and case S_IFREG: */
+	if ((mode & S_IFMT) != 0 && (mode & S_IFMT) != S_IFREG)
+		return;
+
 	if (!ima_policy_flag || !S_ISREG(inode->i_mode))
 		return;
 
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 79+ messages in thread

* [PATCH 03/28] ima: Align ima_post_create_tmpfile() definition with LSM infrastructure
  2023-03-03 18:18 [PATCH 00/28] security: Move IMA and EVM to the LSM infrastructure Roberto Sassu
  2023-03-03 18:18 ` [PATCH 01/28] ima: Align ima_inode_post_setattr() definition with " Roberto Sassu
  2023-03-03 18:18 ` [PATCH 02/28] ima: Align ima_post_path_mknod() " Roberto Sassu
@ 2023-03-03 18:18 ` Roberto Sassu
  2023-03-06 16:53   ` Stefan Berger
  2023-03-08 15:15   ` Mimi Zohar
  2023-03-03 18:18 ` [PATCH 04/28] ima: Align ima_file_mprotect() " Roberto Sassu
                   ` (25 subsequent siblings)
  28 siblings, 2 replies; 79+ messages in thread
From: Roberto Sassu @ 2023-03-03 18:18 UTC (permalink / raw)
  To: viro, chuck.lever, jlayton, zohar, dmitry.kasatkin, paul,
	jmorris, serge, dhowells, jarkko, stephen.smalley.work, eparis,
	casey, brauner
  Cc: linux-fsdevel, linux-nfs, linux-integrity, linux-security-module,
	keyrings, selinux, linux-kernel, stefanb, Roberto Sassu

From: Roberto Sassu <roberto.sassu@huawei.com>

Change ima_post_create_tmpfile() definition, so that it can be registered
as implementation of the post_create_tmpfile hook.

Signed-off-by: Roberto Sassu <roberto.sassu@huawei.com>
---
 fs/namei.c                        | 2 +-
 include/linux/ima.h               | 7 +++++--
 security/integrity/ima/ima_main.c | 8 ++++++--
 3 files changed, 12 insertions(+), 5 deletions(-)

diff --git a/fs/namei.c b/fs/namei.c
index b5a1ec29193..57727a1ae38 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -3622,7 +3622,7 @@ static int vfs_tmpfile(struct mnt_idmap *idmap,
 		inode->i_state |= I_LINKABLE;
 		spin_unlock(&inode->i_lock);
 	}
-	ima_post_create_tmpfile(idmap, inode);
+	ima_post_create_tmpfile(idmap, dir, file_dentry(file), mode);
 	return 0;
 }
 
diff --git a/include/linux/ima.h b/include/linux/ima.h
index 179ce52013b..7535686a403 100644
--- a/include/linux/ima.h
+++ b/include/linux/ima.h
@@ -19,7 +19,8 @@ extern enum hash_algo ima_get_current_hash_algo(void);
 extern int ima_bprm_check(struct linux_binprm *bprm);
 extern int ima_file_check(struct file *file, int mask);
 extern void ima_post_create_tmpfile(struct mnt_idmap *idmap,
-				    struct inode *inode);
+				    struct inode *dir, struct dentry *dentry,
+				    umode_t mode);
 extern void ima_file_free(struct file *file);
 extern int ima_file_mmap(struct file *file, unsigned long reqprot,
 			 unsigned long prot, unsigned long flags);
@@ -69,7 +70,9 @@ static inline int ima_file_check(struct file *file, int mask)
 }
 
 static inline void ima_post_create_tmpfile(struct mnt_idmap *idmap,
-					   struct inode *inode)
+					   struct inode *dir,
+					   struct dentry *dentry,
+					   umode_t mode)
 {
 }
 
diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c
index 8941305376b..4a3d0c8bcba 100644
--- a/security/integrity/ima/ima_main.c
+++ b/security/integrity/ima/ima_main.c
@@ -659,16 +659,20 @@ EXPORT_SYMBOL_GPL(ima_inode_hash);
 /**
  * ima_post_create_tmpfile - mark newly created tmpfile as new
  * @idmap: idmap of the mount the inode was found from
- * @inode: inode of the newly created tmpfile
+ * @dir: inode structure of the parent of the new file
+ * @dentry: dentry structure of the new file
+ * @mode: mode of the new file
  *
  * No measuring, appraising or auditing of newly created tmpfiles is needed.
  * Skip calling process_measurement(), but indicate which newly, created
  * tmpfiles are in policy.
  */
 void ima_post_create_tmpfile(struct mnt_idmap *idmap,
-			     struct inode *inode)
+			     struct inode *dir, struct dentry *dentry,
+			     umode_t mode)
 {
 	struct integrity_iint_cache *iint;
+	struct inode *inode = dentry->d_inode;
 	int must_appraise;
 
 	if (!ima_policy_flag || !S_ISREG(inode->i_mode))
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 79+ messages in thread

* [PATCH 04/28] ima: Align ima_file_mprotect() definition with LSM infrastructure
  2023-03-03 18:18 [PATCH 00/28] security: Move IMA and EVM to the LSM infrastructure Roberto Sassu
                   ` (2 preceding siblings ...)
  2023-03-03 18:18 ` [PATCH 03/28] ima: Align ima_post_create_tmpfile() " Roberto Sassu
@ 2023-03-03 18:18 ` Roberto Sassu
  2023-03-06 16:56   ` Stefan Berger
  2023-03-03 18:18 ` [PATCH 05/28] ima: Align ima_inode_setxattr() " Roberto Sassu
                   ` (24 subsequent siblings)
  28 siblings, 1 reply; 79+ messages in thread
From: Roberto Sassu @ 2023-03-03 18:18 UTC (permalink / raw)
  To: viro, chuck.lever, jlayton, zohar, dmitry.kasatkin, paul,
	jmorris, serge, dhowells, jarkko, stephen.smalley.work, eparis,
	casey, brauner
  Cc: linux-fsdevel, linux-nfs, linux-integrity, linux-security-module,
	keyrings, selinux, linux-kernel, stefanb, Roberto Sassu

From: Roberto Sassu <roberto.sassu@huawei.com>

Change ima_file_mprotect() definition, so that it can be registered
as implementation of the file_mprotect hook.

Signed-off-by: Roberto Sassu <roberto.sassu@huawei.com>
---
 include/linux/ima.h               | 5 +++--
 security/integrity/ima/ima_main.c | 6 ++++--
 security/security.c               | 2 +-
 3 files changed, 8 insertions(+), 5 deletions(-)

diff --git a/include/linux/ima.h b/include/linux/ima.h
index 7535686a403..dd216afab6c 100644
--- a/include/linux/ima.h
+++ b/include/linux/ima.h
@@ -24,7 +24,8 @@ extern void ima_post_create_tmpfile(struct mnt_idmap *idmap,
 extern void ima_file_free(struct file *file);
 extern int ima_file_mmap(struct file *file, unsigned long reqprot,
 			 unsigned long prot, unsigned long flags);
-extern int ima_file_mprotect(struct vm_area_struct *vma, unsigned long prot);
+extern int ima_file_mprotect(struct vm_area_struct *vma, unsigned long reqprot,
+			     unsigned long prot);
 extern int ima_load_data(enum kernel_load_data_id id, bool contents);
 extern int ima_post_load_data(char *buf, loff_t size,
 			      enum kernel_load_data_id id, char *description);
@@ -88,7 +89,7 @@ static inline int ima_file_mmap(struct file *file, unsigned long reqprot,
 }
 
 static inline int ima_file_mprotect(struct vm_area_struct *vma,
-				    unsigned long prot)
+				    unsigned long reqprot, unsigned long prot)
 {
 	return 0;
 }
diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c
index 4a3d0c8bcba..4e26fd49ae7 100644
--- a/security/integrity/ima/ima_main.c
+++ b/security/integrity/ima/ima_main.c
@@ -437,7 +437,8 @@ int ima_file_mmap(struct file *file, unsigned long reqprot,
 /**
  * ima_file_mprotect - based on policy, limit mprotect change
  * @vma: vm_area_struct protection is set to
- * @prot: contains the protection that will be applied by the kernel.
+ * @reqprot: protection requested by the application
+ * @prot: protection that will be applied by the kernel
  *
  * Files can be mmap'ed read/write and later changed to execute to circumvent
  * IMA's mmap appraisal policy rules.  Due to locking issues (mmap semaphore
@@ -447,7 +448,8 @@ int ima_file_mmap(struct file *file, unsigned long reqprot,
  *
  * On mprotect change success, return 0.  On failure, return -EACESS.
  */
-int ima_file_mprotect(struct vm_area_struct *vma, unsigned long prot)
+int ima_file_mprotect(struct vm_area_struct *vma, unsigned long reqprot,
+		      unsigned long prot)
 {
 	struct ima_template_desc *template = NULL;
 	struct file *file;
diff --git a/security/security.c b/security/security.c
index a8abc11dd26..8d31b739879 100644
--- a/security/security.c
+++ b/security/security.c
@@ -2771,7 +2771,7 @@ int security_file_mprotect(struct vm_area_struct *vma, unsigned long reqprot,
 	ret = call_int_hook(file_mprotect, 0, vma, reqprot, prot);
 	if (ret)
 		return ret;
-	return ima_file_mprotect(vma, prot);
+	return ima_file_mprotect(vma, reqprot, prot);
 }
 
 /**
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 79+ messages in thread

* [PATCH 05/28] ima: Align ima_inode_setxattr() definition with LSM infrastructure
  2023-03-03 18:18 [PATCH 00/28] security: Move IMA and EVM to the LSM infrastructure Roberto Sassu
                   ` (3 preceding siblings ...)
  2023-03-03 18:18 ` [PATCH 04/28] ima: Align ima_file_mprotect() " Roberto Sassu
@ 2023-03-03 18:18 ` Roberto Sassu
  2023-03-06 16:57   ` Stefan Berger
  2023-03-03 18:18 ` [PATCH 06/28] ima: Align ima_inode_removexattr() " Roberto Sassu
                   ` (23 subsequent siblings)
  28 siblings, 1 reply; 79+ messages in thread
From: Roberto Sassu @ 2023-03-03 18:18 UTC (permalink / raw)
  To: viro, chuck.lever, jlayton, zohar, dmitry.kasatkin, paul,
	jmorris, serge, dhowells, jarkko, stephen.smalley.work, eparis,
	casey, brauner
  Cc: linux-fsdevel, linux-nfs, linux-integrity, linux-security-module,
	keyrings, selinux, linux-kernel, stefanb, Roberto Sassu

From: Roberto Sassu <roberto.sassu@huawei.com>

Change ima_inode_setxattr() definition, so that it can be registered as
implementation of the inode_setxattr hook.

Signed-off-by: Roberto Sassu <roberto.sassu@huawei.com>
---
 include/linux/ima.h                   | 11 +++++++----
 security/integrity/ima/ima_appraise.c |  5 +++--
 security/security.c                   |  2 +-
 3 files changed, 11 insertions(+), 7 deletions(-)

diff --git a/include/linux/ima.h b/include/linux/ima.h
index dd216afab6c..6ec6725e3ad 100644
--- a/include/linux/ima.h
+++ b/include/linux/ima.h
@@ -194,8 +194,9 @@ static inline void ima_post_key_create_or_update(struct key *keyring,
 extern bool is_ima_appraise_enabled(void);
 extern void ima_inode_post_setattr(struct mnt_idmap *idmap,
 				   struct dentry *dentry, int ia_valid);
-extern int ima_inode_setxattr(struct dentry *dentry, const char *xattr_name,
-		       const void *xattr_value, size_t xattr_value_len);
+extern int ima_inode_setxattr(struct mnt_idmap *idmap, struct dentry *dentry,
+			      const char *xattr_name, const void *xattr_value,
+			      size_t xattr_value_len, int flags);
 extern int ima_inode_set_acl(struct mnt_idmap *idmap,
 			     struct dentry *dentry, const char *acl_name,
 			     struct posix_acl *kacl);
@@ -218,10 +219,12 @@ static inline void ima_inode_post_setattr(struct mnt_idmap *idmap,
 	return;
 }
 
-static inline int ima_inode_setxattr(struct dentry *dentry,
+static inline int ima_inode_setxattr(struct mnt_idmap *idmap,
+				     struct dentry *dentry,
 				     const char *xattr_name,
 				     const void *xattr_value,
-				     size_t xattr_value_len)
+				     size_t xattr_value_len,
+				     int flags)
 {
 	return 0;
 }
diff --git a/security/integrity/ima/ima_appraise.c b/security/integrity/ima/ima_appraise.c
index 6b032bce4fe..88c5a0b2992 100644
--- a/security/integrity/ima/ima_appraise.c
+++ b/security/integrity/ima/ima_appraise.c
@@ -748,8 +748,9 @@ static int validate_hash_algo(struct dentry *dentry,
 	return -EACCES;
 }
 
-int ima_inode_setxattr(struct dentry *dentry, const char *xattr_name,
-		       const void *xattr_value, size_t xattr_value_len)
+int ima_inode_setxattr(struct mnt_idmap *idmap, struct dentry *dentry,
+		       const char *xattr_name, const void *xattr_value,
+		       size_t xattr_value_len, int flags)
 {
 	const struct evm_ima_xattr_data *xvalue = xattr_value;
 	int digsig = 0;
diff --git a/security/security.c b/security/security.c
index 8d31b739879..51612dcf05b 100644
--- a/security/security.c
+++ b/security/security.c
@@ -2221,7 +2221,7 @@ int security_inode_setxattr(struct mnt_idmap *idmap,
 		ret = cap_inode_setxattr(dentry, name, value, size, flags);
 	if (ret)
 		return ret;
-	ret = ima_inode_setxattr(dentry, name, value, size);
+	ret = ima_inode_setxattr(idmap, dentry, name, value, size, flags);
 	if (ret)
 		return ret;
 	return evm_inode_setxattr(idmap, dentry, name, value, size);
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 79+ messages in thread

* [PATCH 06/28] ima: Align ima_inode_removexattr() definition with LSM infrastructure
  2023-03-03 18:18 [PATCH 00/28] security: Move IMA and EVM to the LSM infrastructure Roberto Sassu
                   ` (4 preceding siblings ...)
  2023-03-03 18:18 ` [PATCH 05/28] ima: Align ima_inode_setxattr() " Roberto Sassu
@ 2023-03-03 18:18 ` Roberto Sassu
  2023-03-06 16:58   ` Stefan Berger
  2023-03-03 18:18 ` [PATCH 07/28] ima: Align ima_post_read_file() " Roberto Sassu
                   ` (22 subsequent siblings)
  28 siblings, 1 reply; 79+ messages in thread
From: Roberto Sassu @ 2023-03-03 18:18 UTC (permalink / raw)
  To: viro, chuck.lever, jlayton, zohar, dmitry.kasatkin, paul,
	jmorris, serge, dhowells, jarkko, stephen.smalley.work, eparis,
	casey, brauner
  Cc: linux-fsdevel, linux-nfs, linux-integrity, linux-security-module,
	keyrings, selinux, linux-kernel, stefanb, Roberto Sassu

From: Roberto Sassu <roberto.sassu@huawei.com>

Change ima_inode_removexattr() definition, so that it can be registered as
implementation of the inode_removexattr hook.

Signed-off-by: Roberto Sassu <roberto.sassu@huawei.com>
---
 include/linux/ima.h                   | 6 ++++--
 security/integrity/ima/ima_appraise.c | 3 ++-
 security/security.c                   | 2 +-
 3 files changed, 7 insertions(+), 4 deletions(-)

diff --git a/include/linux/ima.h b/include/linux/ima.h
index 6ec6725e3ad..fb1d4699949 100644
--- a/include/linux/ima.h
+++ b/include/linux/ima.h
@@ -206,7 +206,8 @@ static inline int ima_inode_remove_acl(struct mnt_idmap *idmap,
 {
 	return ima_inode_set_acl(idmap, dentry, acl_name, NULL);
 }
-extern int ima_inode_removexattr(struct dentry *dentry, const char *xattr_name);
+extern int ima_inode_removexattr(struct mnt_idmap *idmap, struct dentry *dentry,
+				 const char *xattr_name);
 #else
 static inline bool is_ima_appraise_enabled(void)
 {
@@ -237,7 +238,8 @@ static inline int ima_inode_set_acl(struct mnt_idmap *idmap,
 	return 0;
 }
 
-static inline int ima_inode_removexattr(struct dentry *dentry,
+static inline int ima_inode_removexattr(struct mnt_idmap *idmap,
+					struct dentry *dentry,
 					const char *xattr_name)
 {
 	return 0;
diff --git a/security/integrity/ima/ima_appraise.c b/security/integrity/ima/ima_appraise.c
index 88c5a0b2992..c35e3537eb8 100644
--- a/security/integrity/ima/ima_appraise.c
+++ b/security/integrity/ima/ima_appraise.c
@@ -788,7 +788,8 @@ int ima_inode_set_acl(struct mnt_idmap *idmap, struct dentry *dentry,
 	return 0;
 }
 
-int ima_inode_removexattr(struct dentry *dentry, const char *xattr_name)
+int ima_inode_removexattr(struct mnt_idmap *idmap, struct dentry *dentry,
+			  const char *xattr_name)
 {
 	int result;
 
diff --git a/security/security.c b/security/security.c
index 51612dcf05b..29b4bebba5e 100644
--- a/security/security.c
+++ b/security/security.c
@@ -2382,7 +2382,7 @@ int security_inode_removexattr(struct mnt_idmap *idmap,
 		ret = cap_inode_removexattr(idmap, dentry, name);
 	if (ret)
 		return ret;
-	ret = ima_inode_removexattr(dentry, name);
+	ret = ima_inode_removexattr(idmap, dentry, name);
 	if (ret)
 		return ret;
 	return evm_inode_removexattr(idmap, dentry, name);
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 79+ messages in thread

* [PATCH 07/28] ima: Align ima_post_read_file() definition with LSM infrastructure
  2023-03-03 18:18 [PATCH 00/28] security: Move IMA and EVM to the LSM infrastructure Roberto Sassu
                   ` (5 preceding siblings ...)
  2023-03-03 18:18 ` [PATCH 06/28] ima: Align ima_inode_removexattr() " Roberto Sassu
@ 2023-03-03 18:18 ` Roberto Sassu
  2023-03-06 16:59   ` Stefan Berger
  2023-03-03 18:18 ` [PATCH 08/28] evm: Align evm_inode_post_setattr() " Roberto Sassu
                   ` (21 subsequent siblings)
  28 siblings, 1 reply; 79+ messages in thread
From: Roberto Sassu @ 2023-03-03 18:18 UTC (permalink / raw)
  To: viro, chuck.lever, jlayton, zohar, dmitry.kasatkin, paul,
	jmorris, serge, dhowells, jarkko, stephen.smalley.work, eparis,
	casey, brauner
  Cc: linux-fsdevel, linux-nfs, linux-integrity, linux-security-module,
	keyrings, selinux, linux-kernel, stefanb, Roberto Sassu

From: Roberto Sassu <roberto.sassu@huawei.com>

Change ima_post_read_file() definition, so that it can be registered as
implementation of the post_read_file hook.

Signed-off-by: Roberto Sassu <roberto.sassu@huawei.com>
---
 include/linux/ima.h               | 4 ++--
 security/integrity/ima/ima_main.c | 2 +-
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/include/linux/ima.h b/include/linux/ima.h
index fb1d4699949..f56c6280667 100644
--- a/include/linux/ima.h
+++ b/include/linux/ima.h
@@ -31,7 +31,7 @@ extern int ima_post_load_data(char *buf, loff_t size,
 			      enum kernel_load_data_id id, char *description);
 extern int ima_read_file(struct file *file, enum kernel_read_file_id id,
 			 bool contents);
-extern int ima_post_read_file(struct file *file, void *buf, loff_t size,
+extern int ima_post_read_file(struct file *file, char *buf, loff_t size,
 			      enum kernel_read_file_id id);
 extern void ima_post_path_mknod(struct mnt_idmap *idmap,
 				const struct path *dir, struct dentry *dentry,
@@ -112,7 +112,7 @@ static inline int ima_read_file(struct file *file, enum kernel_read_file_id id,
 	return 0;
 }
 
-static inline int ima_post_read_file(struct file *file, void *buf, loff_t size,
+static inline int ima_post_read_file(struct file *file, char *buf, loff_t size,
 				     enum kernel_read_file_id id)
 {
 	return 0;
diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c
index 4e26fd49ae7..b7835e287d9 100644
--- a/security/integrity/ima/ima_main.c
+++ b/security/integrity/ima/ima_main.c
@@ -797,7 +797,7 @@ const int read_idmap[READING_MAX_ID] = {
  * On success return 0.  On integrity appraisal error, assuming the file
  * is in policy and IMA-appraisal is in enforcing mode, return -EACCES.
  */
-int ima_post_read_file(struct file *file, void *buf, loff_t size,
+int ima_post_read_file(struct file *file, char *buf, loff_t size,
 		       enum kernel_read_file_id read_id)
 {
 	enum ima_hooks func;
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 79+ messages in thread

* [PATCH 08/28] evm: Align evm_inode_post_setattr() definition with LSM infrastructure
  2023-03-03 18:18 [PATCH 00/28] security: Move IMA and EVM to the LSM infrastructure Roberto Sassu
                   ` (6 preceding siblings ...)
  2023-03-03 18:18 ` [PATCH 07/28] ima: Align ima_post_read_file() " Roberto Sassu
@ 2023-03-03 18:18 ` Roberto Sassu
  2023-03-06 17:00   ` Stefan Berger
  2023-03-03 18:18 ` [PATCH 09/28] evm: Align evm_inode_setxattr() " Roberto Sassu
                   ` (20 subsequent siblings)
  28 siblings, 1 reply; 79+ messages in thread
From: Roberto Sassu @ 2023-03-03 18:18 UTC (permalink / raw)
  To: viro, chuck.lever, jlayton, zohar, dmitry.kasatkin, paul,
	jmorris, serge, dhowells, jarkko, stephen.smalley.work, eparis,
	casey, brauner
  Cc: linux-fsdevel, linux-nfs, linux-integrity, linux-security-module,
	keyrings, selinux, linux-kernel, stefanb, Roberto Sassu

From: Roberto Sassu <roberto.sassu@huawei.com>

Change evm_inode_post_setattr() definition, so that it can be registered as
implementation of the inode_post_setattr hook.

Signed-off-by: Roberto Sassu <roberto.sassu@huawei.com>
---
 fs/attr.c                         | 2 +-
 include/linux/evm.h               | 6 ++++--
 security/integrity/evm/evm_main.c | 4 +++-
 3 files changed, 8 insertions(+), 4 deletions(-)

diff --git a/fs/attr.c b/fs/attr.c
index 5050ab4cc45..da45cf01be6 100644
--- a/fs/attr.c
+++ b/fs/attr.c
@@ -486,7 +486,7 @@ int notify_change(struct mnt_idmap *idmap, struct dentry *dentry,
 	if (!error) {
 		fsnotify_change(dentry, ia_valid);
 		ima_inode_post_setattr(idmap, dentry, ia_valid);
-		evm_inode_post_setattr(dentry, ia_valid);
+		evm_inode_post_setattr(idmap, dentry, ia_valid);
 	}
 
 	return error;
diff --git a/include/linux/evm.h b/include/linux/evm.h
index cc64cea354e..b41f98791a7 100644
--- a/include/linux/evm.h
+++ b/include/linux/evm.h
@@ -23,7 +23,8 @@ extern enum integrity_status evm_verifyxattr(struct dentry *dentry,
 					     struct integrity_iint_cache *iint);
 extern int evm_inode_setattr(struct mnt_idmap *idmap,
 			     struct dentry *dentry, struct iattr *attr);
-extern void evm_inode_post_setattr(struct dentry *dentry, int ia_valid);
+extern void evm_inode_post_setattr(struct mnt_idmap *idmap,
+				   struct dentry *dentry, int ia_valid);
 extern int evm_inode_setxattr(struct mnt_idmap *idmap,
 			      struct dentry *dentry, const char *name,
 			      const void *value, size_t size);
@@ -96,7 +97,8 @@ static inline int evm_inode_setattr(struct mnt_idmap *idmap,
 	return 0;
 }
 
-static inline void evm_inode_post_setattr(struct dentry *dentry, int ia_valid)
+static inline void evm_inode_post_setattr(struct mnt_idmap *idmap,
+					  struct dentry *dentry, int ia_valid)
 {
 	return;
 }
diff --git a/security/integrity/evm/evm_main.c b/security/integrity/evm/evm_main.c
index 40cfe0d16c8..0cb63dfc998 100644
--- a/security/integrity/evm/evm_main.c
+++ b/security/integrity/evm/evm_main.c
@@ -838,6 +838,7 @@ int evm_inode_setattr(struct mnt_idmap *idmap, struct dentry *dentry,
 
 /**
  * evm_inode_post_setattr - update 'security.evm' after modifying metadata
+ * @idmap: idmap of the idmapped mount
  * @dentry: pointer to the affected dentry
  * @ia_valid: for the UID and GID status
  *
@@ -847,7 +848,8 @@ int evm_inode_setattr(struct mnt_idmap *idmap, struct dentry *dentry,
  * This function is called from notify_change(), which expects the caller
  * to lock the inode's i_mutex.
  */
-void evm_inode_post_setattr(struct dentry *dentry, int ia_valid)
+void evm_inode_post_setattr(struct mnt_idmap *idmap, struct dentry *dentry,
+			    int ia_valid)
 {
 	if (!evm_revalidate_status(NULL))
 		return;
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 79+ messages in thread

* [PATCH 09/28] evm: Align evm_inode_setxattr() definition with LSM infrastructure
  2023-03-03 18:18 [PATCH 00/28] security: Move IMA and EVM to the LSM infrastructure Roberto Sassu
                   ` (7 preceding siblings ...)
  2023-03-03 18:18 ` [PATCH 08/28] evm: Align evm_inode_post_setattr() " Roberto Sassu
@ 2023-03-03 18:18 ` Roberto Sassu
  2023-03-06 17:01   ` Stefan Berger
  2023-03-03 18:18 ` [PATCH 10/28] evm: Align evm_inode_post_setxattr() " Roberto Sassu
                   ` (19 subsequent siblings)
  28 siblings, 1 reply; 79+ messages in thread
From: Roberto Sassu @ 2023-03-03 18:18 UTC (permalink / raw)
  To: viro, chuck.lever, jlayton, zohar, dmitry.kasatkin, paul,
	jmorris, serge, dhowells, jarkko, stephen.smalley.work, eparis,
	casey, brauner
  Cc: linux-fsdevel, linux-nfs, linux-integrity, linux-security-module,
	keyrings, selinux, linux-kernel, stefanb, Roberto Sassu

From: Roberto Sassu <roberto.sassu@huawei.com>

Change evm_inode_setxattr() definition, so that it can be registered as
implementation of the inode_setxattr hook.

Signed-off-by: Roberto Sassu <roberto.sassu@huawei.com>
---
 include/linux/evm.h               | 4 ++--
 security/integrity/evm/evm_main.c | 3 ++-
 security/security.c               | 2 +-
 3 files changed, 5 insertions(+), 4 deletions(-)

diff --git a/include/linux/evm.h b/include/linux/evm.h
index b41f98791a7..2f8c5a3983f 100644
--- a/include/linux/evm.h
+++ b/include/linux/evm.h
@@ -27,7 +27,7 @@ extern void evm_inode_post_setattr(struct mnt_idmap *idmap,
 				   struct dentry *dentry, int ia_valid);
 extern int evm_inode_setxattr(struct mnt_idmap *idmap,
 			      struct dentry *dentry, const char *name,
-			      const void *value, size_t size);
+			      const void *value, size_t size, int flags);
 extern void evm_inode_post_setxattr(struct dentry *dentry,
 				    const char *xattr_name,
 				    const void *xattr_value,
@@ -105,7 +105,7 @@ static inline void evm_inode_post_setattr(struct mnt_idmap *idmap,
 
 static inline int evm_inode_setxattr(struct mnt_idmap *idmap,
 				     struct dentry *dentry, const char *name,
-				     const void *value, size_t size)
+				     const void *value, size_t size, int flags)
 {
 	return 0;
 }
diff --git a/security/integrity/evm/evm_main.c b/security/integrity/evm/evm_main.c
index 0cb63dfc998..c884534f3b7 100644
--- a/security/integrity/evm/evm_main.c
+++ b/security/integrity/evm/evm_main.c
@@ -558,6 +558,7 @@ static int evm_protect_xattr(struct mnt_idmap *idmap,
  * @xattr_name: pointer to the affected extended attribute name
  * @xattr_value: pointer to the new extended attribute value
  * @xattr_value_len: pointer to the new extended attribute value length
+ * @flags: flags to pass into filesystem operations
  *
  * Before allowing the 'security.evm' protected xattr to be updated,
  * verify the existing value is valid.  As only the kernel should have
@@ -567,7 +568,7 @@ static int evm_protect_xattr(struct mnt_idmap *idmap,
  */
 int evm_inode_setxattr(struct mnt_idmap *idmap, struct dentry *dentry,
 		       const char *xattr_name, const void *xattr_value,
-		       size_t xattr_value_len)
+		       size_t xattr_value_len, int flags)
 {
 	const struct evm_ima_xattr_data *xattr_data = xattr_value;
 
diff --git a/security/security.c b/security/security.c
index 29b4bebba5e..dcb98901eb9 100644
--- a/security/security.c
+++ b/security/security.c
@@ -2224,7 +2224,7 @@ int security_inode_setxattr(struct mnt_idmap *idmap,
 	ret = ima_inode_setxattr(idmap, dentry, name, value, size, flags);
 	if (ret)
 		return ret;
-	return evm_inode_setxattr(idmap, dentry, name, value, size);
+	return evm_inode_setxattr(idmap, dentry, name, value, size, flags);
 }
 
 /**
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 79+ messages in thread

* [PATCH 10/28] evm: Align evm_inode_post_setxattr() definition with LSM infrastructure
  2023-03-03 18:18 [PATCH 00/28] security: Move IMA and EVM to the LSM infrastructure Roberto Sassu
                   ` (8 preceding siblings ...)
  2023-03-03 18:18 ` [PATCH 09/28] evm: Align evm_inode_setxattr() " Roberto Sassu
@ 2023-03-03 18:18 ` Roberto Sassu
  2023-03-06 17:02   ` Stefan Berger
  2023-03-03 18:18 ` [PATCH 11/28] evm: Complete description of evm_inode_setattr() Roberto Sassu
                   ` (18 subsequent siblings)
  28 siblings, 1 reply; 79+ messages in thread
From: Roberto Sassu @ 2023-03-03 18:18 UTC (permalink / raw)
  To: viro, chuck.lever, jlayton, zohar, dmitry.kasatkin, paul,
	jmorris, serge, dhowells, jarkko, stephen.smalley.work, eparis,
	casey, brauner
  Cc: linux-fsdevel, linux-nfs, linux-integrity, linux-security-module,
	keyrings, selinux, linux-kernel, stefanb, Roberto Sassu

From: Roberto Sassu <roberto.sassu@huawei.com>

Change evm_inode_post_setxattr() definition, so that it can be registered
as implementation of the inode_post_setxattr hook.

Signed-off-by: Roberto Sassu <roberto.sassu@huawei.com>
---
 include/linux/evm.h               | 8 +++++---
 security/integrity/evm/evm_main.c | 4 +++-
 security/security.c               | 2 +-
 3 files changed, 9 insertions(+), 5 deletions(-)

diff --git a/include/linux/evm.h b/include/linux/evm.h
index 2f8c5a3983f..8c043273552 100644
--- a/include/linux/evm.h
+++ b/include/linux/evm.h
@@ -31,7 +31,8 @@ extern int evm_inode_setxattr(struct mnt_idmap *idmap,
 extern void evm_inode_post_setxattr(struct dentry *dentry,
 				    const char *xattr_name,
 				    const void *xattr_value,
-				    size_t xattr_value_len);
+				    size_t xattr_value_len,
+				    int flags);
 extern int evm_inode_removexattr(struct mnt_idmap *idmap,
 				 struct dentry *dentry, const char *xattr_name);
 extern void evm_inode_post_removexattr(struct dentry *dentry,
@@ -55,7 +56,7 @@ static inline void evm_inode_post_set_acl(struct dentry *dentry,
 					  const char *acl_name,
 					  struct posix_acl *kacl)
 {
-	return evm_inode_post_setxattr(dentry, acl_name, NULL, 0);
+	return evm_inode_post_setxattr(dentry, acl_name, NULL, 0, 0);
 }
 extern int evm_inode_init_security(struct inode *inode, struct inode *dir,
 				   const struct qstr *qstr,
@@ -113,7 +114,8 @@ static inline int evm_inode_setxattr(struct mnt_idmap *idmap,
 static inline void evm_inode_post_setxattr(struct dentry *dentry,
 					   const char *xattr_name,
 					   const void *xattr_value,
-					   size_t xattr_value_len)
+					   size_t xattr_value_len,
+					   int flags)
 {
 	return;
 }
diff --git a/security/integrity/evm/evm_main.c b/security/integrity/evm/evm_main.c
index c884534f3b7..1155a58ae87 100644
--- a/security/integrity/evm/evm_main.c
+++ b/security/integrity/evm/evm_main.c
@@ -730,6 +730,7 @@ bool evm_revalidate_status(const char *xattr_name)
  * @xattr_name: pointer to the affected extended attribute name
  * @xattr_value: pointer to the new extended attribute value
  * @xattr_value_len: pointer to the new extended attribute value length
+ * @flags: flags to pass into filesystem operations
  *
  * Update the HMAC stored in 'security.evm' to reflect the change.
  *
@@ -738,7 +739,8 @@ bool evm_revalidate_status(const char *xattr_name)
  * i_mutex lock.
  */
 void evm_inode_post_setxattr(struct dentry *dentry, const char *xattr_name,
-			     const void *xattr_value, size_t xattr_value_len)
+			     const void *xattr_value, size_t xattr_value_len,
+			     int flags)
 {
 	if (!evm_revalidate_status(xattr_name))
 		return;
diff --git a/security/security.c b/security/security.c
index dcb98901eb9..df6714aa19d 100644
--- a/security/security.c
+++ b/security/security.c
@@ -2319,7 +2319,7 @@ void security_inode_post_setxattr(struct dentry *dentry, const char *name,
 	if (unlikely(IS_PRIVATE(d_backing_inode(dentry))))
 		return;
 	call_void_hook(inode_post_setxattr, dentry, name, value, size, flags);
-	evm_inode_post_setxattr(dentry, name, value, size);
+	evm_inode_post_setxattr(dentry, name, value, size, flags);
 }
 
 /**
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 79+ messages in thread

* [PATCH 11/28] evm: Complete description of evm_inode_setattr()
  2023-03-03 18:18 [PATCH 00/28] security: Move IMA and EVM to the LSM infrastructure Roberto Sassu
                   ` (9 preceding siblings ...)
  2023-03-03 18:18 ` [PATCH 10/28] evm: Align evm_inode_post_setxattr() " Roberto Sassu
@ 2023-03-03 18:18 ` Roberto Sassu
  2023-03-06 17:04   ` Stefan Berger
  2023-03-03 18:18 ` [PATCH 12/28] fs: Fix description of vfs_tmpfile() Roberto Sassu
                   ` (17 subsequent siblings)
  28 siblings, 1 reply; 79+ messages in thread
From: Roberto Sassu @ 2023-03-03 18:18 UTC (permalink / raw)
  To: viro, chuck.lever, jlayton, zohar, dmitry.kasatkin, paul,
	jmorris, serge, dhowells, jarkko, stephen.smalley.work, eparis,
	casey, brauner
  Cc: linux-fsdevel, linux-nfs, linux-integrity, linux-security-module,
	keyrings, selinux, linux-kernel, stefanb, Roberto Sassu

From: Roberto Sassu <roberto.sassu@huawei.com>

Add the description for missing parameters of evm_inode_setattr() to
avoid the warning arising with W=n compile option.

Fixes: 817b54aa45db ("evm: add evm_inode_setattr to prevent updating an invalid security.evm")
Fixes: c1632a0f1120 ("fs: port ->setattr() to pass mnt_idmap")
Signed-off-by: Roberto Sassu <roberto.sassu@huawei.com>
---
 security/integrity/evm/evm_main.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/security/integrity/evm/evm_main.c b/security/integrity/evm/evm_main.c
index 1155a58ae87..8b5c472f78b 100644
--- a/security/integrity/evm/evm_main.c
+++ b/security/integrity/evm/evm_main.c
@@ -798,7 +798,9 @@ static int evm_attr_change(struct mnt_idmap *idmap,
 
 /**
  * evm_inode_setattr - prevent updating an invalid EVM extended attribute
+ * @idmap: idmap of the mount
  * @dentry: pointer to the affected dentry
+ * @attr: iattr structure containing the new file attributes
  *
  * Permit update of file attributes when files have a valid EVM signature,
  * except in the case of them having an immutable portable signature.
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 79+ messages in thread

* [PATCH 12/28] fs: Fix description of vfs_tmpfile()
  2023-03-03 18:18 [PATCH 00/28] security: Move IMA and EVM to the LSM infrastructure Roberto Sassu
                   ` (10 preceding siblings ...)
  2023-03-03 18:18 ` [PATCH 11/28] evm: Complete description of evm_inode_setattr() Roberto Sassu
@ 2023-03-03 18:18 ` Roberto Sassu
  2023-03-06 10:28   ` Christian Brauner
  2023-03-03 18:18 ` [PATCH 13/28] security: Align inode_setattr hook definition with EVM Roberto Sassu
                   ` (16 subsequent siblings)
  28 siblings, 1 reply; 79+ messages in thread
From: Roberto Sassu @ 2023-03-03 18:18 UTC (permalink / raw)
  To: viro, chuck.lever, jlayton, zohar, dmitry.kasatkin, paul,
	jmorris, serge, dhowells, jarkko, stephen.smalley.work, eparis,
	casey, brauner
  Cc: linux-fsdevel, linux-nfs, linux-integrity, linux-security-module,
	keyrings, selinux, linux-kernel, stefanb, Roberto Sassu

From: Roberto Sassu <roberto.sassu@huawei.com>

Update the description of vfs_tmpfile() to match the current parameters of
that function.

Fixes: 9751b338656f ("vfs: move open right after ->tmpfile()")
Signed-off-by: Roberto Sassu <roberto.sassu@huawei.com>
---
 fs/namei.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/fs/namei.c b/fs/namei.c
index 57727a1ae38..b4c52c4890b 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -3574,9 +3574,9 @@ static int do_open(struct nameidata *nd,
 /**
  * vfs_tmpfile - create tmpfile
  * @idmap:	idmap of the mount the inode was found from
- * @dentry:	pointer to dentry of the base directory
+ * @parentpath:	pointer to the path of the base directory
+ * @file:	file descriptor of the new tmpfile
  * @mode:	mode of the new tmpfile
- * @open_flag:	flags
  *
  * Create a temporary file.
  *
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 79+ messages in thread

* [PATCH 13/28] security: Align inode_setattr hook definition with EVM
  2023-03-03 18:18 [PATCH 00/28] security: Move IMA and EVM to the LSM infrastructure Roberto Sassu
                   ` (11 preceding siblings ...)
  2023-03-03 18:18 ` [PATCH 12/28] fs: Fix description of vfs_tmpfile() Roberto Sassu
@ 2023-03-03 18:18 ` Roberto Sassu
  2023-03-05  0:42   ` Casey Schaufler
  2023-03-06 17:06   ` Stefan Berger
  2023-03-03 18:18 ` [PATCH 14/28] security: Introduce inode_post_setattr hook Roberto Sassu
                   ` (15 subsequent siblings)
  28 siblings, 2 replies; 79+ messages in thread
From: Roberto Sassu @ 2023-03-03 18:18 UTC (permalink / raw)
  To: viro, chuck.lever, jlayton, zohar, dmitry.kasatkin, paul,
	jmorris, serge, dhowells, jarkko, stephen.smalley.work, eparis,
	casey, brauner
  Cc: linux-fsdevel, linux-nfs, linux-integrity, linux-security-module,
	keyrings, selinux, linux-kernel, stefanb, Roberto Sassu

From: Roberto Sassu <roberto.sassu@huawei.com>

Add the idmap parameter to the definition, so that evm_inode_setattr() can
be registered as this hook implementation.

Signed-off-by: Roberto Sassu <roberto.sassu@huawei.com>
---
 include/linux/lsm_hook_defs.h | 3 ++-
 security/security.c           | 2 +-
 security/selinux/hooks.c      | 3 ++-
 security/smack/smack_lsm.c    | 4 +++-
 4 files changed, 8 insertions(+), 4 deletions(-)

diff --git a/include/linux/lsm_hook_defs.h b/include/linux/lsm_hook_defs.h
index 2e10945622a..4372a6b2632 100644
--- a/include/linux/lsm_hook_defs.h
+++ b/include/linux/lsm_hook_defs.h
@@ -133,7 +133,8 @@ LSM_HOOK(int, 0, inode_readlink, struct dentry *dentry)
 LSM_HOOK(int, 0, inode_follow_link, struct dentry *dentry, struct inode *inode,
 	 bool rcu)
 LSM_HOOK(int, 0, inode_permission, struct inode *inode, int mask)
-LSM_HOOK(int, 0, inode_setattr, struct dentry *dentry, struct iattr *attr)
+LSM_HOOK(int, 0, inode_setattr, struct mnt_idmap *idmap, struct dentry *dentry,
+	 struct iattr *attr)
 LSM_HOOK(int, 0, inode_getattr, const struct path *path)
 LSM_HOOK(int, 0, inode_setxattr, struct mnt_idmap *idmap,
 	 struct dentry *dentry, const char *name, const void *value,
diff --git a/security/security.c b/security/security.c
index df6714aa19d..f7fe252e9d3 100644
--- a/security/security.c
+++ b/security/security.c
@@ -2168,7 +2168,7 @@ int security_inode_setattr(struct mnt_idmap *idmap,
 
 	if (unlikely(IS_PRIVATE(d_backing_inode(dentry))))
 		return 0;
-	ret = call_int_hook(inode_setattr, 0, dentry, attr);
+	ret = call_int_hook(inode_setattr, 0, idmap, dentry, attr);
 	if (ret)
 		return ret;
 	return evm_inode_setattr(idmap, dentry, attr);
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 3e4308dd336..b31ad6109b0 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -3104,7 +3104,8 @@ static int selinux_inode_permission(struct inode *inode, int mask)
 	return rc;
 }
 
-static int selinux_inode_setattr(struct dentry *dentry, struct iattr *iattr)
+static int selinux_inode_setattr(struct mnt_idmap *idmap, struct dentry *dentry,
+				 struct iattr *iattr)
 {
 	const struct cred *cred = current_cred();
 	struct inode *inode = d_backing_inode(dentry);
diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c
index 598b398c62e..09cfd3c31dc 100644
--- a/security/smack/smack_lsm.c
+++ b/security/smack/smack_lsm.c
@@ -1173,12 +1173,14 @@ static int smack_inode_permission(struct inode *inode, int mask)
 
 /**
  * smack_inode_setattr - Smack check for setting attributes
+ * @idmap: idmap of the mount
  * @dentry: the object
  * @iattr: for the force flag
  *
  * Returns 0 if access is permitted, an error code otherwise
  */
-static int smack_inode_setattr(struct dentry *dentry, struct iattr *iattr)
+static int smack_inode_setattr(struct mnt_idmap *idmap, struct dentry *dentry,
+			       struct iattr *iattr)
 {
 	struct smk_audit_info ad;
 	int rc;
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 79+ messages in thread

* [PATCH 14/28] security: Introduce inode_post_setattr hook
  2023-03-03 18:18 [PATCH 00/28] security: Move IMA and EVM to the LSM infrastructure Roberto Sassu
                   ` (12 preceding siblings ...)
  2023-03-03 18:18 ` [PATCH 13/28] security: Align inode_setattr hook definition with EVM Roberto Sassu
@ 2023-03-03 18:18 ` Roberto Sassu
  2023-03-06 17:08   ` Stefan Berger
  2023-03-08 15:19   ` Mimi Zohar
  2023-03-03 18:18 ` [PATCH 15/28] security: Introduce inode_post_removexattr hook Roberto Sassu
                   ` (14 subsequent siblings)
  28 siblings, 2 replies; 79+ messages in thread
From: Roberto Sassu @ 2023-03-03 18:18 UTC (permalink / raw)
  To: viro, chuck.lever, jlayton, zohar, dmitry.kasatkin, paul,
	jmorris, serge, dhowells, jarkko, stephen.smalley.work, eparis,
	casey, brauner
  Cc: linux-fsdevel, linux-nfs, linux-integrity, linux-security-module,
	keyrings, selinux, linux-kernel, stefanb, Roberto Sassu

From: Roberto Sassu <roberto.sassu@huawei.com>

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

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

diff --git a/fs/attr.c b/fs/attr.c
index da45cf01be6..343d6d62435 100644
--- a/fs/attr.c
+++ b/fs/attr.c
@@ -485,6 +485,7 @@ int notify_change(struct mnt_idmap *idmap, struct dentry *dentry,
 
 	if (!error) {
 		fsnotify_change(dentry, ia_valid);
+		security_inode_post_setattr(idmap, dentry, ia_valid);
 		ima_inode_post_setattr(idmap, dentry, ia_valid);
 		evm_inode_post_setattr(idmap, dentry, ia_valid);
 	}
diff --git a/include/linux/lsm_hook_defs.h b/include/linux/lsm_hook_defs.h
index 4372a6b2632..eedefbcdde3 100644
--- a/include/linux/lsm_hook_defs.h
+++ b/include/linux/lsm_hook_defs.h
@@ -135,6 +135,8 @@ LSM_HOOK(int, 0, inode_follow_link, struct dentry *dentry, struct inode *inode,
 LSM_HOOK(int, 0, inode_permission, struct inode *inode, int mask)
 LSM_HOOK(int, 0, inode_setattr, struct mnt_idmap *idmap, struct dentry *dentry,
 	 struct iattr *attr)
+LSM_HOOK(void, LSM_RET_VOID, inode_post_setattr, struct mnt_idmap *idmap,
+	 struct dentry *dentry, int ia_valid)
 LSM_HOOK(int, 0, inode_getattr, const struct path *path)
 LSM_HOOK(int, 0, inode_setxattr, struct mnt_idmap *idmap,
 	 struct dentry *dentry, const char *name, const void *value,
diff --git a/include/linux/security.h b/include/linux/security.h
index cd23221ce9e..64224216f6c 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -354,6 +354,8 @@ int security_inode_follow_link(struct dentry *dentry, struct inode *inode,
 int security_inode_permission(struct inode *inode, int mask);
 int security_inode_setattr(struct mnt_idmap *idmap,
 			   struct dentry *dentry, struct iattr *attr);
+void security_inode_post_setattr(struct mnt_idmap *idmap, struct dentry *dentry,
+				 int ia_valid);
 int security_inode_getattr(const struct path *path);
 int security_inode_setxattr(struct mnt_idmap *idmap,
 			    struct dentry *dentry, const char *name,
@@ -855,6 +857,11 @@ static inline int security_inode_setattr(struct mnt_idmap *idmap,
 	return 0;
 }
 
+static inline void
+security_inode_post_setattr(struct mnt_idmap *idmap, struct dentry *dentry,
+			    int ia_valid)
+{ }
+
 static inline int security_inode_getattr(const struct path *path)
 {
 	return 0;
diff --git a/security/security.c b/security/security.c
index f7fe252e9d3..2dbf225f5d8 100644
--- a/security/security.c
+++ b/security/security.c
@@ -2190,6 +2190,22 @@ int security_inode_getattr(const struct path *path)
 	return call_int_hook(inode_getattr, 0, path);
 }
 
+/**
+ * security_inode_post_setattr() - Update the inode after a setattr operation
+ * @idmap: idmap of the mount
+ * @dentry: file
+ * @ia_valid: file attributes set
+ *
+ * Update inode security field after successful setting file attributes.
+ */
+void security_inode_post_setattr(struct mnt_idmap *idmap, struct dentry *dentry,
+				 int ia_valid)
+{
+	if (unlikely(IS_PRIVATE(d_backing_inode(dentry))))
+		return;
+	call_void_hook(inode_post_setattr, idmap, dentry, ia_valid);
+}
+
 /**
  * security_inode_setxattr() - Check if setting file xattrs is allowed
  * @idmap: idmap of the mount
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 79+ messages in thread

* [PATCH 15/28] security: Introduce inode_post_removexattr hook
  2023-03-03 18:18 [PATCH 00/28] security: Move IMA and EVM to the LSM infrastructure Roberto Sassu
                   ` (13 preceding siblings ...)
  2023-03-03 18:18 ` [PATCH 14/28] security: Introduce inode_post_setattr hook Roberto Sassu
@ 2023-03-03 18:18 ` Roberto Sassu
  2023-03-06 19:17   ` Stefan Berger
  2023-03-08 15:43   ` Mimi Zohar
  2023-03-03 18:18 ` [PATCH 16/28] security: Introduce file_post_open hook Roberto Sassu
                   ` (13 subsequent siblings)
  28 siblings, 2 replies; 79+ messages in thread
From: Roberto Sassu @ 2023-03-03 18:18 UTC (permalink / raw)
  To: viro, chuck.lever, jlayton, zohar, dmitry.kasatkin, paul,
	jmorris, serge, dhowells, jarkko, stephen.smalley.work, eparis,
	casey, brauner
  Cc: linux-fsdevel, linux-nfs, linux-integrity, linux-security-module,
	keyrings, selinux, linux-kernel, stefanb, Roberto Sassu

From: Roberto Sassu <roberto.sassu@huawei.com>

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

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

diff --git a/fs/xattr.c b/fs/xattr.c
index 14a7eb3c8fa..10c959d9fc6 100644
--- a/fs/xattr.c
+++ b/fs/xattr.c
@@ -534,6 +534,7 @@ __vfs_removexattr_locked(struct mnt_idmap *idmap,
 
 	if (!error) {
 		fsnotify_xattr(dentry);
+		security_inode_post_removexattr(dentry, name);
 		evm_inode_post_removexattr(dentry, name);
 	}
 
diff --git a/include/linux/lsm_hook_defs.h b/include/linux/lsm_hook_defs.h
index eedefbcdde3..2ae5224d967 100644
--- a/include/linux/lsm_hook_defs.h
+++ b/include/linux/lsm_hook_defs.h
@@ -147,6 +147,8 @@ LSM_HOOK(int, 0, inode_getxattr, struct dentry *dentry, const char *name)
 LSM_HOOK(int, 0, inode_listxattr, struct dentry *dentry)
 LSM_HOOK(int, 0, inode_removexattr, struct mnt_idmap *idmap,
 	 struct dentry *dentry, const char *name)
+LSM_HOOK(void, LSM_RET_VOID, inode_post_removexattr, struct dentry *dentry,
+	 const char *name)
 LSM_HOOK(int, 0, inode_set_acl, struct mnt_idmap *idmap,
 	 struct dentry *dentry, const char *acl_name, struct posix_acl *kacl)
 LSM_HOOK(int, 0, inode_get_acl, struct mnt_idmap *idmap,
diff --git a/include/linux/security.h b/include/linux/security.h
index 64224216f6c..b511f608958 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -373,6 +373,7 @@ int security_inode_getxattr(struct dentry *dentry, const char *name);
 int security_inode_listxattr(struct dentry *dentry);
 int security_inode_removexattr(struct mnt_idmap *idmap,
 			       struct dentry *dentry, const char *name);
+void security_inode_post_removexattr(struct dentry *dentry, const char *name);
 int security_inode_need_killpriv(struct dentry *dentry);
 int security_inode_killpriv(struct mnt_idmap *idmap, struct dentry *dentry);
 int security_inode_getsecurity(struct mnt_idmap *idmap,
@@ -918,6 +919,10 @@ static inline int security_inode_removexattr(struct mnt_idmap *idmap,
 	return cap_inode_removexattr(idmap, dentry, name);
 }
 
+static inline void security_inode_post_removexattr(struct dentry *dentry,
+						   const char *name)
+{ }
+
 static inline int security_inode_need_killpriv(struct dentry *dentry)
 {
 	return cap_inode_need_killpriv(dentry);
diff --git a/security/security.c b/security/security.c
index 2dbf225f5d8..6bf4a92db94 100644
--- a/security/security.c
+++ b/security/security.c
@@ -2404,6 +2404,20 @@ int security_inode_removexattr(struct mnt_idmap *idmap,
 	return evm_inode_removexattr(idmap, dentry, name);
 }
 
+/**
+ * security_inode_post_removexattr() - Update the inode after a removexattr op
+ * @dentry: file
+ * @name: xattr name
+ *
+ * Update the inode after a successful removexattr operation.
+ */
+void security_inode_post_removexattr(struct dentry *dentry, const char *name)
+{
+	if (unlikely(IS_PRIVATE(d_backing_inode(dentry))))
+		return;
+	call_void_hook(inode_post_removexattr, dentry, name);
+}
+
 /**
  * security_inode_need_killpriv() - Check if security_inode_killpriv() required
  * @dentry: associated dentry
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 79+ messages in thread

* [PATCH 16/28] security: Introduce file_post_open hook
  2023-03-03 18:18 [PATCH 00/28] security: Move IMA and EVM to the LSM infrastructure Roberto Sassu
                   ` (14 preceding siblings ...)
  2023-03-03 18:18 ` [PATCH 15/28] security: Introduce inode_post_removexattr hook Roberto Sassu
@ 2023-03-03 18:18 ` Roberto Sassu
  2023-03-06 19:24   ` Stefan Berger
  2023-03-03 18:18 ` [PATCH 17/28] security: Introduce file_pre_free_security hook Roberto Sassu
                   ` (12 subsequent siblings)
  28 siblings, 1 reply; 79+ messages in thread
From: Roberto Sassu @ 2023-03-03 18:18 UTC (permalink / raw)
  To: viro, chuck.lever, jlayton, zohar, dmitry.kasatkin, paul,
	jmorris, serge, dhowells, jarkko, stephen.smalley.work, eparis,
	casey, brauner
  Cc: linux-fsdevel, linux-nfs, linux-integrity, linux-security-module,
	keyrings, selinux, linux-kernel, stefanb, Roberto Sassu

From: Roberto Sassu <roberto.sassu@huawei.com>

In preparation to move IMA and EVM to the LSM infrastructure, introduce the
file_post_open hook. Also, export security_file_post_open() for NFS.

Signed-off-by: Roberto Sassu <roberto.sassu@huawei.com>
---
 fs/namei.c                    |  2 ++
 fs/nfsd/vfs.c                 |  6 ++++++
 include/linux/lsm_hook_defs.h |  1 +
 include/linux/security.h      |  6 ++++++
 security/security.c           | 17 +++++++++++++++++
 5 files changed, 32 insertions(+)

diff --git a/fs/namei.c b/fs/namei.c
index b4c52c4890b..41f7fdf4657 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -3558,6 +3558,8 @@ static int do_open(struct nameidata *nd,
 	error = may_open(idmap, &nd->path, acc_mode, open_flag);
 	if (!error && !(file->f_mode & FMODE_OPENED))
 		error = vfs_open(&nd->path, file);
+	if (!error)
+		error = security_file_post_open(file, op->acc_mode);
 	if (!error)
 		error = ima_file_check(file, op->acc_mode);
 	if (!error && do_truncate)
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c
index e7462b5e5f1..4b86c158ffb 100644
--- a/fs/nfsd/vfs.c
+++ b/fs/nfsd/vfs.c
@@ -852,6 +852,12 @@ __nfsd_open(struct svc_rqst *rqstp, struct svc_fh *fhp, umode_t type,
 		goto out_nfserr;
 	}
 
+	host_err = security_file_post_open(file, may_flags);
+	if (host_err) {
+		fput(file);
+		goto out_nfserr;
+	}
+
 	host_err = ima_file_check(file, may_flags);
 	if (host_err) {
 		fput(file);
diff --git a/include/linux/lsm_hook_defs.h b/include/linux/lsm_hook_defs.h
index 2ae5224d967..5d4e256e250 100644
--- a/include/linux/lsm_hook_defs.h
+++ b/include/linux/lsm_hook_defs.h
@@ -187,6 +187,7 @@ LSM_HOOK(int, 0, file_send_sigiotask, struct task_struct *tsk,
 	 struct fown_struct *fown, int sig)
 LSM_HOOK(int, 0, file_receive, struct file *file)
 LSM_HOOK(int, 0, file_open, struct file *file)
+LSM_HOOK(int, 0, file_post_open, struct file *file, int mask)
 LSM_HOOK(int, 0, file_truncate, struct file *file)
 LSM_HOOK(int, 0, task_alloc, struct task_struct *task,
 	 unsigned long clone_flags)
diff --git a/include/linux/security.h b/include/linux/security.h
index b511f608958..4fdc62a1b42 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -402,6 +402,7 @@ int security_file_send_sigiotask(struct task_struct *tsk,
 				 struct fown_struct *fown, int sig);
 int security_file_receive(struct file *file);
 int security_file_open(struct file *file);
+int security_file_post_open(struct file *file, int mask);
 int security_file_truncate(struct file *file);
 int security_task_alloc(struct task_struct *task, unsigned long clone_flags);
 void security_task_free(struct task_struct *task);
@@ -1043,6 +1044,11 @@ static inline int security_file_open(struct file *file)
 	return 0;
 }
 
+static inline int security_file_post_open(struct file *file, int mask)
+{
+	return 0;
+}
+
 static inline int security_file_truncate(struct file *file)
 {
 	return 0;
diff --git a/security/security.c b/security/security.c
index 6bf4a92db94..e252c87df4f 100644
--- a/security/security.c
+++ b/security/security.c
@@ -2906,6 +2906,23 @@ int security_file_open(struct file *file)
 	return fsnotify_perm(file, MAY_OPEN);
 }
 
+/**
+ * security_file_post_open() - Recheck access to a file after it has been opened
+ * @file: the file
+ * @mask: access mask
+ *
+ * Recheck access with mask after the file has been opened. The hook is useful
+ * for LSMs that require the file content to be available in order to make
+ * decisions.
+ *
+ * Return: Returns 0 if permission is granted.
+ */
+int security_file_post_open(struct file *file, int mask)
+{
+	return call_int_hook(file_post_open, 0, file, mask);
+}
+EXPORT_SYMBOL_GPL(security_file_post_open);
+
 /**
  * security_file_truncate() - Check if truncating a file is allowed
  * @file: file
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 79+ messages in thread

* [PATCH 17/28] security: Introduce file_pre_free_security hook
  2023-03-03 18:18 [PATCH 00/28] security: Move IMA and EVM to the LSM infrastructure Roberto Sassu
                   ` (15 preceding siblings ...)
  2023-03-03 18:18 ` [PATCH 16/28] security: Introduce file_post_open hook Roberto Sassu
@ 2023-03-03 18:18 ` Roberto Sassu
  2023-03-06 19:26   ` Stefan Berger
  2023-03-03 18:18 ` [PATCH 18/28] security: Introduce path_post_mknod hook Roberto Sassu
                   ` (11 subsequent siblings)
  28 siblings, 1 reply; 79+ messages in thread
From: Roberto Sassu @ 2023-03-03 18:18 UTC (permalink / raw)
  To: viro, chuck.lever, jlayton, zohar, dmitry.kasatkin, paul,
	jmorris, serge, dhowells, jarkko, stephen.smalley.work, eparis,
	casey, brauner
  Cc: linux-fsdevel, linux-nfs, linux-integrity, linux-security-module,
	keyrings, selinux, linux-kernel, stefanb, Roberto Sassu

From: Roberto Sassu <roberto.sassu@huawei.com>

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

Signed-off-by: Roberto Sassu <roberto.sassu@huawei.com>
---
 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 372653b9261..3150e613aec 100644
--- a/fs/file_table.c
+++ b/fs/file_table.c
@@ -312,6 +312,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 5d4e256e250..4580912051a 100644
--- a/include/linux/lsm_hook_defs.h
+++ b/include/linux/lsm_hook_defs.h
@@ -171,6 +171,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 4fdc62a1b42..88e88280f7d 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -388,6 +388,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,
@@ -984,6 +985,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 e252c87df4f..6cbbb4289f7 100644
--- a/security/security.c
+++ b/security/security.c
@@ -2676,6 +2676,17 @@ int security_file_alloc(struct file *file)
 	return rc;
 }
 
+/**
+ * security_file_pre_free() - Perform actions before freeing a file's LSM blob
+ * @file: the file
+ *
+ * Perform actions before the file descriptor is freed.
+ */
+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.25.1


^ permalink raw reply related	[flat|nested] 79+ messages in thread

* [PATCH 18/28] security: Introduce path_post_mknod hook
  2023-03-03 18:18 [PATCH 00/28] security: Move IMA and EVM to the LSM infrastructure Roberto Sassu
                   ` (16 preceding siblings ...)
  2023-03-03 18:18 ` [PATCH 17/28] security: Introduce file_pre_free_security hook Roberto Sassu
@ 2023-03-03 18:18 ` Roberto Sassu
  2023-03-06 19:29   ` Stefan Berger
  2023-03-08 15:47   ` Mimi Zohar
  2023-03-03 18:18 ` [PATCH 19/28] security: Introduce inode_post_create_tmpfile hook Roberto Sassu
                   ` (10 subsequent siblings)
  28 siblings, 2 replies; 79+ messages in thread
From: Roberto Sassu @ 2023-03-03 18:18 UTC (permalink / raw)
  To: viro, chuck.lever, jlayton, zohar, dmitry.kasatkin, paul,
	jmorris, serge, dhowells, jarkko, stephen.smalley.work, eparis,
	casey, brauner
  Cc: linux-fsdevel, linux-nfs, linux-integrity, linux-security-module,
	keyrings, selinux, linux-kernel, stefanb, Roberto Sassu

From: Roberto Sassu <roberto.sassu@huawei.com>

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

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

diff --git a/fs/namei.c b/fs/namei.c
index 41f7fdf4657..3f2747521d3 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -3980,6 +3980,8 @@ static int do_mknodat(int dfd, struct filename *name, umode_t mode,
 					  dentry, mode, 0);
 			break;
 	}
+	if (!error)
+		security_path_post_mknod(idmap, &path, dentry, mode, dev);
 out2:
 	done_path_create(&path, dentry);
 	if (retry_estale(error, lookup_flags)) {
diff --git a/include/linux/lsm_hook_defs.h b/include/linux/lsm_hook_defs.h
index 4580912051a..32c801a3ea2 100644
--- a/include/linux/lsm_hook_defs.h
+++ b/include/linux/lsm_hook_defs.h
@@ -93,6 +93,9 @@ LSM_HOOK(int, 0, path_mkdir, const struct path *dir, struct dentry *dentry,
 LSM_HOOK(int, 0, path_rmdir, const struct path *dir, struct dentry *dentry)
 LSM_HOOK(int, 0, path_mknod, const struct path *dir, struct dentry *dentry,
 	 umode_t mode, unsigned int dev)
+LSM_HOOK(void, LSM_RET_VOID, path_post_mknod, struct mnt_idmap *idmap,
+	 const struct path *dir, struct dentry *dentry, umode_t mode,
+	 unsigned int dev)
 LSM_HOOK(int, 0, path_truncate, const struct path *path)
 LSM_HOOK(int, 0, path_symlink, const struct path *dir, struct dentry *dentry,
 	 const char *old_name)
diff --git a/include/linux/security.h b/include/linux/security.h
index 88e88280f7d..fb6e9d434c6 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -1835,6 +1835,9 @@ int security_path_mkdir(const struct path *dir, struct dentry *dentry, umode_t m
 int security_path_rmdir(const struct path *dir, struct dentry *dentry);
 int security_path_mknod(const struct path *dir, struct dentry *dentry, umode_t mode,
 			unsigned int dev);
+void security_path_post_mknod(struct mnt_idmap *idmap, const struct path *dir,
+			      struct dentry *dentry, umode_t mode,
+			      unsigned int dev);
 int security_path_truncate(const struct path *path);
 int security_path_symlink(const struct path *dir, struct dentry *dentry,
 			  const char *old_name);
@@ -1869,6 +1872,12 @@ static inline int security_path_mknod(const struct path *dir, struct dentry *den
 	return 0;
 }
 
+static inline void security_path_post_mknod(struct mnt_idmap *idmap,
+					    const struct path *dir,
+					    struct dentry *dentry, umode_t mode,
+					    unsigned int dev)
+{ }
+
 static inline int security_path_truncate(const struct path *path)
 {
 	return 0;
diff --git a/security/security.c b/security/security.c
index 6cbbb4289f7..f5f367e2064 100644
--- a/security/security.c
+++ b/security/security.c
@@ -1753,6 +1753,25 @@ int security_path_mknod(const struct path *dir, struct dentry *dentry,
 }
 EXPORT_SYMBOL(security_path_mknod);
 
+/**
+ * security_path_post_mknod() - Update inode security field after file creation
+ * @idmap: idmap of the mount
+ * @dir: parent directory
+ * @dentry: new file
+ * @mode: new file mode
+ * @dev: device number
+ *
+ * Update inode security field after a file has been created.
+ */
+void security_path_post_mknod(struct mnt_idmap *idmap, const struct path *dir,
+			      struct dentry *dentry, umode_t mode,
+			      unsigned int dev)
+{
+	if (unlikely(IS_PRIVATE(d_backing_inode(dir->dentry))))
+		return;
+	call_void_hook(path_post_mknod, idmap, dir, dentry, mode, dev);
+}
+
 /**
  * security_path_mkdir() - Check if creating a new directory is allowed
  * @dir: parent directory
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 79+ messages in thread

* [PATCH 19/28] security: Introduce inode_post_create_tmpfile hook
  2023-03-03 18:18 [PATCH 00/28] security: Move IMA and EVM to the LSM infrastructure Roberto Sassu
                   ` (17 preceding siblings ...)
  2023-03-03 18:18 ` [PATCH 18/28] security: Introduce path_post_mknod hook Roberto Sassu
@ 2023-03-03 18:18 ` Roberto Sassu
  2023-03-06 19:35   ` Stefan Berger
  2023-03-03 18:18 ` [PATCH 20/28] security: Introduce inode_post_set_acl hook Roberto Sassu
                   ` (9 subsequent siblings)
  28 siblings, 1 reply; 79+ messages in thread
From: Roberto Sassu @ 2023-03-03 18:18 UTC (permalink / raw)
  To: viro, chuck.lever, jlayton, zohar, dmitry.kasatkin, paul,
	jmorris, serge, dhowells, jarkko, stephen.smalley.work, eparis,
	casey, brauner
  Cc: linux-fsdevel, linux-nfs, linux-integrity, linux-security-module,
	keyrings, selinux, linux-kernel, stefanb, Roberto Sassu

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.

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 3f2747521d3..8c4fdfd81d4 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -3624,6 +3624,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_dentry(file), mode);
 	ima_post_create_tmpfile(idmap, dir, file_dentry(file), mode);
 	return 0;
 }
diff --git a/include/linux/lsm_hook_defs.h b/include/linux/lsm_hook_defs.h
index 32c801a3ea2..5dc2a7c3d9a 100644
--- a/include/linux/lsm_hook_defs.h
+++ b/include/linux/lsm_hook_defs.h
@@ -120,6 +120,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 dentry *dentry, 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 fb6e9d434c6..b3e201404dc 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -337,6 +337,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 dentry *dentry, 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);
@@ -787,6 +790,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 dentry *dentry, 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 f5f367e2064..8883082b686 100644
--- a/security/security.c
+++ b/security/security.c
@@ -1971,6 +1971,24 @@ int security_inode_create(struct inode *dir, struct dentry *dentry,
 }
 EXPORT_SYMBOL_GPL(security_inode_create);
 
+/**
+ * security_inode_post_create_tmpfile() - Update inode sec after tmpfile created
+ * @idmap: idmap of the mount
+ * @dir: the inode of the base directory
+ * @dentry: the dentry 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 dentry *dentry, umode_t mode)
+{
+	if (unlikely(IS_PRIVATE(dir)))
+		return;
+	call_void_hook(inode_post_create_tmpfile, idmap, dir, dentry, mode);
+}
+
 /**
  * security_inode_link() - Check if creating a hard link is allowed
  * @old_dentry: existing file
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 79+ messages in thread

* [PATCH 20/28] security: Introduce inode_post_set_acl hook
  2023-03-03 18:18 [PATCH 00/28] security: Move IMA and EVM to the LSM infrastructure Roberto Sassu
                   ` (18 preceding siblings ...)
  2023-03-03 18:18 ` [PATCH 19/28] security: Introduce inode_post_create_tmpfile hook Roberto Sassu
@ 2023-03-03 18:18 ` Roberto Sassu
  2023-03-06 19:45   ` Stefan Berger
  2023-03-03 18:18 ` [PATCH 21/28] security: Introduce inode_post_remove_acl hook Roberto Sassu
                   ` (8 subsequent siblings)
  28 siblings, 1 reply; 79+ messages in thread
From: Roberto Sassu @ 2023-03-03 18:18 UTC (permalink / raw)
  To: viro, chuck.lever, jlayton, zohar, dmitry.kasatkin, paul,
	jmorris, serge, dhowells, jarkko, stephen.smalley.work, eparis,
	casey, brauner
  Cc: linux-fsdevel, linux-nfs, linux-integrity, linux-security-module,
	keyrings, selinux, linux-kernel, stefanb, Roberto Sassu

From: Roberto Sassu <roberto.sassu@huawei.com>

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

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

diff --git a/fs/posix_acl.c b/fs/posix_acl.c
index 5a76fb35923..acddf2dff4c 100644
--- a/fs/posix_acl.c
+++ b/fs/posix_acl.c
@@ -1102,6 +1102,7 @@ int vfs_set_acl(struct mnt_idmap *idmap, struct dentry *dentry,
 		error = -EOPNOTSUPP;
 	if (!error) {
 		fsnotify_xattr(dentry);
+		security_inode_post_set_acl(dentry, acl_name, kacl);
 		evm_inode_post_set_acl(dentry, acl_name, kacl);
 	}
 
diff --git a/include/linux/lsm_hook_defs.h b/include/linux/lsm_hook_defs.h
index 5dc2a7c3d9a..9a3e14db0af 100644
--- a/include/linux/lsm_hook_defs.h
+++ b/include/linux/lsm_hook_defs.h
@@ -156,6 +156,8 @@ LSM_HOOK(void, LSM_RET_VOID, inode_post_removexattr, struct dentry *dentry,
 	 const char *name)
 LSM_HOOK(int, 0, inode_set_acl, struct mnt_idmap *idmap,
 	 struct dentry *dentry, const char *acl_name, struct posix_acl *kacl)
+LSM_HOOK(void, LSM_RET_VOID, inode_post_set_acl, struct dentry *dentry,
+	 const char *acl_name, struct posix_acl *kacl)
 LSM_HOOK(int, 0, inode_get_acl, struct mnt_idmap *idmap,
 	 struct dentry *dentry, const char *acl_name)
 LSM_HOOK(int, 0, inode_remove_acl, struct mnt_idmap *idmap,
diff --git a/include/linux/security.h b/include/linux/security.h
index b3e201404dc..b0691bf7237 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -366,6 +366,8 @@ int security_inode_setxattr(struct mnt_idmap *idmap,
 int security_inode_set_acl(struct mnt_idmap *idmap,
 			   struct dentry *dentry, const char *acl_name,
 			   struct posix_acl *kacl);
+void security_inode_post_set_acl(struct dentry *dentry, const char *acl_name,
+				 struct posix_acl *kacl);
 int security_inode_get_acl(struct mnt_idmap *idmap,
 			   struct dentry *dentry, const char *acl_name);
 int security_inode_remove_acl(struct mnt_idmap *idmap,
@@ -893,6 +895,11 @@ static inline int security_inode_set_acl(struct mnt_idmap *idmap,
 	return 0;
 }
 
+static inline void security_inode_post_set_acl(struct dentry *dentry,
+					       const char *acl_name,
+					       struct posix_acl *kacl)
+{ }
+
 static inline int security_inode_get_acl(struct mnt_idmap *idmap,
 					 struct dentry *dentry,
 					 const char *acl_name)
diff --git a/security/security.c b/security/security.c
index 8883082b686..fc11d70bb02 100644
--- a/security/security.c
+++ b/security/security.c
@@ -2310,6 +2310,23 @@ int security_inode_set_acl(struct mnt_idmap *idmap,
 	return evm_inode_set_acl(idmap, dentry, acl_name, kacl);
 }
 
+/**
+ * security_inode_post_set_acl() - Update inode sec after set_acl operation
+ * @dentry: file
+ * @acl_name: acl name
+ * @kacl: acl struct
+ *
+ * Update inode security field after successful set_acl operation on @dentry.
+ * The posix acls in @kacl are identified by @acl_name.
+ */
+void security_inode_post_set_acl(struct dentry *dentry, const char *acl_name,
+				 struct posix_acl *kacl)
+{
+	if (unlikely(IS_PRIVATE(d_backing_inode(dentry))))
+		return;
+	call_void_hook(inode_post_set_acl, dentry, acl_name, kacl);
+}
+
 /**
  * security_inode_get_acl() - Check if reading posix acls is allowed
  * @idmap: idmap of the mount
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 79+ messages in thread

* [PATCH 21/28] security: Introduce inode_post_remove_acl hook
  2023-03-03 18:18 [PATCH 00/28] security: Move IMA and EVM to the LSM infrastructure Roberto Sassu
                   ` (19 preceding siblings ...)
  2023-03-03 18:18 ` [PATCH 20/28] security: Introduce inode_post_set_acl hook Roberto Sassu
@ 2023-03-03 18:18 ` Roberto Sassu
  2023-03-06 15:22   ` Stefan Berger
  2023-03-03 18:18 ` [PATCH 22/28] security: Introduce key_post_create_or_update hook Roberto Sassu
                   ` (7 subsequent siblings)
  28 siblings, 1 reply; 79+ messages in thread
From: Roberto Sassu @ 2023-03-03 18:18 UTC (permalink / raw)
  To: viro, chuck.lever, jlayton, zohar, dmitry.kasatkin, paul,
	jmorris, serge, dhowells, jarkko, stephen.smalley.work, eparis,
	casey, brauner
  Cc: linux-fsdevel, linux-nfs, linux-integrity, linux-security-module,
	keyrings, selinux, linux-kernel, stefanb, Roberto Sassu

From: Roberto Sassu <roberto.sassu@huawei.com>

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

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

diff --git a/fs/posix_acl.c b/fs/posix_acl.c
index acddf2dff4c..5b8c92fce0c 100644
--- a/fs/posix_acl.c
+++ b/fs/posix_acl.c
@@ -1213,6 +1213,7 @@ int vfs_remove_acl(struct mnt_idmap *idmap, struct dentry *dentry,
 		error = -EOPNOTSUPP;
 	if (!error) {
 		fsnotify_xattr(dentry);
+		security_inode_post_remove_acl(idmap, dentry, acl_name);
 		evm_inode_post_remove_acl(idmap, dentry, acl_name);
 	}
 
diff --git a/include/linux/lsm_hook_defs.h b/include/linux/lsm_hook_defs.h
index 9a3e14db0af..6c324fe5099 100644
--- a/include/linux/lsm_hook_defs.h
+++ b/include/linux/lsm_hook_defs.h
@@ -162,6 +162,8 @@ LSM_HOOK(int, 0, inode_get_acl, struct mnt_idmap *idmap,
 	 struct dentry *dentry, const char *acl_name)
 LSM_HOOK(int, 0, inode_remove_acl, struct mnt_idmap *idmap,
 	 struct dentry *dentry, const char *acl_name)
+LSM_HOOK(void, LSM_RET_VOID, inode_post_remove_acl, struct mnt_idmap *idmap,
+	 struct dentry *dentry, const char *acl_name)
 LSM_HOOK(int, 0, inode_need_killpriv, struct dentry *dentry)
 LSM_HOOK(int, 0, inode_killpriv, struct mnt_idmap *idmap,
 	 struct dentry *dentry)
diff --git a/include/linux/security.h b/include/linux/security.h
index b0691bf7237..f8df5b69667 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -372,6 +372,9 @@ int security_inode_get_acl(struct mnt_idmap *idmap,
 			   struct dentry *dentry, const char *acl_name);
 int security_inode_remove_acl(struct mnt_idmap *idmap,
 			      struct dentry *dentry, const char *acl_name);
+void security_inode_post_remove_acl(struct mnt_idmap *idmap,
+				    struct dentry *dentry,
+				    const char *acl_name);
 void security_inode_post_setxattr(struct dentry *dentry, const char *name,
 				  const void *value, size_t size, int flags);
 int security_inode_getxattr(struct dentry *dentry, const char *name);
@@ -914,6 +917,11 @@ static inline int security_inode_remove_acl(struct mnt_idmap *idmap,
 	return 0;
 }
 
+static inline void security_inode_post_remove_acl(struct mnt_idmap *idmap,
+						  struct dentry *dentry,
+						  const char *acl_name)
+{ }
+
 static inline void security_inode_post_setxattr(struct dentry *dentry,
 		const char *name, const void *value, size_t size, int flags)
 { }
diff --git a/security/security.c b/security/security.c
index fc11d70bb02..b3a9c317f75 100644
--- a/security/security.c
+++ b/security/security.c
@@ -2373,6 +2373,23 @@ int security_inode_remove_acl(struct mnt_idmap *idmap,
 	return evm_inode_remove_acl(idmap, dentry, acl_name);
 }
 
+/**
+ * security_inode_post_remove_acl() - Update inode sec after remove_acl op
+ * @idmap: idmap of the mount
+ * @dentry: file
+ * @acl_name: acl name
+ *
+ * Update inode security field after successful remove_acl operation on @dentry
+ * in @idmap. The posix acls are identified by @acl_name.
+ */
+void security_inode_post_remove_acl(struct mnt_idmap *idmap,
+				    struct dentry *dentry, const char *acl_name)
+{
+	if (unlikely(IS_PRIVATE(d_backing_inode(dentry))))
+		return;
+	call_void_hook(inode_post_remove_acl, idmap, dentry, acl_name);
+}
+
 /**
  * security_inode_post_setxattr() - Update the inode after a setxattr operation
  * @dentry: file
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 79+ messages in thread

* [PATCH 22/28] security: Introduce key_post_create_or_update hook
  2023-03-03 18:18 [PATCH 00/28] security: Move IMA and EVM to the LSM infrastructure Roberto Sassu
                   ` (20 preceding siblings ...)
  2023-03-03 18:18 ` [PATCH 21/28] security: Introduce inode_post_remove_acl hook Roberto Sassu
@ 2023-03-03 18:18 ` Roberto Sassu
  2023-03-07 17:48   ` Stefan Berger
  2023-03-08 15:49   ` Mimi Zohar
  2023-03-03 18:25 ` [PATCH 23/28] security: Introduce LSM_ORDER_LAST Roberto Sassu
                   ` (6 subsequent siblings)
  28 siblings, 2 replies; 79+ messages in thread
From: Roberto Sassu @ 2023-03-03 18:18 UTC (permalink / raw)
  To: viro, chuck.lever, jlayton, zohar, dmitry.kasatkin, paul,
	jmorris, serge, dhowells, jarkko, stephen.smalley.work, eparis,
	casey, brauner
  Cc: linux-fsdevel, linux-nfs, linux-integrity, linux-security-module,
	keyrings, selinux, linux-kernel, stefanb, Roberto Sassu

From: Roberto Sassu <roberto.sassu@huawei.com>

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

Signed-off-by: Roberto Sassu <roberto.sassu@huawei.com>
---
 include/linux/lsm_hook_defs.h |  3 +++
 include/linux/security.h      | 11 +++++++++++
 security/keys/key.c           |  7 ++++++-
 security/security.c           | 19 +++++++++++++++++++
 4 files changed, 39 insertions(+), 1 deletion(-)

diff --git a/include/linux/lsm_hook_defs.h b/include/linux/lsm_hook_defs.h
index 6c324fe5099..cf171e65420 100644
--- a/include/linux/lsm_hook_defs.h
+++ b/include/linux/lsm_hook_defs.h
@@ -397,6 +397,9 @@ LSM_HOOK(void, LSM_RET_VOID, key_free, struct key *key)
 LSM_HOOK(int, 0, key_permission, key_ref_t key_ref, const struct cred *cred,
 	 enum key_need_perm need_perm)
 LSM_HOOK(int, 0, key_getsecurity, struct key *key, char **_buffer)
+LSM_HOOK(void, LSM_RET_VOID, key_post_create_or_update, struct key *keyring,
+	 struct key *key, const void *payload, size_t payload_len,
+	 unsigned long flags, bool create)
 #endif /* CONFIG_KEYS */
 
 #ifdef CONFIG_AUDIT
diff --git a/include/linux/security.h b/include/linux/security.h
index f8df5b69667..be23a303bba 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -1952,6 +1952,9 @@ void security_key_free(struct key *key);
 int security_key_permission(key_ref_t key_ref, const struct cred *cred,
 			    enum key_need_perm need_perm);
 int security_key_getsecurity(struct key *key, char **_buffer);
+void security_key_post_create_or_update(struct key *keyring, struct key *key,
+					const void *payload, size_t payload_len,
+					unsigned long flags, bool create);
 
 #else
 
@@ -1979,6 +1982,14 @@ static inline int security_key_getsecurity(struct key *key, char **_buffer)
 	return 0;
 }
 
+static inline void security_key_post_create_or_update(struct key *keyring,
+						      struct key *key,
+						      const void *payload,
+						      size_t payload_len,
+						      unsigned long flags,
+						      bool create)
+{ }
+
 #endif
 #endif /* CONFIG_KEYS */
 
diff --git a/security/keys/key.c b/security/keys/key.c
index 5c0c7df833f..0f9c6faf349 100644
--- a/security/keys/key.c
+++ b/security/keys/key.c
@@ -934,6 +934,8 @@ static key_ref_t __key_create_or_update(key_ref_t keyring_ref,
 		goto error_link_end;
 	}
 
+	security_key_post_create_or_update(keyring, key, payload, plen, flags,
+					   true);
 	ima_post_key_create_or_update(keyring, key, payload, plen,
 				      flags, true);
 
@@ -967,10 +969,13 @@ static key_ref_t __key_create_or_update(key_ref_t keyring_ref,
 
 	key_ref = __key_update(key_ref, &prep);
 
-	if (!IS_ERR(key_ref))
+	if (!IS_ERR(key_ref)) {
+		security_key_post_create_or_update(keyring, key, payload, plen,
+						   flags, false);
 		ima_post_key_create_or_update(keyring, key,
 					      payload, plen,
 					      flags, false);
+	}
 
 	goto error_free_prep;
 }
diff --git a/security/security.c b/security/security.c
index b3a9c317f75..322090a50cd 100644
--- a/security/security.c
+++ b/security/security.c
@@ -5195,6 +5195,25 @@ int security_key_getsecurity(struct key *key, char **_buffer)
 	*_buffer = NULL;
 	return call_int_hook(key_getsecurity, 0, key, _buffer);
 }
+
+/**
+ * security_key_post_create_or_update() - Tell caller of key creation or update
+ * @keyring: keyring to which the key is linked to
+ * @key: created or updated key
+ * @payload: data used to instantiate or update the key
+ * @payload_len: length of payload
+ * @flags: key flags
+ * @create: flag indicating whether the key was created or updated
+ *
+ * Notify the caller of a key creation or update.
+ */
+void security_key_post_create_or_update(struct key *keyring, struct key *key,
+					const void *payload, size_t payload_len,
+					unsigned long flags, bool create)
+{
+	call_void_hook(key_post_create_or_update, keyring, key, payload,
+		       payload_len, flags, create);
+}
 #endif	/* CONFIG_KEYS */
 
 #ifdef CONFIG_AUDIT
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 79+ messages in thread

* [PATCH 23/28] security: Introduce LSM_ORDER_LAST
  2023-03-03 18:18 [PATCH 00/28] security: Move IMA and EVM to the LSM infrastructure Roberto Sassu
                   ` (21 preceding siblings ...)
  2023-03-03 18:18 ` [PATCH 22/28] security: Introduce key_post_create_or_update hook Roberto Sassu
@ 2023-03-03 18:25 ` Roberto Sassu
  2023-03-07 18:04   ` Stefan Berger
  2023-03-08 13:13   ` Mimi Zohar
  2023-03-03 18:25 ` [PATCH 24/28] ima: Move to LSM infrastructure Roberto Sassu
                   ` (5 subsequent siblings)
  28 siblings, 2 replies; 79+ messages in thread
From: Roberto Sassu @ 2023-03-03 18:25 UTC (permalink / raw)
  To: viro, chuck.lever, jlayton, zohar, dmitry.kasatkin, paul,
	jmorris, serge, dhowells, jarkko, stephen.smalley.work, eparis,
	casey, brauner
  Cc: linux-fsdevel, linux-nfs, linux-integrity, linux-security-module,
	keyrings, selinux, linux-kernel, stefanb, Roberto Sassu

From: Roberto Sassu <roberto.sassu@huawei.com>

Introduce LSM_ORDER_LAST, to satisfy the requirement of LSMs willing to be
the last, e.g. the 'integrity' LSM, without changing the kernel command
line or configuration.

As for LSM_ORDER_FIRST, LSMs with LSM_ORDER_LAST are always enabled and put
at the end of the LSM list in no particular order.

Signed-off-by: Roberto Sassu <roberto.sassu@huawei.com>
---
 include/linux/lsm_hooks.h |  1 +
 security/security.c       | 12 +++++++++---
 2 files changed, 10 insertions(+), 3 deletions(-)

diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h
index 21a8ce23108..05c4b831d99 100644
--- a/include/linux/lsm_hooks.h
+++ b/include/linux/lsm_hooks.h
@@ -93,6 +93,7 @@ extern void security_add_hooks(struct security_hook_list *hooks, int count,
 enum lsm_order {
 	LSM_ORDER_FIRST = -1,	/* This is only for capabilities. */
 	LSM_ORDER_MUTABLE = 0,
+	LSM_ORDER_LAST = 1,
 };
 
 struct lsm_info {
diff --git a/security/security.c b/security/security.c
index 322090a50cd..24f52ba3218 100644
--- a/security/security.c
+++ b/security/security.c
@@ -284,9 +284,9 @@ static void __init ordered_lsm_parse(const char *order, const char *origin)
 		bool found = false;
 
 		for (lsm = __start_lsm_info; lsm < __end_lsm_info; lsm++) {
-			if (lsm->order == LSM_ORDER_MUTABLE &&
-			    strcmp(lsm->name, name) == 0) {
-				append_ordered_lsm(lsm, origin);
+			if (strcmp(lsm->name, name) == 0) {
+				if (lsm->order == LSM_ORDER_MUTABLE)
+					append_ordered_lsm(lsm, origin);
 				found = true;
 			}
 		}
@@ -306,6 +306,12 @@ static void __init ordered_lsm_parse(const char *order, const char *origin)
 		}
 	}
 
+	/* LSM_ORDER_LAST is always last. */
+	for (lsm = __start_lsm_info; lsm < __end_lsm_info; lsm++) {
+		if (lsm->order == LSM_ORDER_LAST)
+			append_ordered_lsm(lsm, "   last");
+	}
+
 	/* Disable all LSMs not in the ordered list. */
 	for (lsm = __start_lsm_info; lsm < __end_lsm_info; lsm++) {
 		if (exists_ordered_lsm(lsm))
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 79+ messages in thread

* [PATCH 24/28] ima: Move to LSM infrastructure
  2023-03-03 18:18 [PATCH 00/28] security: Move IMA and EVM to the LSM infrastructure Roberto Sassu
                   ` (22 preceding siblings ...)
  2023-03-03 18:25 ` [PATCH 23/28] security: Introduce LSM_ORDER_LAST Roberto Sassu
@ 2023-03-03 18:25 ` Roberto Sassu
  2023-03-03 18:25 ` [PATCH 25/28] ima: Move IMA-Appraisal " Roberto Sassu
                   ` (4 subsequent siblings)
  28 siblings, 0 replies; 79+ messages in thread
From: Roberto Sassu @ 2023-03-03 18:25 UTC (permalink / raw)
  To: viro, chuck.lever, jlayton, zohar, dmitry.kasatkin, paul,
	jmorris, serge, dhowells, jarkko, stephen.smalley.work, eparis,
	casey, brauner
  Cc: linux-fsdevel, linux-nfs, linux-integrity, linux-security-module,
	keyrings, selinux, linux-kernel, stefanb, Roberto Sassu

From: Roberto Sassu <roberto.sassu@huawei.com>

Remove hardcoded IMA function calls (not for appraisal) from the LSM
infrastructure, the VFS, NFS and the key subsystem.

Make those functions as static (except for ima_file_check() which is
exported, and ima_post_key_create_or_update(), which is not in ima_main.c),
and register them as implementation of the respective hooks in the new
function init_ima_lsm().

Call init_ima_lsm() from integrity_lsm_init() (renamed from
integrity_iintcache_init()), to make sure that the integrity subsystem is
ready at the time IMA hooks are registered. The same will be done for EVM,
by calling init_evm_lsm() just after init_ima_lsm().

Put 'integrity' at the end of the LSM list by setting the order to
LSM_ORDER_LAST. 'integrity' must be the last so that EVM can calculate the
HMAC on xattrs previously provided by the other selected LSMs.

Setting the order to LSM_ORDER_LAST also causes 'integrity' to be always
enabled regardless of the LSM choice. This avoids any risk that IMA and EVM
functions are not called when transitioning from an old kernel to one where
IMA and EVM are stacked.

Signed-off-by: Roberto Sassu <roberto.sassu@huawei.com>
---
 fs/file_table.c                   |   2 -
 fs/namei.c                        |   7 ---
 fs/nfsd/vfs.c                     |   7 ---
 fs/open.c                         |   1 -
 include/linux/ima.h               | 100 ------------------------------
 security/integrity/iint.c         |   8 ++-
 security/integrity/ima/ima.h      |   7 +++
 security/integrity/ima/ima_main.c |  64 +++++++++++++------
 security/integrity/integrity.h    |   8 +++
 security/keys/key.c               |   9 +--
 security/security.c               |  53 +++-------------
 11 files changed, 74 insertions(+), 192 deletions(-)

diff --git a/fs/file_table.c b/fs/file_table.c
index 3150e613aec..37f9bf5ed97 100644
--- a/fs/file_table.c
+++ b/fs/file_table.c
@@ -26,7 +26,6 @@
 #include <linux/percpu_counter.h>
 #include <linux/percpu.h>
 #include <linux/task_work.h>
-#include <linux/ima.h>
 #include <linux/swap.h>
 #include <linux/kmemleak.h>
 
@@ -313,7 +312,6 @@ static void __fput(struct file *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)
 			file->f_op->fasync(-1, file, 0);
diff --git a/fs/namei.c b/fs/namei.c
index 8c4fdfd81d4..cd700d4e8cf 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -27,7 +27,6 @@
 #include <linux/fsnotify.h>
 #include <linux/personality.h>
 #include <linux/security.h>
-#include <linux/ima.h>
 #include <linux/syscalls.h>
 #include <linux/mount.h>
 #include <linux/audit.h>
@@ -3560,8 +3559,6 @@ static int do_open(struct nameidata *nd,
 		error = vfs_open(&nd->path, file);
 	if (!error)
 		error = security_file_post_open(file, op->acc_mode);
-	if (!error)
-		error = ima_file_check(file, op->acc_mode);
 	if (!error && do_truncate)
 		error = handle_truncate(idmap, file);
 	if (unlikely(error > 0)) {
@@ -3625,7 +3622,6 @@ static int vfs_tmpfile(struct mnt_idmap *idmap,
 		spin_unlock(&inode->i_lock);
 	}
 	security_inode_post_create_tmpfile(idmap, dir, file_dentry(file), mode);
-	ima_post_create_tmpfile(idmap, dir, file_dentry(file), mode);
 	return 0;
 }
 
@@ -3968,9 +3964,6 @@ static int do_mknodat(int dfd, struct filename *name, umode_t mode,
 		case 0: case S_IFREG:
 			error = vfs_create(idmap, path.dentry->d_inode,
 					   dentry, mode, true);
-			if (!error)
-				ima_post_path_mknod(idmap, &path, dentry, mode,
-						    dev);
 			break;
 		case S_IFCHR: case S_IFBLK:
 			error = vfs_mknod(idmap, path.dentry->d_inode,
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c
index 4b86c158ffb..50038722602 100644
--- a/fs/nfsd/vfs.c
+++ b/fs/nfsd/vfs.c
@@ -25,7 +25,6 @@
 #include <linux/posix_acl_xattr.h>
 #include <linux/xattr.h>
 #include <linux/jhash.h>
-#include <linux/ima.h>
 #include <linux/pagemap.h>
 #include <linux/slab.h>
 #include <linux/uaccess.h>
@@ -858,12 +857,6 @@ __nfsd_open(struct svc_rqst *rqstp, struct svc_fh *fhp, umode_t type,
 		goto out_nfserr;
 	}
 
-	host_err = ima_file_check(file, may_flags);
-	if (host_err) {
-		fput(file);
-		goto out_nfserr;
-	}
-
 	if (may_flags & NFSD_MAY_64BIT_COOKIE)
 		file->f_mode |= FMODE_64BITHASH;
 	else
diff --git a/fs/open.c b/fs/open.c
index 4401a73d403..5d99c2bc061 100644
--- a/fs/open.c
+++ b/fs/open.c
@@ -29,7 +29,6 @@
 #include <linux/audit.h>
 #include <linux/falloc.h>
 #include <linux/fs_struct.h>
-#include <linux/ima.h>
 #include <linux/dnotify.h>
 #include <linux/compat.h>
 #include <linux/mnt_idmapping.h>
diff --git a/include/linux/ima.h b/include/linux/ima.h
index f56c6280667..6980e160ee5 100644
--- a/include/linux/ima.h
+++ b/include/linux/ima.h
@@ -16,26 +16,6 @@ struct linux_binprm;
 
 #ifdef CONFIG_IMA
 extern enum hash_algo ima_get_current_hash_algo(void);
-extern int ima_bprm_check(struct linux_binprm *bprm);
-extern int ima_file_check(struct file *file, int mask);
-extern void ima_post_create_tmpfile(struct mnt_idmap *idmap,
-				    struct inode *dir, struct dentry *dentry,
-				    umode_t mode);
-extern void ima_file_free(struct file *file);
-extern int ima_file_mmap(struct file *file, unsigned long reqprot,
-			 unsigned long prot, unsigned long flags);
-extern int ima_file_mprotect(struct vm_area_struct *vma, unsigned long reqprot,
-			     unsigned long prot);
-extern int ima_load_data(enum kernel_load_data_id id, bool contents);
-extern int ima_post_load_data(char *buf, loff_t size,
-			      enum kernel_load_data_id id, char *description);
-extern int ima_read_file(struct file *file, enum kernel_read_file_id id,
-			 bool contents);
-extern int ima_post_read_file(struct file *file, char *buf, loff_t size,
-			      enum kernel_read_file_id id);
-extern void ima_post_path_mknod(struct mnt_idmap *idmap,
-				const struct path *dir, struct dentry *dentry,
-				umode_t mode, unsigned int dev);
 extern int ima_file_hash(struct file *file, char *buf, size_t buf_size);
 extern int ima_inode_hash(struct inode *inode, char *buf, size_t buf_size);
 extern void ima_kexec_cmdline(int kernel_fd, const void *buf, int size);
@@ -60,72 +40,6 @@ static inline enum hash_algo ima_get_current_hash_algo(void)
 	return HASH_ALGO__LAST;
 }
 
-static inline int ima_bprm_check(struct linux_binprm *bprm)
-{
-	return 0;
-}
-
-static inline int ima_file_check(struct file *file, int mask)
-{
-	return 0;
-}
-
-static inline void ima_post_create_tmpfile(struct mnt_idmap *idmap,
-					   struct inode *dir,
-					   struct dentry *dentry,
-					   umode_t mode)
-{
-}
-
-static inline void ima_file_free(struct file *file)
-{
-	return;
-}
-
-static inline int ima_file_mmap(struct file *file, unsigned long reqprot,
-				unsigned long prot, unsigned long flags)
-{
-	return 0;
-}
-
-static inline int ima_file_mprotect(struct vm_area_struct *vma,
-				    unsigned long reqprot, unsigned long prot)
-{
-	return 0;
-}
-
-static inline int ima_load_data(enum kernel_load_data_id id, bool contents)
-{
-	return 0;
-}
-
-static inline int ima_post_load_data(char *buf, loff_t size,
-				     enum kernel_load_data_id id,
-				     char *description)
-{
-	return 0;
-}
-
-static inline int ima_read_file(struct file *file, enum kernel_read_file_id id,
-				bool contents)
-{
-	return 0;
-}
-
-static inline int ima_post_read_file(struct file *file, char *buf, loff_t size,
-				     enum kernel_read_file_id id)
-{
-	return 0;
-}
-
-static inline void ima_post_path_mknod(struct mnt_idmap *idmap,
-				       const struct path *dir,
-				       struct dentry *dentry,
-				       umode_t mode, unsigned int dev)
-{
-	return;
-}
-
 static inline int ima_file_hash(struct file *file, char *buf, size_t buf_size)
 {
 	return -EOPNOTSUPP;
@@ -176,20 +90,6 @@ static inline void ima_add_kexec_buffer(struct kimage *image)
 {}
 #endif
 
-#ifdef CONFIG_IMA_MEASURE_ASYMMETRIC_KEYS
-extern void ima_post_key_create_or_update(struct key *keyring,
-					  struct key *key,
-					  const void *payload, size_t plen,
-					  unsigned long flags, bool create);
-#else
-static inline void ima_post_key_create_or_update(struct key *keyring,
-						 struct key *key,
-						 const void *payload,
-						 size_t plen,
-						 unsigned long flags,
-						 bool create) {}
-#endif  /* CONFIG_IMA_MEASURE_ASYMMETRIC_KEYS */
-
 #ifdef CONFIG_IMA_APPRAISE
 extern bool is_ima_appraise_enabled(void);
 extern void ima_inode_post_setattr(struct mnt_idmap *idmap,
diff --git a/security/integrity/iint.c b/security/integrity/iint.c
index 8638976f799..bbadf974b31 100644
--- a/security/integrity/iint.c
+++ b/security/integrity/iint.c
@@ -172,19 +172,21 @@ static void init_once(void *foo)
 	mutex_init(&iint->mutex);
 }
 
-static int __init integrity_iintcache_init(void)
+static int __init integrity_lsm_init(void)
 {
 	iint_cache =
 	    kmem_cache_create("iint_cache", sizeof(struct integrity_iint_cache),
 			      0, SLAB_PANIC, init_once);
+
+	init_ima_lsm();
 	return 0;
 }
 DEFINE_LSM(integrity) = {
 	.name = "integrity",
-	.init = integrity_iintcache_init,
+	.init = integrity_lsm_init,
+	.order = LSM_ORDER_LAST,
 };
 
-
 /*
  * integrity_kernel_read - read data from the file
  *
diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h
index c29db699c99..7bdc7cdce07 100644
--- a/security/integrity/ima/ima.h
+++ b/security/integrity/ima/ima.h
@@ -127,6 +127,13 @@ void ima_load_kexec_buffer(void);
 static inline void ima_load_kexec_buffer(void) {}
 #endif /* CONFIG_HAVE_IMA_KEXEC */
 
+#ifdef CONFIG_IMA_MEASURE_ASYMMETRIC_KEYS
+extern void ima_post_key_create_or_update(struct key *keyring,
+					  struct key *key,
+					  const void *payload, size_t plen,
+					  unsigned long flags, bool create);
+#endif
+
 /*
  * The default binary_runtime_measurements list format is defined as the
  * platform native format.  The canonical format is defined as little-endian.
diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c
index b7835e287d9..567b7af0f55 100644
--- a/security/integrity/ima/ima_main.c
+++ b/security/integrity/ima/ima_main.c
@@ -25,6 +25,7 @@
 #include <linux/xattr.h>
 #include <linux/ima.h>
 #include <linux/iversion.h>
+#include <linux/lsm_hooks.h>
 #include <linux/fs.h>
 
 #include "ima.h"
@@ -184,7 +185,7 @@ static void ima_check_last_writer(struct integrity_iint_cache *iint,
  *
  * Flag files that changed, based on i_version
  */
-void ima_file_free(struct file *file)
+static void ima_file_free(struct file *file)
 {
 	struct inode *inode = file_inode(file);
 	struct integrity_iint_cache *iint;
@@ -409,8 +410,8 @@ static int process_measurement(struct file *file, const struct cred *cred,
  * On success return 0.  On integrity appraisal error, assuming the file
  * is in policy and IMA-appraisal is in enforcing mode, return -EACCES.
  */
-int ima_file_mmap(struct file *file, unsigned long reqprot,
-		  unsigned long prot, unsigned long flags)
+static int ima_file_mmap(struct file *file, unsigned long reqprot,
+			 unsigned long prot, unsigned long flags)
 {
 	u32 secid;
 	int ret;
@@ -448,8 +449,8 @@ int ima_file_mmap(struct file *file, unsigned long reqprot,
  *
  * On mprotect change success, return 0.  On failure, return -EACESS.
  */
-int ima_file_mprotect(struct vm_area_struct *vma, unsigned long reqprot,
-		      unsigned long prot)
+static int ima_file_mprotect(struct vm_area_struct *vma, unsigned long reqprot,
+			     unsigned long prot)
 {
 	struct ima_template_desc *template = NULL;
 	struct file *file;
@@ -507,7 +508,7 @@ int ima_file_mprotect(struct vm_area_struct *vma, unsigned long reqprot,
  * On success return 0.  On integrity appraisal error, assuming the file
  * is in policy and IMA-appraisal is in enforcing mode, return -EACCES.
  */
-int ima_bprm_check(struct linux_binprm *bprm)
+static int ima_bprm_check(struct linux_binprm *bprm)
 {
 	int ret;
 	u32 secid;
@@ -669,9 +670,8 @@ EXPORT_SYMBOL_GPL(ima_inode_hash);
  * Skip calling process_measurement(), but indicate which newly, created
  * tmpfiles are in policy.
  */
-void ima_post_create_tmpfile(struct mnt_idmap *idmap,
-			     struct inode *dir, struct dentry *dentry,
-			     umode_t mode)
+static void ima_post_create_tmpfile(struct mnt_idmap *idmap, struct inode *dir,
+				    struct dentry *dentry, umode_t mode)
 {
 	struct integrity_iint_cache *iint;
 	struct inode *inode = dentry->d_inode;
@@ -706,9 +706,9 @@ void ima_post_create_tmpfile(struct mnt_idmap *idmap,
  * Mark files created via the mknodat syscall as new, so that the
  * file data can be written later.
  */
-void ima_post_path_mknod(struct mnt_idmap *idmap,
-			 const struct path *dir, struct dentry *dentry,
-			 umode_t mode, unsigned int dev)
+static void __maybe_unused
+ima_post_path_mknod(struct mnt_idmap *idmap, const struct path *dir,
+		    struct dentry *dentry, umode_t mode, unsigned int dev)
 {
 	struct integrity_iint_cache *iint;
 	struct inode *inode = dentry->d_inode;
@@ -747,8 +747,8 @@ void ima_post_path_mknod(struct mnt_idmap *idmap,
  *
  * For permission return 0, otherwise return -EACCES.
  */
-int ima_read_file(struct file *file, enum kernel_read_file_id read_id,
-		  bool contents)
+static int ima_read_file(struct file *file, enum kernel_read_file_id read_id,
+			 bool contents)
 {
 	enum ima_hooks func;
 	u32 secid;
@@ -797,8 +797,8 @@ const int read_idmap[READING_MAX_ID] = {
  * On success return 0.  On integrity appraisal error, assuming the file
  * is in policy and IMA-appraisal is in enforcing mode, return -EACCES.
  */
-int ima_post_read_file(struct file *file, char *buf, loff_t size,
-		       enum kernel_read_file_id read_id)
+static int ima_post_read_file(struct file *file, char *buf, loff_t size,
+			      enum kernel_read_file_id read_id)
 {
 	enum ima_hooks func;
 	u32 secid;
@@ -831,7 +831,7 @@ int ima_post_read_file(struct file *file, char *buf, loff_t size,
  *
  * For permission return 0, otherwise return -EACCES.
  */
-int ima_load_data(enum kernel_load_data_id id, bool contents)
+static int ima_load_data(enum kernel_load_data_id id, bool contents)
 {
 	bool ima_enforce, sig_enforce;
 
@@ -885,9 +885,9 @@ int ima_load_data(enum kernel_load_data_id id, bool contents)
  * On success return 0.  On integrity appraisal error, assuming the file
  * is in policy and IMA-appraisal is in enforcing mode, return -EACCES.
  */
-int ima_post_load_data(char *buf, loff_t size,
-		       enum kernel_load_data_id load_id,
-		       char *description)
+static int ima_post_load_data(char *buf, loff_t size,
+			      enum kernel_load_data_id load_id,
+			      char *description)
 {
 	if (load_id == LOADING_FIRMWARE) {
 		if ((ima_appraise & IMA_APPRAISE_FIRMWARE) &&
@@ -1116,4 +1116,28 @@ static int __init init_ima(void)
 	return error;
 }
 
+static struct security_hook_list ima_hooks[] __lsm_ro_after_init = {
+	LSM_HOOK_INIT(bprm_check_security, ima_bprm_check),
+	LSM_HOOK_INIT(file_post_open, ima_file_check),
+	LSM_HOOK_INIT(inode_post_create_tmpfile, ima_post_create_tmpfile),
+	LSM_HOOK_INIT(file_pre_free_security, ima_file_free),
+	LSM_HOOK_INIT(mmap_file, ima_file_mmap),
+	LSM_HOOK_INIT(file_mprotect, ima_file_mprotect),
+	LSM_HOOK_INIT(kernel_load_data, ima_load_data),
+	LSM_HOOK_INIT(kernel_post_load_data, ima_post_load_data),
+	LSM_HOOK_INIT(kernel_read_file, ima_read_file),
+	LSM_HOOK_INIT(kernel_post_read_file, ima_post_read_file),
+#ifdef CONFIG_SECURITY_PATH
+	LSM_HOOK_INIT(path_post_mknod, ima_post_path_mknod),
+#endif
+#ifdef CONFIG_IMA_MEASURE_ASYMMETRIC_KEYS
+	LSM_HOOK_INIT(key_post_create_or_update, ima_post_key_create_or_update),
+#endif
+};
+
+void __init init_ima_lsm(void)
+{
+	security_add_hooks(ima_hooks, ARRAY_SIZE(ima_hooks), "integrity");
+}
+
 late_initcall(init_ima);	/* Start IMA after the TPM is available */
diff --git a/security/integrity/integrity.h b/security/integrity/integrity.h
index 7167a6e99bd..c72d375a356 100644
--- a/security/integrity/integrity.h
+++ b/security/integrity/integrity.h
@@ -191,6 +191,14 @@ extern struct dentry *integrity_dir;
 
 struct modsig;
 
+#ifdef CONFIG_IMA
+void __init init_ima_lsm(void);
+#else
+static inline void __init init_ima_lsm(void)
+{
+}
+#endif
+
 #ifdef CONFIG_INTEGRITY_SIGNATURE
 
 int integrity_digsig_verify(const unsigned int id, const char *sig, int siglen,
diff --git a/security/keys/key.c b/security/keys/key.c
index 0f9c6faf349..2acf9fa8073 100644
--- a/security/keys/key.c
+++ b/security/keys/key.c
@@ -13,7 +13,6 @@
 #include <linux/security.h>
 #include <linux/workqueue.h>
 #include <linux/random.h>
-#include <linux/ima.h>
 #include <linux/err.h>
 #include "internal.h"
 
@@ -936,8 +935,6 @@ static key_ref_t __key_create_or_update(key_ref_t keyring_ref,
 
 	security_key_post_create_or_update(keyring, key, payload, plen, flags,
 					   true);
-	ima_post_key_create_or_update(keyring, key, payload, plen,
-				      flags, true);
 
 	key_ref = make_key_ref(key, is_key_possessed(keyring_ref));
 
@@ -969,13 +966,9 @@ static key_ref_t __key_create_or_update(key_ref_t keyring_ref,
 
 	key_ref = __key_update(key_ref, &prep);
 
-	if (!IS_ERR(key_ref)) {
+	if (!IS_ERR(key_ref))
 		security_key_post_create_or_update(keyring, key, payload, plen,
 						   flags, false);
-		ima_post_key_create_or_update(keyring, key,
-					      payload, plen,
-					      flags, false);
-	}
 
 	goto error_free_prep;
 }
diff --git a/security/security.c b/security/security.c
index 24f52ba3218..5ca8d89eb57 100644
--- a/security/security.c
+++ b/security/security.c
@@ -1097,12 +1097,7 @@ int security_bprm_creds_from_file(struct linux_binprm *bprm, struct file *file)
  */
 int security_bprm_check(struct linux_binprm *bprm)
 {
-	int ret;
-
-	ret = call_int_hook(bprm_check_security, 0, bprm);
-	if (ret)
-		return ret;
-	return ima_bprm_check(bprm);
+	return call_int_hook(bprm_check_security, 0, bprm);
 }
 
 /**
@@ -2849,13 +2844,8 @@ static inline unsigned long mmap_prot(struct file *file, unsigned long prot)
 int security_mmap_file(struct file *file, unsigned long prot,
 		       unsigned long flags)
 {
-	unsigned long prot_adj = mmap_prot(file, prot);
-	int ret;
-
-	ret = call_int_hook(mmap_file, 0, file, prot, prot_adj, flags);
-	if (ret)
-		return ret;
-	return ima_file_mmap(file, prot, prot_adj, flags);
+	return call_int_hook(mmap_file, 0, file, prot, mmap_prot(file, prot),
+			     flags);
 }
 
 /**
@@ -2884,12 +2874,7 @@ int security_mmap_addr(unsigned long addr)
 int security_file_mprotect(struct vm_area_struct *vma, unsigned long reqprot,
 			   unsigned long prot)
 {
-	int ret;
-
-	ret = call_int_hook(file_mprotect, 0, vma, reqprot, prot);
-	if (ret)
-		return ret;
-	return ima_file_mprotect(vma, reqprot, prot);
+	return call_int_hook(file_mprotect, 0, vma, reqprot, prot);
 }
 
 /**
@@ -3219,12 +3204,7 @@ int security_kernel_module_request(char *kmod_name)
 int security_kernel_read_file(struct file *file, enum kernel_read_file_id id,
 			      bool contents)
 {
-	int ret;
-
-	ret = call_int_hook(kernel_read_file, 0, file, id, contents);
-	if (ret)
-		return ret;
-	return ima_read_file(file, id, contents);
+	return call_int_hook(kernel_read_file, 0, file, id, contents);
 }
 EXPORT_SYMBOL_GPL(security_kernel_read_file);
 
@@ -3244,12 +3224,7 @@ EXPORT_SYMBOL_GPL(security_kernel_read_file);
 int security_kernel_post_read_file(struct file *file, char *buf, loff_t size,
 				   enum kernel_read_file_id id)
 {
-	int ret;
-
-	ret = call_int_hook(kernel_post_read_file, 0, file, buf, size, id);
-	if (ret)
-		return ret;
-	return ima_post_read_file(file, buf, size, id);
+	return call_int_hook(kernel_post_read_file, 0, file, buf, size, id);
 }
 EXPORT_SYMBOL_GPL(security_kernel_post_read_file);
 
@@ -3264,12 +3239,7 @@ EXPORT_SYMBOL_GPL(security_kernel_post_read_file);
  */
 int security_kernel_load_data(enum kernel_load_data_id id, bool contents)
 {
-	int ret;
-
-	ret = call_int_hook(kernel_load_data, 0, id, contents);
-	if (ret)
-		return ret;
-	return ima_load_data(id, contents);
+	return call_int_hook(kernel_load_data, 0, id, contents);
 }
 EXPORT_SYMBOL_GPL(security_kernel_load_data);
 
@@ -3291,13 +3261,8 @@ int security_kernel_post_load_data(char *buf, loff_t size,
 				   enum kernel_load_data_id id,
 				   char *description)
 {
-	int ret;
-
-	ret = call_int_hook(kernel_post_load_data, 0, buf, size, id,
-			    description);
-	if (ret)
-		return ret;
-	return ima_post_load_data(buf, size, id, description);
+	return call_int_hook(kernel_post_load_data, 0, buf, size, id,
+			     description);
 }
 EXPORT_SYMBOL_GPL(security_kernel_post_load_data);
 
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 79+ messages in thread

* [PATCH 25/28] ima: Move IMA-Appraisal to LSM infrastructure
  2023-03-03 18:18 [PATCH 00/28] security: Move IMA and EVM to the LSM infrastructure Roberto Sassu
                   ` (23 preceding siblings ...)
  2023-03-03 18:25 ` [PATCH 24/28] ima: Move to LSM infrastructure Roberto Sassu
@ 2023-03-03 18:25 ` Roberto Sassu
  2023-03-03 18:26 ` [PATCH 26/28] evm: Move " Roberto Sassu
                   ` (3 subsequent siblings)
  28 siblings, 0 replies; 79+ messages in thread
From: Roberto Sassu @ 2023-03-03 18:25 UTC (permalink / raw)
  To: viro, chuck.lever, jlayton, zohar, dmitry.kasatkin, paul,
	jmorris, serge, dhowells, jarkko, stephen.smalley.work, eparis,
	casey, brauner
  Cc: linux-fsdevel, linux-nfs, linux-integrity, linux-security-module,
	keyrings, selinux, linux-kernel, stefanb, Roberto Sassu

From: Roberto Sassu <roberto.sassu@huawei.com>

Do the registration of IMA-Appraisal functions separately from the rest of
IMA functions, as appraisal is a separate feature not necessarily enabled
in the kernel configuration.

Reuse the same approach as for other IMA functions, remove hardcoded calls
from the LSM infrastructure or the other places, declare the functions as
static and register them as hook implementations in
init_ima_appraise_lsm(), called by init_ima_lsm() to chain the
initialization.

Signed-off-by: Roberto Sassu <roberto.sassu@huawei.com>
---
 fs/attr.c                             |  2 -
 include/linux/ima.h                   | 54 ---------------------------
 security/integrity/ima/ima.h          |  5 +++
 security/integrity/ima/ima_appraise.c | 39 ++++++++++++++-----
 security/integrity/ima/ima_main.c     |  1 +
 security/security.c                   | 13 -------
 6 files changed, 36 insertions(+), 78 deletions(-)

diff --git a/fs/attr.c b/fs/attr.c
index 343d6d62435..406d782dfab 100644
--- a/fs/attr.c
+++ b/fs/attr.c
@@ -17,7 +17,6 @@
 #include <linux/filelock.h>
 #include <linux/security.h>
 #include <linux/evm.h>
-#include <linux/ima.h>
 
 #include "internal.h"
 
@@ -486,7 +485,6 @@ int notify_change(struct mnt_idmap *idmap, struct dentry *dentry,
 	if (!error) {
 		fsnotify_change(dentry, ia_valid);
 		security_inode_post_setattr(idmap, dentry, ia_valid);
-		ima_inode_post_setattr(idmap, dentry, ia_valid);
 		evm_inode_post_setattr(idmap, dentry, ia_valid);
 	}
 
diff --git a/include/linux/ima.h b/include/linux/ima.h
index 6980e160ee5..0bae61a15b6 100644
--- a/include/linux/ima.h
+++ b/include/linux/ima.h
@@ -92,65 +92,11 @@ static inline void ima_add_kexec_buffer(struct kimage *image)
 
 #ifdef CONFIG_IMA_APPRAISE
 extern bool is_ima_appraise_enabled(void);
-extern void ima_inode_post_setattr(struct mnt_idmap *idmap,
-				   struct dentry *dentry, int ia_valid);
-extern int ima_inode_setxattr(struct mnt_idmap *idmap, struct dentry *dentry,
-			      const char *xattr_name, const void *xattr_value,
-			      size_t xattr_value_len, int flags);
-extern int ima_inode_set_acl(struct mnt_idmap *idmap,
-			     struct dentry *dentry, const char *acl_name,
-			     struct posix_acl *kacl);
-static inline int ima_inode_remove_acl(struct mnt_idmap *idmap,
-				       struct dentry *dentry,
-				       const char *acl_name)
-{
-	return ima_inode_set_acl(idmap, dentry, acl_name, NULL);
-}
-extern int ima_inode_removexattr(struct mnt_idmap *idmap, struct dentry *dentry,
-				 const char *xattr_name);
 #else
 static inline bool is_ima_appraise_enabled(void)
 {
 	return 0;
 }
-
-static inline void ima_inode_post_setattr(struct mnt_idmap *idmap,
-					  struct dentry *dentry, int ia_valid)
-{
-	return;
-}
-
-static inline int ima_inode_setxattr(struct mnt_idmap *idmap,
-				     struct dentry *dentry,
-				     const char *xattr_name,
-				     const void *xattr_value,
-				     size_t xattr_value_len,
-				     int flags)
-{
-	return 0;
-}
-
-static inline int ima_inode_set_acl(struct mnt_idmap *idmap,
-				    struct dentry *dentry, const char *acl_name,
-				    struct posix_acl *kacl)
-{
-
-	return 0;
-}
-
-static inline int ima_inode_removexattr(struct mnt_idmap *idmap,
-					struct dentry *dentry,
-					const char *xattr_name)
-{
-	return 0;
-}
-
-static inline int ima_inode_remove_acl(struct mnt_idmap *idmap,
-				       struct dentry *dentry,
-				       const char *acl_name)
-{
-	return 0;
-}
 #endif /* CONFIG_IMA_APPRAISE */
 
 #if defined(CONFIG_IMA_APPRAISE) && defined(CONFIG_INTEGRITY_TRUSTED_KEYRING)
diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h
index 7bdc7cdce07..0f6443fb0f3 100644
--- a/security/integrity/ima/ima.h
+++ b/security/integrity/ima/ima.h
@@ -335,6 +335,7 @@ enum hash_algo ima_get_hash_algo(const struct evm_ima_xattr_data *xattr_value,
 				 int xattr_len);
 int ima_read_xattr(struct dentry *dentry,
 		   struct evm_ima_xattr_data **xattr_value, int xattr_len);
+void __init init_ima_appraise_lsm(void);
 
 #else
 static inline int ima_check_blacklist(struct integrity_iint_cache *iint,
@@ -386,6 +387,10 @@ static inline int ima_read_xattr(struct dentry *dentry,
 	return 0;
 }
 
+static inline void __init init_ima_appraise_lsm(void)
+{
+}
+
 #endif /* CONFIG_IMA_APPRAISE */
 
 #ifdef CONFIG_IMA_APPRAISE_MODSIG
diff --git a/security/integrity/ima/ima_appraise.c b/security/integrity/ima/ima_appraise.c
index c35e3537eb8..7726e821a1f 100644
--- a/security/integrity/ima/ima_appraise.c
+++ b/security/integrity/ima/ima_appraise.c
@@ -14,6 +14,7 @@
 #include <linux/ima.h>
 #include <linux/evm.h>
 #include <linux/fsverity.h>
+#include <linux/lsm_hooks.h>
 #include <keys/system_keyring.h>
 #include <uapi/linux/fsverity.h>
 
@@ -634,8 +635,8 @@ void ima_update_xattr(struct integrity_iint_cache *iint, struct file *file)
  * This function is called from notify_change(), which expects the caller
  * to lock the inode's i_mutex.
  */
-void ima_inode_post_setattr(struct mnt_idmap *idmap,
-			    struct dentry *dentry, int ia_valid)
+static void ima_inode_post_setattr(struct mnt_idmap *idmap,
+				   struct dentry *dentry, int ia_valid)
 {
 	struct inode *inode = d_backing_inode(dentry);
 	struct integrity_iint_cache *iint;
@@ -748,9 +749,9 @@ static int validate_hash_algo(struct dentry *dentry,
 	return -EACCES;
 }
 
-int ima_inode_setxattr(struct mnt_idmap *idmap, struct dentry *dentry,
-		       const char *xattr_name, const void *xattr_value,
-		       size_t xattr_value_len, int flags)
+static int ima_inode_setxattr(struct mnt_idmap *idmap, struct dentry *dentry,
+			      const char *xattr_name, const void *xattr_value,
+			      size_t xattr_value_len, int flags)
 {
 	const struct evm_ima_xattr_data *xvalue = xattr_value;
 	int digsig = 0;
@@ -779,8 +780,8 @@ int ima_inode_setxattr(struct mnt_idmap *idmap, struct dentry *dentry,
 	return result;
 }
 
-int ima_inode_set_acl(struct mnt_idmap *idmap, struct dentry *dentry,
-		      const char *acl_name, struct posix_acl *kacl)
+static int ima_inode_set_acl(struct mnt_idmap *idmap, struct dentry *dentry,
+			     const char *acl_name, struct posix_acl *kacl)
 {
 	if (evm_revalidate_status(acl_name))
 		ima_reset_appraise_flags(d_backing_inode(dentry), 0);
@@ -788,8 +789,8 @@ int ima_inode_set_acl(struct mnt_idmap *idmap, struct dentry *dentry,
 	return 0;
 }
 
-int ima_inode_removexattr(struct mnt_idmap *idmap, struct dentry *dentry,
-			  const char *xattr_name)
+static int ima_inode_removexattr(struct mnt_idmap *idmap, struct dentry *dentry,
+				 const char *xattr_name)
 {
 	int result;
 
@@ -801,3 +802,23 @@ int ima_inode_removexattr(struct mnt_idmap *idmap, struct dentry *dentry,
 	}
 	return result;
 }
+
+static int ima_inode_remove_acl(struct mnt_idmap *idmap, struct dentry *dentry,
+				const char *acl_name)
+{
+	return ima_inode_set_acl(idmap, dentry, acl_name, NULL);
+}
+
+static struct security_hook_list ima_appraise_hooks[] __lsm_ro_after_init = {
+	LSM_HOOK_INIT(inode_post_setattr, ima_inode_post_setattr),
+	LSM_HOOK_INIT(inode_setxattr, ima_inode_setxattr),
+	LSM_HOOK_INIT(inode_set_acl, ima_inode_set_acl),
+	LSM_HOOK_INIT(inode_removexattr, ima_inode_removexattr),
+	LSM_HOOK_INIT(inode_remove_acl, ima_inode_remove_acl),
+};
+
+void __init init_ima_appraise_lsm(void)
+{
+	security_add_hooks(ima_appraise_hooks, ARRAY_SIZE(ima_appraise_hooks),
+			   "integrity");
+}
diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c
index 567b7af0f55..38419370b28 100644
--- a/security/integrity/ima/ima_main.c
+++ b/security/integrity/ima/ima_main.c
@@ -1138,6 +1138,7 @@ static struct security_hook_list ima_hooks[] __lsm_ro_after_init = {
 void __init init_ima_lsm(void)
 {
 	security_add_hooks(ima_hooks, ARRAY_SIZE(ima_hooks), "integrity");
+	init_ima_appraise_lsm();
 }
 
 late_initcall(init_ima);	/* Start IMA after the TPM is available */
diff --git a/security/security.c b/security/security.c
index 5ca8d89eb57..9bc6a4ef758 100644
--- a/security/security.c
+++ b/security/security.c
@@ -20,7 +20,6 @@
 #include <linux/kernel_read_file.h>
 #include <linux/lsm_hooks.h>
 #include <linux/integrity.h>
-#include <linux/ima.h>
 #include <linux/evm.h>
 #include <linux/fsnotify.h>
 #include <linux/mman.h>
@@ -2273,9 +2272,6 @@ int security_inode_setxattr(struct mnt_idmap *idmap,
 
 	if (ret == 1)
 		ret = cap_inode_setxattr(dentry, name, value, size, flags);
-	if (ret)
-		return ret;
-	ret = ima_inode_setxattr(idmap, dentry, name, value, size, flags);
 	if (ret)
 		return ret;
 	return evm_inode_setxattr(idmap, dentry, name, value, size, flags);
@@ -2303,9 +2299,6 @@ int security_inode_set_acl(struct mnt_idmap *idmap,
 		return 0;
 	ret = call_int_hook(inode_set_acl, 0, idmap, dentry, acl_name,
 			    kacl);
-	if (ret)
-		return ret;
-	ret = ima_inode_set_acl(idmap, dentry, acl_name, kacl);
 	if (ret)
 		return ret;
 	return evm_inode_set_acl(idmap, dentry, acl_name, kacl);
@@ -2366,9 +2359,6 @@ int security_inode_remove_acl(struct mnt_idmap *idmap,
 	if (unlikely(IS_PRIVATE(d_backing_inode(dentry))))
 		return 0;
 	ret = call_int_hook(inode_remove_acl, 0, idmap, dentry, acl_name);
-	if (ret)
-		return ret;
-	ret = ima_inode_remove_acl(idmap, dentry, acl_name);
 	if (ret)
 		return ret;
 	return evm_inode_remove_acl(idmap, dentry, acl_name);
@@ -2468,9 +2458,6 @@ int security_inode_removexattr(struct mnt_idmap *idmap,
 	ret = call_int_hook(inode_removexattr, 1, idmap, dentry, name);
 	if (ret == 1)
 		ret = cap_inode_removexattr(idmap, dentry, name);
-	if (ret)
-		return ret;
-	ret = ima_inode_removexattr(idmap, dentry, name);
 	if (ret)
 		return ret;
 	return evm_inode_removexattr(idmap, dentry, name);
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 79+ messages in thread

* [PATCH 26/28] evm: Move to LSM infrastructure
  2023-03-03 18:18 [PATCH 00/28] security: Move IMA and EVM to the LSM infrastructure Roberto Sassu
                   ` (24 preceding siblings ...)
  2023-03-03 18:25 ` [PATCH 25/28] ima: Move IMA-Appraisal " Roberto Sassu
@ 2023-03-03 18:26 ` Roberto Sassu
  2023-03-04 21:36   ` Casey Schaufler
  2023-03-03 18:26 ` [PATCH 27/28] integrity: Move integrity functions to the " Roberto Sassu
                   ` (2 subsequent siblings)
  28 siblings, 1 reply; 79+ messages in thread
From: Roberto Sassu @ 2023-03-03 18:26 UTC (permalink / raw)
  To: viro, chuck.lever, jlayton, zohar, dmitry.kasatkin, paul,
	jmorris, serge, dhowells, jarkko, stephen.smalley.work, eparis,
	casey, brauner
  Cc: linux-fsdevel, linux-nfs, linux-integrity, linux-security-module,
	keyrings, selinux, linux-kernel, stefanb, Roberto Sassu

From: Roberto Sassu <roberto.sassu@huawei.com>

As for IMA, remove hardcoded EVM function calls from the LSM infrastructure
and the VFS. Make EVM functions as static (except for
evm_inode_init_security(), which is exported), and register them as hook
implementations in init_evm_lsm(), called from integrity_lsm_init().

Finally, switch to the LSM reservation mechanism for the EVM xattr, by
setting the lbs_xattr field of the lsm_blob_sizes structure, and
consequently decrement the number of xattrs to allocate in
security_inode_init_security().

Signed-off-by: Roberto Sassu <roberto.sassu@huawei.com>
---
 fs/attr.c                         |   2 -
 fs/posix_acl.c                    |   3 -
 fs/xattr.c                        |   2 -
 include/linux/evm.h               | 116 ------------------------------
 security/integrity/evm/evm_main.c | 106 ++++++++++++++++++++++-----
 security/integrity/iint.c         |   7 ++
 security/integrity/integrity.h    |   9 +++
 security/security.c               |  41 +++--------
 8 files changed, 115 insertions(+), 171 deletions(-)

diff --git a/fs/attr.c b/fs/attr.c
index 406d782dfab..1b911a627fe 100644
--- a/fs/attr.c
+++ b/fs/attr.c
@@ -16,7 +16,6 @@
 #include <linux/fcntl.h>
 #include <linux/filelock.h>
 #include <linux/security.h>
-#include <linux/evm.h>
 
 #include "internal.h"
 
@@ -485,7 +484,6 @@ int notify_change(struct mnt_idmap *idmap, struct dentry *dentry,
 	if (!error) {
 		fsnotify_change(dentry, ia_valid);
 		security_inode_post_setattr(idmap, dentry, ia_valid);
-		evm_inode_post_setattr(idmap, dentry, ia_valid);
 	}
 
 	return error;
diff --git a/fs/posix_acl.c b/fs/posix_acl.c
index 5b8c92fce0c..608cb0a9f84 100644
--- a/fs/posix_acl.c
+++ b/fs/posix_acl.c
@@ -26,7 +26,6 @@
 #include <linux/mnt_idmapping.h>
 #include <linux/iversion.h>
 #include <linux/security.h>
-#include <linux/evm.h>
 #include <linux/fsnotify.h>
 #include <linux/filelock.h>
 
@@ -1103,7 +1102,6 @@ int vfs_set_acl(struct mnt_idmap *idmap, struct dentry *dentry,
 	if (!error) {
 		fsnotify_xattr(dentry);
 		security_inode_post_set_acl(dentry, acl_name, kacl);
-		evm_inode_post_set_acl(dentry, acl_name, kacl);
 	}
 
 out_inode_unlock:
@@ -1214,7 +1212,6 @@ int vfs_remove_acl(struct mnt_idmap *idmap, struct dentry *dentry,
 	if (!error) {
 		fsnotify_xattr(dentry);
 		security_inode_post_remove_acl(idmap, dentry, acl_name);
-		evm_inode_post_remove_acl(idmap, dentry, acl_name);
 	}
 
 out_inode_unlock:
diff --git a/fs/xattr.c b/fs/xattr.c
index 10c959d9fc6..7708ffdacca 100644
--- a/fs/xattr.c
+++ b/fs/xattr.c
@@ -16,7 +16,6 @@
 #include <linux/mount.h>
 #include <linux/namei.h>
 #include <linux/security.h>
-#include <linux/evm.h>
 #include <linux/syscalls.h>
 #include <linux/export.h>
 #include <linux/fsnotify.h>
@@ -535,7 +534,6 @@ __vfs_removexattr_locked(struct mnt_idmap *idmap,
 	if (!error) {
 		fsnotify_xattr(dentry);
 		security_inode_post_removexattr(dentry, name);
-		evm_inode_post_removexattr(dentry, name);
 	}
 
 out:
diff --git a/include/linux/evm.h b/include/linux/evm.h
index 8c043273552..61794299f09 100644
--- a/include/linux/evm.h
+++ b/include/linux/evm.h
@@ -21,46 +21,6 @@ extern enum integrity_status evm_verifyxattr(struct dentry *dentry,
 					     void *xattr_value,
 					     size_t xattr_value_len,
 					     struct integrity_iint_cache *iint);
-extern int evm_inode_setattr(struct mnt_idmap *idmap,
-			     struct dentry *dentry, struct iattr *attr);
-extern void evm_inode_post_setattr(struct mnt_idmap *idmap,
-				   struct dentry *dentry, int ia_valid);
-extern int evm_inode_setxattr(struct mnt_idmap *idmap,
-			      struct dentry *dentry, const char *name,
-			      const void *value, size_t size, int flags);
-extern void evm_inode_post_setxattr(struct dentry *dentry,
-				    const char *xattr_name,
-				    const void *xattr_value,
-				    size_t xattr_value_len,
-				    int flags);
-extern int evm_inode_removexattr(struct mnt_idmap *idmap,
-				 struct dentry *dentry, const char *xattr_name);
-extern void evm_inode_post_removexattr(struct dentry *dentry,
-				       const char *xattr_name);
-static inline void evm_inode_post_remove_acl(struct mnt_idmap *idmap,
-					     struct dentry *dentry,
-					     const char *acl_name)
-{
-	evm_inode_post_removexattr(dentry, acl_name);
-}
-extern int evm_inode_set_acl(struct mnt_idmap *idmap,
-			     struct dentry *dentry, const char *acl_name,
-			     struct posix_acl *kacl);
-static inline int evm_inode_remove_acl(struct mnt_idmap *idmap,
-				       struct dentry *dentry,
-				       const char *acl_name)
-{
-	return evm_inode_set_acl(idmap, dentry, acl_name, NULL);
-}
-static inline void evm_inode_post_set_acl(struct dentry *dentry,
-					  const char *acl_name,
-					  struct posix_acl *kacl)
-{
-	return evm_inode_post_setxattr(dentry, acl_name, NULL, 0, 0);
-}
-extern int evm_inode_init_security(struct inode *inode, struct inode *dir,
-				   const struct qstr *qstr,
-				   struct xattr *xattrs);
 extern bool evm_revalidate_status(const char *xattr_name);
 extern int evm_protected_xattr_if_enabled(const char *req_xattr_name);
 extern int evm_read_protected_xattrs(struct dentry *dentry, u8 *buffer,
@@ -92,82 +52,6 @@ static inline enum integrity_status evm_verifyxattr(struct dentry *dentry,
 }
 #endif
 
-static inline int evm_inode_setattr(struct mnt_idmap *idmap,
-				    struct dentry *dentry, struct iattr *attr)
-{
-	return 0;
-}
-
-static inline void evm_inode_post_setattr(struct mnt_idmap *idmap,
-					  struct dentry *dentry, int ia_valid)
-{
-	return;
-}
-
-static inline int evm_inode_setxattr(struct mnt_idmap *idmap,
-				     struct dentry *dentry, const char *name,
-				     const void *value, size_t size, int flags)
-{
-	return 0;
-}
-
-static inline void evm_inode_post_setxattr(struct dentry *dentry,
-					   const char *xattr_name,
-					   const void *xattr_value,
-					   size_t xattr_value_len,
-					   int flags)
-{
-	return;
-}
-
-static inline int evm_inode_removexattr(struct mnt_idmap *idmap,
-					struct dentry *dentry,
-					const char *xattr_name)
-{
-	return 0;
-}
-
-static inline void evm_inode_post_removexattr(struct dentry *dentry,
-					      const char *xattr_name)
-{
-	return;
-}
-
-static inline void evm_inode_post_remove_acl(struct mnt_idmap *idmap,
-					     struct dentry *dentry,
-					     const char *acl_name)
-{
-	return;
-}
-
-static inline int evm_inode_set_acl(struct mnt_idmap *idmap,
-				    struct dentry *dentry, const char *acl_name,
-				    struct posix_acl *kacl)
-{
-	return 0;
-}
-
-static inline int evm_inode_remove_acl(struct mnt_idmap *idmap,
-				       struct dentry *dentry,
-				       const char *acl_name)
-{
-	return 0;
-}
-
-static inline void evm_inode_post_set_acl(struct dentry *dentry,
-					  const char *acl_name,
-					  struct posix_acl *kacl)
-{
-	return;
-}
-
-static inline int evm_inode_init_security(struct inode *inode, struct inode *dir,
-					  const struct qstr *qstr,
-					  struct xattr *xattrs)
-{
-	return 0;
-}
-
 static inline bool evm_revalidate_status(const char *xattr_name)
 {
 	return false;
diff --git a/security/integrity/evm/evm_main.c b/security/integrity/evm/evm_main.c
index 8b5c472f78b..c45bc97277c 100644
--- a/security/integrity/evm/evm_main.c
+++ b/security/integrity/evm/evm_main.c
@@ -19,6 +19,7 @@
 #include <linux/xattr.h>
 #include <linux/integrity.h>
 #include <linux/evm.h>
+#include <linux/lsm_hooks.h>
 #include <linux/magic.h>
 #include <linux/posix_acl_xattr.h>
 
@@ -566,9 +567,9 @@ static int evm_protect_xattr(struct mnt_idmap *idmap,
  * userspace from writing HMAC value.  Writing 'security.evm' requires
  * requires CAP_SYS_ADMIN privileges.
  */
-int evm_inode_setxattr(struct mnt_idmap *idmap, struct dentry *dentry,
-		       const char *xattr_name, const void *xattr_value,
-		       size_t xattr_value_len, int flags)
+static int evm_inode_setxattr(struct mnt_idmap *idmap, struct dentry *dentry,
+			      const char *xattr_name, const void *xattr_value,
+			      size_t xattr_value_len, int flags)
 {
 	const struct evm_ima_xattr_data *xattr_data = xattr_value;
 
@@ -598,8 +599,8 @@ int evm_inode_setxattr(struct mnt_idmap *idmap, struct dentry *dentry,
  * Removing 'security.evm' requires CAP_SYS_ADMIN privileges and that
  * the current value is valid.
  */
-int evm_inode_removexattr(struct mnt_idmap *idmap,
-			  struct dentry *dentry, const char *xattr_name)
+static int evm_inode_removexattr(struct mnt_idmap *idmap, struct dentry *dentry,
+				 const char *xattr_name)
 {
 	/* Policy permits modification of the protected xattrs even though
 	 * there's no HMAC key loaded
@@ -649,9 +650,11 @@ static inline int evm_inode_set_acl_change(struct mnt_idmap *idmap,
  * Prevent modifying posix acls causing the EVM HMAC to be re-calculated
  * and 'security.evm' xattr updated, unless the existing 'security.evm' is
  * valid.
+ *
+ * Return: zero on success, -EPERM on failure.
  */
-int evm_inode_set_acl(struct mnt_idmap *idmap, struct dentry *dentry,
-		      const char *acl_name, struct posix_acl *kacl)
+static int evm_inode_set_acl(struct mnt_idmap *idmap, struct dentry *dentry,
+			     const char *acl_name, struct posix_acl *kacl)
 {
 	enum integrity_status evm_status;
 
@@ -690,6 +693,24 @@ int evm_inode_set_acl(struct mnt_idmap *idmap, struct dentry *dentry,
 	return -EPERM;
 }
 
+/**
+ * evm_inode_remove_acl - Protect the EVM extended attribute from posix acls
+ * @idmap: idmap of the mount
+ * @dentry: pointer to the affected dentry
+ * @acl_name: name of the posix acl
+ *
+ * Prevent removing posix acls causing the EVM HMAC to be re-calculated
+ * and 'security.evm' xattr updated, unless the existing 'security.evm' is
+ * valid.
+ *
+ * Return: zero on success, -EPERM on failure.
+ */
+static int evm_inode_remove_acl(struct mnt_idmap *idmap, struct dentry *dentry,
+				const char *acl_name)
+{
+	return evm_inode_set_acl(idmap, dentry, acl_name, NULL);
+}
+
 static void evm_reset_status(struct inode *inode)
 {
 	struct integrity_iint_cache *iint;
@@ -738,9 +759,11 @@ bool evm_revalidate_status(const char *xattr_name)
  * __vfs_setxattr_noperm().  The caller of which has taken the inode's
  * i_mutex lock.
  */
-void evm_inode_post_setxattr(struct dentry *dentry, const char *xattr_name,
-			     const void *xattr_value, size_t xattr_value_len,
-			     int flags)
+static void evm_inode_post_setxattr(struct dentry *dentry,
+				    const char *xattr_name,
+				    const void *xattr_value,
+				    size_t xattr_value_len,
+				    int flags)
 {
 	if (!evm_revalidate_status(xattr_name))
 		return;
@@ -756,6 +779,21 @@ void evm_inode_post_setxattr(struct dentry *dentry, const char *xattr_name,
 	evm_update_evmxattr(dentry, xattr_name, xattr_value, xattr_value_len);
 }
 
+/**
+ * evm_inode_post_set_acl - Update the EVM extended attribute from posix acls
+ * @dentry: pointer to the affected dentry
+ * @acl_name: name of the posix acl
+ * @kacl: pointer to the posix acls
+ *
+ * Update the 'security.evm' xattr with the EVM HMAC re-calculated after setting
+ * posix acls.
+ */
+static void evm_inode_post_set_acl(struct dentry *dentry, const char *acl_name,
+				   struct posix_acl *kacl)
+{
+	return evm_inode_post_setxattr(dentry, acl_name, NULL, 0, 0);
+}
+
 /**
  * evm_inode_post_removexattr - update 'security.evm' after removing the xattr
  * @dentry: pointer to the affected dentry
@@ -766,7 +804,8 @@ void evm_inode_post_setxattr(struct dentry *dentry, const char *xattr_name,
  * No need to take the i_mutex lock here, as this function is called from
  * vfs_removexattr() which takes the i_mutex.
  */
-void evm_inode_post_removexattr(struct dentry *dentry, const char *xattr_name)
+static void evm_inode_post_removexattr(struct dentry *dentry,
+				       const char *xattr_name)
 {
 	if (!evm_revalidate_status(xattr_name))
 		return;
@@ -782,6 +821,22 @@ void evm_inode_post_removexattr(struct dentry *dentry, const char *xattr_name)
 	evm_update_evmxattr(dentry, xattr_name, NULL, 0);
 }
 
+/**
+ * evm_inode_post_remove_acl - Update the EVM extended attribute from posix acls
+ * @idmap: idmap of the mount
+ * @dentry: pointer to the affected dentry
+ * @acl_name: name of the posix acl
+ *
+ * Update the 'security.evm' xattr with the EVM HMAC re-calculated after
+ * removing posix acls.
+ */
+static inline void evm_inode_post_remove_acl(struct mnt_idmap *idmap,
+					     struct dentry *dentry,
+					     const char *acl_name)
+{
+	evm_inode_post_removexattr(dentry, acl_name);
+}
+
 static int evm_attr_change(struct mnt_idmap *idmap,
 			   struct dentry *dentry, struct iattr *attr)
 {
@@ -805,8 +860,8 @@ static int evm_attr_change(struct mnt_idmap *idmap,
  * Permit update of file attributes when files have a valid EVM signature,
  * except in the case of them having an immutable portable signature.
  */
-int evm_inode_setattr(struct mnt_idmap *idmap, struct dentry *dentry,
-		      struct iattr *attr)
+static int evm_inode_setattr(struct mnt_idmap *idmap, struct dentry *dentry,
+			     struct iattr *attr)
 {
 	unsigned int ia_valid = attr->ia_valid;
 	enum integrity_status evm_status;
@@ -853,8 +908,8 @@ int evm_inode_setattr(struct mnt_idmap *idmap, struct dentry *dentry,
  * This function is called from notify_change(), which expects the caller
  * to lock the inode's i_mutex.
  */
-void evm_inode_post_setattr(struct mnt_idmap *idmap, struct dentry *dentry,
-			    int ia_valid)
+static void evm_inode_post_setattr(struct mnt_idmap *idmap,
+				   struct dentry *dentry, int ia_valid)
 {
 	if (!evm_revalidate_status(NULL))
 		return;
@@ -892,7 +947,7 @@ int evm_inode_init_security(struct inode *inode, struct inode *dir,
 	if (!evm_protected_xattrs)
 		return -EOPNOTSUPP;
 
-	evm_xattr = xattr;
+	evm_xattr = xattrs + integrity_blob_sizes.lbs_xattr;
 
 	xattr_data = kzalloc(sizeof(*xattr_data), GFP_NOFS);
 	if (!xattr_data)
@@ -952,4 +1007,23 @@ static int __init init_evm(void)
 	return error;
 }
 
+static struct security_hook_list evm_hooks[] __lsm_ro_after_init = {
+	LSM_HOOK_INIT(inode_setattr, evm_inode_setattr),
+	LSM_HOOK_INIT(inode_post_setattr, evm_inode_post_setattr),
+	LSM_HOOK_INIT(inode_setxattr, evm_inode_setxattr),
+	LSM_HOOK_INIT(inode_set_acl, evm_inode_set_acl),
+	LSM_HOOK_INIT(inode_post_set_acl, evm_inode_post_set_acl),
+	LSM_HOOK_INIT(inode_remove_acl, evm_inode_remove_acl),
+	LSM_HOOK_INIT(inode_post_remove_acl, evm_inode_post_remove_acl),
+	LSM_HOOK_INIT(inode_post_setxattr, evm_inode_post_setxattr),
+	LSM_HOOK_INIT(inode_removexattr, evm_inode_removexattr),
+	LSM_HOOK_INIT(inode_post_removexattr, evm_inode_post_removexattr),
+	LSM_HOOK_INIT(inode_init_security, evm_inode_init_security),
+};
+
+void __init init_evm_lsm(void)
+{
+	security_add_hooks(evm_hooks, ARRAY_SIZE(evm_hooks), "integrity");
+}
+
 late_initcall(init_evm);
diff --git a/security/integrity/iint.c b/security/integrity/iint.c
index bbadf974b31..952d5ea4e18 100644
--- a/security/integrity/iint.c
+++ b/security/integrity/iint.c
@@ -179,12 +179,19 @@ static int __init integrity_lsm_init(void)
 			      0, SLAB_PANIC, init_once);
 
 	init_ima_lsm();
+	init_evm_lsm();
 	return 0;
 }
+
+struct lsm_blob_sizes integrity_blob_sizes __lsm_ro_after_init = {
+	.lbs_xattr = 1,
+};
+
 DEFINE_LSM(integrity) = {
 	.name = "integrity",
 	.init = integrity_lsm_init,
 	.order = LSM_ORDER_LAST,
+	.blobs = &integrity_blob_sizes,
 };
 
 /*
diff --git a/security/integrity/integrity.h b/security/integrity/integrity.h
index c72d375a356..76e7eda6651 100644
--- a/security/integrity/integrity.h
+++ b/security/integrity/integrity.h
@@ -188,6 +188,7 @@ int integrity_kernel_read(struct file *file, loff_t offset,
 #define INTEGRITY_KEYRING_MAX		4
 
 extern struct dentry *integrity_dir;
+extern struct lsm_blob_sizes integrity_blob_sizes;
 
 struct modsig;
 
@@ -199,6 +200,14 @@ static inline void __init init_ima_lsm(void)
 }
 #endif
 
+#ifdef CONFIG_EVM
+void __init init_evm_lsm(void);
+#else
+static inline void __init init_evm_lsm(void)
+{
+}
+#endif
+
 #ifdef CONFIG_INTEGRITY_SIGNATURE
 
 int integrity_digsig_verify(const unsigned int id, const char *sig, int siglen,
diff --git a/security/security.c b/security/security.c
index 9bc6a4ef758..74abf04feef 100644
--- a/security/security.c
+++ b/security/security.c
@@ -20,13 +20,13 @@
 #include <linux/kernel_read_file.h>
 #include <linux/lsm_hooks.h>
 #include <linux/integrity.h>
-#include <linux/evm.h>
 #include <linux/fsnotify.h>
 #include <linux/mman.h>
 #include <linux/mount.h>
 #include <linux/personality.h>
 #include <linux/backing-dev.h>
 #include <linux/string.h>
+#include <linux/xattr.h>
 #include <linux/msg.h>
 #include <net/flow.h>
 
@@ -1662,8 +1662,8 @@ int security_inode_init_security(struct inode *inode, struct inode *dir,
 	if (!initxattrs)
 		return call_int_hook(inode_init_security, -EOPNOTSUPP, inode,
 				    dir, qstr, NULL);
-	/* Allocate +1 for EVM and +1 as terminator. */
-	new_xattrs = kcalloc(blob_sizes.lbs_xattr + 2, sizeof(*new_xattrs),
+	/* Allocate +1 for terminator. */
+	new_xattrs = kcalloc(blob_sizes.lbs_xattr + 1, sizeof(*new_xattrs),
 			     GFP_NOFS);
 	if (!new_xattrs)
 		return -ENOMEM;
@@ -1699,9 +1699,6 @@ int security_inode_init_security(struct inode *inode, struct inode *dir,
 	if (!num_filled_xattrs)
 		goto out;
 
-	ret = evm_inode_init_security(inode, dir, qstr, new_xattrs);
-	if (ret && ret != -EOPNOTSUPP)
-		goto out;
 	ret = initxattrs(inode, new_xattrs, fs_data);
 out:
 	for (xattr = new_xattrs; xattr->value != NULL; xattr++)
@@ -2201,14 +2198,9 @@ int security_inode_permission(struct inode *inode, int mask)
 int security_inode_setattr(struct mnt_idmap *idmap,
 			   struct dentry *dentry, struct iattr *attr)
 {
-	int ret;
-
 	if (unlikely(IS_PRIVATE(d_backing_inode(dentry))))
 		return 0;
-	ret = call_int_hook(inode_setattr, 0, idmap, dentry, attr);
-	if (ret)
-		return ret;
-	return evm_inode_setattr(idmap, dentry, attr);
+	return call_int_hook(inode_setattr, 0, idmap, dentry, attr);
 }
 EXPORT_SYMBOL_GPL(security_inode_setattr);
 
@@ -2272,9 +2264,7 @@ int security_inode_setxattr(struct mnt_idmap *idmap,
 
 	if (ret == 1)
 		ret = cap_inode_setxattr(dentry, name, value, size, flags);
-	if (ret)
-		return ret;
-	return evm_inode_setxattr(idmap, dentry, name, value, size, flags);
+	return ret;
 }
 
 /**
@@ -2293,15 +2283,10 @@ int security_inode_set_acl(struct mnt_idmap *idmap,
 			   struct dentry *dentry, const char *acl_name,
 			   struct posix_acl *kacl)
 {
-	int ret;
-
 	if (unlikely(IS_PRIVATE(d_backing_inode(dentry))))
 		return 0;
-	ret = call_int_hook(inode_set_acl, 0, idmap, dentry, acl_name,
-			    kacl);
-	if (ret)
-		return ret;
-	return evm_inode_set_acl(idmap, dentry, acl_name, kacl);
+	return call_int_hook(inode_set_acl, 0, idmap, dentry, acl_name,
+			     kacl);
 }
 
 /**
@@ -2354,14 +2339,9 @@ int security_inode_get_acl(struct mnt_idmap *idmap,
 int security_inode_remove_acl(struct mnt_idmap *idmap,
 			      struct dentry *dentry, const char *acl_name)
 {
-	int ret;
-
 	if (unlikely(IS_PRIVATE(d_backing_inode(dentry))))
 		return 0;
-	ret = call_int_hook(inode_remove_acl, 0, idmap, dentry, acl_name);
-	if (ret)
-		return ret;
-	return evm_inode_remove_acl(idmap, dentry, acl_name);
+	return call_int_hook(inode_remove_acl, 0, idmap, dentry, acl_name);
 }
 
 /**
@@ -2397,7 +2377,6 @@ void security_inode_post_setxattr(struct dentry *dentry, const char *name,
 	if (unlikely(IS_PRIVATE(d_backing_inode(dentry))))
 		return;
 	call_void_hook(inode_post_setxattr, dentry, name, value, size, flags);
-	evm_inode_post_setxattr(dentry, name, value, size, flags);
 }
 
 /**
@@ -2458,9 +2437,7 @@ int security_inode_removexattr(struct mnt_idmap *idmap,
 	ret = call_int_hook(inode_removexattr, 1, idmap, dentry, name);
 	if (ret == 1)
 		ret = cap_inode_removexattr(idmap, dentry, name);
-	if (ret)
-		return ret;
-	return evm_inode_removexattr(idmap, dentry, name);
+	return ret;
 }
 
 /**
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 79+ messages in thread

* [PATCH 27/28] integrity: Move integrity functions to the LSM infrastructure
  2023-03-03 18:18 [PATCH 00/28] security: Move IMA and EVM to the LSM infrastructure Roberto Sassu
                   ` (25 preceding siblings ...)
  2023-03-03 18:26 ` [PATCH 26/28] evm: Move " Roberto Sassu
@ 2023-03-03 18:26 ` Roberto Sassu
  2023-03-03 18:26 ` [PATCH 28/28] integrity: Switch from rbtree to LSM-managed blob for integrity_iint_cache Roberto Sassu
  2023-03-08 15:14 ` [PATCH 00/28] security: Move IMA and EVM to the LSM infrastructure Mimi Zohar
  28 siblings, 0 replies; 79+ messages in thread
From: Roberto Sassu @ 2023-03-03 18:26 UTC (permalink / raw)
  To: viro, chuck.lever, jlayton, zohar, dmitry.kasatkin, paul,
	jmorris, serge, dhowells, jarkko, stephen.smalley.work, eparis,
	casey, brauner
  Cc: linux-fsdevel, linux-nfs, linux-integrity, linux-security-module,
	keyrings, selinux, linux-kernel, stefanb, Roberto Sassu

From: Roberto Sassu <roberto.sassu@huawei.com>

Remove hardcoded calls to integrity functions from the LSM infrastructure.
Also move the global declaration of integrity_inode_get() to
security/integrity/integrity.h, so that the function can be still called by
IMA.

Register integrity functions as hook implementations in
integrity_lsm_init().

Signed-off-by: Roberto Sassu <roberto.sassu@huawei.com>
---
 include/linux/integrity.h      | 26 --------------------------
 security/integrity/iint.c      | 11 ++++++++++-
 security/integrity/integrity.h |  7 +++++++
 security/security.c            |  9 +--------
 4 files changed, 18 insertions(+), 35 deletions(-)

diff --git a/include/linux/integrity.h b/include/linux/integrity.h
index 2ea0f2f65ab..afaae7ad26f 100644
--- a/include/linux/integrity.h
+++ b/include/linux/integrity.h
@@ -21,38 +21,12 @@ enum integrity_status {
 
 /* List of EVM protected security xattrs */
 #ifdef CONFIG_INTEGRITY
-extern struct integrity_iint_cache *integrity_inode_get(struct inode *inode);
-extern void integrity_inode_free(struct inode *inode);
 extern void __init integrity_load_keys(void);
 
 #else
-static inline struct integrity_iint_cache *
-				integrity_inode_get(struct inode *inode)
-{
-	return NULL;
-}
-
-static inline void integrity_inode_free(struct inode *inode)
-{
-	return;
-}
-
 static inline void integrity_load_keys(void)
 {
 }
 #endif /* CONFIG_INTEGRITY */
 
-#ifdef CONFIG_INTEGRITY_ASYMMETRIC_KEYS
-
-extern int integrity_kernel_module_request(char *kmod_name);
-
-#else
-
-static inline int integrity_kernel_module_request(char *kmod_name)
-{
-	return 0;
-}
-
-#endif /* CONFIG_INTEGRITY_ASYMMETRIC_KEYS */
-
 #endif /* _LINUX_INTEGRITY_H */
diff --git a/security/integrity/iint.c b/security/integrity/iint.c
index 952d5ea4e18..b12215d8b13 100644
--- a/security/integrity/iint.c
+++ b/security/integrity/iint.c
@@ -143,7 +143,7 @@ struct integrity_iint_cache *integrity_inode_get(struct inode *inode)
  *
  * Free the integrity information(iint) associated with an inode.
  */
-void integrity_inode_free(struct inode *inode)
+static void integrity_inode_free(struct inode *inode)
 {
 	struct integrity_iint_cache *iint;
 
@@ -172,12 +172,21 @@ static void init_once(void *foo)
 	mutex_init(&iint->mutex);
 }
 
+static struct security_hook_list integrity_hooks[] __lsm_ro_after_init = {
+	LSM_HOOK_INIT(inode_free_security, integrity_inode_free),
+#ifdef CONFIG_INTEGRITY_ASYMMETRIC_KEYS
+	LSM_HOOK_INIT(kernel_module_request, integrity_kernel_module_request),
+#endif
+};
+
 static int __init integrity_lsm_init(void)
 {
 	iint_cache =
 	    kmem_cache_create("iint_cache", sizeof(struct integrity_iint_cache),
 			      0, SLAB_PANIC, init_once);
 
+	security_add_hooks(integrity_hooks, ARRAY_SIZE(integrity_hooks),
+			   "integrity");
 	init_ima_lsm();
 	init_evm_lsm();
 	return 0;
diff --git a/security/integrity/integrity.h b/security/integrity/integrity.h
index 76e7eda6651..a3cbc65f9c6 100644
--- a/security/integrity/integrity.h
+++ b/security/integrity/integrity.h
@@ -177,6 +177,7 @@ struct integrity_iint_cache {
  * integrity data associated with an inode.
  */
 struct integrity_iint_cache *integrity_iint_find(struct inode *inode);
+struct integrity_iint_cache *integrity_inode_get(struct inode *inode);
 
 int integrity_kernel_read(struct file *file, loff_t offset,
 			  void *addr, unsigned long count);
@@ -250,12 +251,18 @@ static inline int __init integrity_load_cert(const unsigned int id,
 #ifdef CONFIG_INTEGRITY_ASYMMETRIC_KEYS
 int asymmetric_verify(struct key *keyring, const char *sig,
 		      int siglen, const char *data, int datalen);
+extern int integrity_kernel_module_request(char *kmod_name);
 #else
 static inline int asymmetric_verify(struct key *keyring, const char *sig,
 				    int siglen, const char *data, int datalen)
 {
 	return -EOPNOTSUPP;
 }
+
+static inline int integrity_kernel_module_request(char *kmod_name)
+{
+	return 0;
+}
 #endif
 
 #ifdef CONFIG_IMA_APPRAISE_MODSIG
diff --git a/security/security.c b/security/security.c
index 74abf04feef..985e4bf3309 100644
--- a/security/security.c
+++ b/security/security.c
@@ -19,7 +19,6 @@
 #include <linux/kernel.h>
 #include <linux/kernel_read_file.h>
 #include <linux/lsm_hooks.h>
-#include <linux/integrity.h>
 #include <linux/fsnotify.h>
 #include <linux/mman.h>
 #include <linux/mount.h>
@@ -1496,7 +1495,6 @@ static void inode_free_by_rcu(struct rcu_head *head)
  */
 void security_inode_free(struct inode *inode)
 {
-	integrity_inode_free(inode);
 	call_void_hook(inode_free_security, inode);
 	/*
 	 * The inode may still be referenced in a path walk and
@@ -3147,12 +3145,7 @@ int security_kernel_create_files_as(struct cred *new, struct inode *inode)
  */
 int security_kernel_module_request(char *kmod_name)
 {
-	int ret;
-
-	ret = call_int_hook(kernel_module_request, 0, kmod_name);
-	if (ret)
-		return ret;
-	return integrity_kernel_module_request(kmod_name);
+	return call_int_hook(kernel_module_request, 0, kmod_name);
 }
 
 /**
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 79+ messages in thread

* [PATCH 28/28] integrity: Switch from rbtree to LSM-managed blob for integrity_iint_cache
  2023-03-03 18:18 [PATCH 00/28] security: Move IMA and EVM to the LSM infrastructure Roberto Sassu
                   ` (26 preceding siblings ...)
  2023-03-03 18:26 ` [PATCH 27/28] integrity: Move integrity functions to the " Roberto Sassu
@ 2023-03-03 18:26 ` Roberto Sassu
  2023-03-08 15:14 ` [PATCH 00/28] security: Move IMA and EVM to the LSM infrastructure Mimi Zohar
  28 siblings, 0 replies; 79+ messages in thread
From: Roberto Sassu @ 2023-03-03 18:26 UTC (permalink / raw)
  To: viro, chuck.lever, jlayton, zohar, dmitry.kasatkin, paul,
	jmorris, serge, dhowells, jarkko, stephen.smalley.work, eparis,
	casey, brauner
  Cc: linux-fsdevel, linux-nfs, linux-integrity, linux-security-module,
	keyrings, selinux, linux-kernel, stefanb, Roberto Sassu

From: Roberto Sassu <roberto.sassu@huawei.com>

Before the security field of kernel objects could be shared among LSMs with
the LSM stacking feature, IMA and EVM had to rely on an alternative storage
of inode metadata. The association between inode metadata and inode is
maintained through an rbtree.

With the reservation mechanism offered by the LSM infrastructure, the
rbtree is no longer necessary, as each LSM could reserve a space in the
security blob for each inode. Thus, request from the 'integrity' LSM a
space in the security blob for the pointer of inode metadata
(integrity_iint_cache structure).

Prefer this to allocating the integrity_iint_cache structure directly, as
IMA would require it only for a subset of inodes. Always allocating it
would cause a waste of memory.

Introduce two primitives for getting and setting the pointer of
integrity_iint_cache in the security blob, respectively
integrity_inode_get_iint() and integrity_inode_set_iint(). This would make
the code more understandable, as they directly replace rbtree operations.

Locking is not needed, as access to inode metadata is not shared, it is per
inode.

Signed-off-by: Roberto Sassu <roberto.sassu@huawei.com>
---
 security/integrity/iint.c      | 64 ++++------------------------------
 security/integrity/integrity.h | 20 ++++++++++-
 2 files changed, 25 insertions(+), 59 deletions(-)

diff --git a/security/integrity/iint.c b/security/integrity/iint.c
index b12215d8b13..1610380de2f 100644
--- a/security/integrity/iint.c
+++ b/security/integrity/iint.c
@@ -14,58 +14,25 @@
 #include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/spinlock.h>
-#include <linux/rbtree.h>
 #include <linux/file.h>
 #include <linux/uaccess.h>
 #include <linux/security.h>
 #include <linux/lsm_hooks.h>
 #include "integrity.h"
 
-static struct rb_root integrity_iint_tree = RB_ROOT;
-static DEFINE_RWLOCK(integrity_iint_lock);
 static struct kmem_cache *iint_cache __read_mostly;
 
 struct dentry *integrity_dir;
 
-/*
- * __integrity_iint_find - return the iint associated with an inode
- */
-static struct integrity_iint_cache *__integrity_iint_find(struct inode *inode)
-{
-	struct integrity_iint_cache *iint;
-	struct rb_node *n = integrity_iint_tree.rb_node;
-
-	while (n) {
-		iint = rb_entry(n, struct integrity_iint_cache, rb_node);
-
-		if (inode < iint->inode)
-			n = n->rb_left;
-		else if (inode > iint->inode)
-			n = n->rb_right;
-		else
-			break;
-	}
-	if (!n)
-		return NULL;
-
-	return iint;
-}
-
 /*
  * integrity_iint_find - return the iint associated with an inode
  */
 struct integrity_iint_cache *integrity_iint_find(struct inode *inode)
 {
-	struct integrity_iint_cache *iint;
-
 	if (!IS_IMA(inode))
 		return NULL;
 
-	read_lock(&integrity_iint_lock);
-	iint = __integrity_iint_find(inode);
-	read_unlock(&integrity_iint_lock);
-
-	return iint;
+	return integrity_inode_get_iint(inode);
 }
 
 static void iint_free(struct integrity_iint_cache *iint)
@@ -94,9 +61,7 @@ static void iint_free(struct integrity_iint_cache *iint)
  */
 struct integrity_iint_cache *integrity_inode_get(struct inode *inode)
 {
-	struct rb_node **p;
-	struct rb_node *node, *parent = NULL;
-	struct integrity_iint_cache *iint, *test_iint;
+	struct integrity_iint_cache *iint;
 
 	/*
 	 * The integrity's "iint_cache" is initialized at security_init(),
@@ -114,26 +79,10 @@ struct integrity_iint_cache *integrity_inode_get(struct inode *inode)
 	if (!iint)
 		return NULL;
 
-	write_lock(&integrity_iint_lock);
-
-	p = &integrity_iint_tree.rb_node;
-	while (*p) {
-		parent = *p;
-		test_iint = rb_entry(parent, struct integrity_iint_cache,
-				     rb_node);
-		if (inode < test_iint->inode)
-			p = &(*p)->rb_left;
-		else
-			p = &(*p)->rb_right;
-	}
-
 	iint->inode = inode;
-	node = &iint->rb_node;
 	inode->i_flags |= S_IMA;
-	rb_link_node(node, parent, p);
-	rb_insert_color(node, &integrity_iint_tree);
+	integrity_inode_set_iint(inode, iint);
 
-	write_unlock(&integrity_iint_lock);
 	return iint;
 }
 
@@ -150,10 +99,8 @@ static void integrity_inode_free(struct inode *inode)
 	if (!IS_IMA(inode))
 		return;
 
-	write_lock(&integrity_iint_lock);
-	iint = __integrity_iint_find(inode);
-	rb_erase(&iint->rb_node, &integrity_iint_tree);
-	write_unlock(&integrity_iint_lock);
+	iint = integrity_iint_find(inode);
+	integrity_inode_set_iint(inode, NULL);
 
 	iint_free(iint);
 }
@@ -193,6 +140,7 @@ static int __init integrity_lsm_init(void)
 }
 
 struct lsm_blob_sizes integrity_blob_sizes __lsm_ro_after_init = {
+	.lbs_inode = sizeof(struct integrity_iint_cache *),
 	.lbs_xattr = 1,
 };
 
diff --git a/security/integrity/integrity.h b/security/integrity/integrity.h
index a3cbc65f9c6..720c2f183e4 100644
--- a/security/integrity/integrity.h
+++ b/security/integrity/integrity.h
@@ -18,6 +18,7 @@
 #include <crypto/hash.h>
 #include <linux/key.h>
 #include <linux/audit.h>
+#include <linux/lsm_hooks.h>
 
 /* iint action cache flags */
 #define IMA_MEASURE		0x00000001
@@ -157,7 +158,6 @@ struct ima_file_id {
 
 /* integrity data associated with an inode */
 struct integrity_iint_cache {
-	struct rb_node rb_node;	/* rooted in integrity_iint_tree */
 	struct mutex mutex;	/* protects: version, flags, digest */
 	struct inode *inode;	/* back pointer to inode in question */
 	u64 version;		/* track inode changes */
@@ -191,6 +191,24 @@ int integrity_kernel_read(struct file *file, loff_t offset,
 extern struct dentry *integrity_dir;
 extern struct lsm_blob_sizes integrity_blob_sizes;
 
+static inline struct integrity_iint_cache *
+integrity_inode_get_iint(const struct inode *inode)
+{
+	struct integrity_iint_cache **iint_sec;
+
+	iint_sec = inode->i_security + integrity_blob_sizes.lbs_inode;
+	return *iint_sec;
+}
+
+static inline void integrity_inode_set_iint(const struct inode *inode,
+					    struct integrity_iint_cache *iint)
+{
+	struct integrity_iint_cache **iint_sec;
+
+	iint_sec = inode->i_security + integrity_blob_sizes.lbs_inode;
+	*iint_sec = iint;
+}
+
 struct modsig;
 
 #ifdef CONFIG_IMA
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 79+ messages in thread

* Re: [PATCH 26/28] evm: Move to LSM infrastructure
  2023-03-03 18:26 ` [PATCH 26/28] evm: Move " Roberto Sassu
@ 2023-03-04 21:36   ` Casey Schaufler
  2023-03-06  9:21     ` Roberto Sassu
  0 siblings, 1 reply; 79+ messages in thread
From: Casey Schaufler @ 2023-03-04 21:36 UTC (permalink / raw)
  To: Roberto Sassu, viro, chuck.lever, jlayton, zohar,
	dmitry.kasatkin, paul, jmorris, serge, dhowells, jarkko,
	stephen.smalley.work, eparis, brauner
  Cc: linux-fsdevel, linux-nfs, linux-integrity, linux-security-module,
	keyrings, selinux, linux-kernel, stefanb, Roberto Sassu, casey


On 3/3/2023 10:26 AM, Roberto Sassu wrote:
> From: Roberto Sassu <roberto.sassu@huawei.com>
>
> As for IMA, remove hardcoded EVM function calls from the LSM infrastructure
> and the VFS. Make EVM functions as static (except for
> evm_inode_init_security(), which is exported), and register them as hook
> implementations in init_evm_lsm(), called from integrity_lsm_init().
>
> Finally, switch to the LSM reservation mechanism for the EVM xattr, by
> setting the lbs_xattr field of the lsm_blob_sizes structure, and
> consequently decrement the number of xattrs to allocate in
> security_inode_init_security().
>
> Signed-off-by: Roberto Sassu <roberto.sassu@huawei.com>
> ---
>  fs/attr.c                         |   2 -
>  fs/posix_acl.c                    |   3 -
>  fs/xattr.c                        |   2 -
>  include/linux/evm.h               | 116 ------------------------------
>  security/integrity/evm/evm_main.c | 106 ++++++++++++++++++++++-----
>  security/integrity/iint.c         |   7 ++
>  security/integrity/integrity.h    |   9 +++
>  security/security.c               |  41 +++--------
>  8 files changed, 115 insertions(+), 171 deletions(-)
>
> diff --git a/fs/attr.c b/fs/attr.c
> index 406d782dfab..1b911a627fe 100644
> --- a/fs/attr.c
> +++ b/fs/attr.c
> @@ -16,7 +16,6 @@
>  #include <linux/fcntl.h>
>  #include <linux/filelock.h>
>  #include <linux/security.h>
> -#include <linux/evm.h>
>  
>  #include "internal.h"
>  
> @@ -485,7 +484,6 @@ int notify_change(struct mnt_idmap *idmap, struct dentry *dentry,
>  	if (!error) {
>  		fsnotify_change(dentry, ia_valid);
>  		security_inode_post_setattr(idmap, dentry, ia_valid);
> -		evm_inode_post_setattr(idmap, dentry, ia_valid);
>  	}
>  
>  	return error;
> diff --git a/fs/posix_acl.c b/fs/posix_acl.c
> index 5b8c92fce0c..608cb0a9f84 100644
> --- a/fs/posix_acl.c
> +++ b/fs/posix_acl.c
> @@ -26,7 +26,6 @@
>  #include <linux/mnt_idmapping.h>
>  #include <linux/iversion.h>
>  #include <linux/security.h>
> -#include <linux/evm.h>
>  #include <linux/fsnotify.h>
>  #include <linux/filelock.h>
>  
> @@ -1103,7 +1102,6 @@ int vfs_set_acl(struct mnt_idmap *idmap, struct dentry *dentry,
>  	if (!error) {
>  		fsnotify_xattr(dentry);
>  		security_inode_post_set_acl(dentry, acl_name, kacl);
> -		evm_inode_post_set_acl(dentry, acl_name, kacl);
>  	}
>  
>  out_inode_unlock:
> @@ -1214,7 +1212,6 @@ int vfs_remove_acl(struct mnt_idmap *idmap, struct dentry *dentry,
>  	if (!error) {
>  		fsnotify_xattr(dentry);
>  		security_inode_post_remove_acl(idmap, dentry, acl_name);
> -		evm_inode_post_remove_acl(idmap, dentry, acl_name);
>  	}
>  
>  out_inode_unlock:
> diff --git a/fs/xattr.c b/fs/xattr.c
> index 10c959d9fc6..7708ffdacca 100644
> --- a/fs/xattr.c
> +++ b/fs/xattr.c
> @@ -16,7 +16,6 @@
>  #include <linux/mount.h>
>  #include <linux/namei.h>
>  #include <linux/security.h>
> -#include <linux/evm.h>
>  #include <linux/syscalls.h>
>  #include <linux/export.h>
>  #include <linux/fsnotify.h>
> @@ -535,7 +534,6 @@ __vfs_removexattr_locked(struct mnt_idmap *idmap,
>  	if (!error) {
>  		fsnotify_xattr(dentry);
>  		security_inode_post_removexattr(dentry, name);
> -		evm_inode_post_removexattr(dentry, name);
>  	}
>  
>  out:
> diff --git a/include/linux/evm.h b/include/linux/evm.h
> index 8c043273552..61794299f09 100644
> --- a/include/linux/evm.h
> +++ b/include/linux/evm.h
> @@ -21,46 +21,6 @@ extern enum integrity_status evm_verifyxattr(struct dentry *dentry,
>  					     void *xattr_value,
>  					     size_t xattr_value_len,
>  					     struct integrity_iint_cache *iint);
> -extern int evm_inode_setattr(struct mnt_idmap *idmap,
> -			     struct dentry *dentry, struct iattr *attr);
> -extern void evm_inode_post_setattr(struct mnt_idmap *idmap,
> -				   struct dentry *dentry, int ia_valid);
> -extern int evm_inode_setxattr(struct mnt_idmap *idmap,
> -			      struct dentry *dentry, const char *name,
> -			      const void *value, size_t size, int flags);
> -extern void evm_inode_post_setxattr(struct dentry *dentry,
> -				    const char *xattr_name,
> -				    const void *xattr_value,
> -				    size_t xattr_value_len,
> -				    int flags);
> -extern int evm_inode_removexattr(struct mnt_idmap *idmap,
> -				 struct dentry *dentry, const char *xattr_name);
> -extern void evm_inode_post_removexattr(struct dentry *dentry,
> -				       const char *xattr_name);
> -static inline void evm_inode_post_remove_acl(struct mnt_idmap *idmap,
> -					     struct dentry *dentry,
> -					     const char *acl_name)
> -{
> -	evm_inode_post_removexattr(dentry, acl_name);
> -}
> -extern int evm_inode_set_acl(struct mnt_idmap *idmap,
> -			     struct dentry *dentry, const char *acl_name,
> -			     struct posix_acl *kacl);
> -static inline int evm_inode_remove_acl(struct mnt_idmap *idmap,
> -				       struct dentry *dentry,
> -				       const char *acl_name)
> -{
> -	return evm_inode_set_acl(idmap, dentry, acl_name, NULL);
> -}
> -static inline void evm_inode_post_set_acl(struct dentry *dentry,
> -					  const char *acl_name,
> -					  struct posix_acl *kacl)
> -{
> -	return evm_inode_post_setxattr(dentry, acl_name, NULL, 0, 0);
> -}
> -extern int evm_inode_init_security(struct inode *inode, struct inode *dir,
> -				   const struct qstr *qstr,
> -				   struct xattr *xattrs);
>  extern bool evm_revalidate_status(const char *xattr_name);
>  extern int evm_protected_xattr_if_enabled(const char *req_xattr_name);
>  extern int evm_read_protected_xattrs(struct dentry *dentry, u8 *buffer,
> @@ -92,82 +52,6 @@ static inline enum integrity_status evm_verifyxattr(struct dentry *dentry,
>  }
>  #endif
>  
> -static inline int evm_inode_setattr(struct mnt_idmap *idmap,
> -				    struct dentry *dentry, struct iattr *attr)
> -{
> -	return 0;
> -}
> -
> -static inline void evm_inode_post_setattr(struct mnt_idmap *idmap,
> -					  struct dentry *dentry, int ia_valid)
> -{
> -	return;
> -}
> -
> -static inline int evm_inode_setxattr(struct mnt_idmap *idmap,
> -				     struct dentry *dentry, const char *name,
> -				     const void *value, size_t size, int flags)
> -{
> -	return 0;
> -}
> -
> -static inline void evm_inode_post_setxattr(struct dentry *dentry,
> -					   const char *xattr_name,
> -					   const void *xattr_value,
> -					   size_t xattr_value_len,
> -					   int flags)
> -{
> -	return;
> -}
> -
> -static inline int evm_inode_removexattr(struct mnt_idmap *idmap,
> -					struct dentry *dentry,
> -					const char *xattr_name)
> -{
> -	return 0;
> -}
> -
> -static inline void evm_inode_post_removexattr(struct dentry *dentry,
> -					      const char *xattr_name)
> -{
> -	return;
> -}
> -
> -static inline void evm_inode_post_remove_acl(struct mnt_idmap *idmap,
> -					     struct dentry *dentry,
> -					     const char *acl_name)
> -{
> -	return;
> -}
> -
> -static inline int evm_inode_set_acl(struct mnt_idmap *idmap,
> -				    struct dentry *dentry, const char *acl_name,
> -				    struct posix_acl *kacl)
> -{
> -	return 0;
> -}
> -
> -static inline int evm_inode_remove_acl(struct mnt_idmap *idmap,
> -				       struct dentry *dentry,
> -				       const char *acl_name)
> -{
> -	return 0;
> -}
> -
> -static inline void evm_inode_post_set_acl(struct dentry *dentry,
> -					  const char *acl_name,
> -					  struct posix_acl *kacl)
> -{
> -	return;
> -}
> -
> -static inline int evm_inode_init_security(struct inode *inode, struct inode *dir,
> -					  const struct qstr *qstr,
> -					  struct xattr *xattrs)
> -{
> -	return 0;
> -}
> -
>  static inline bool evm_revalidate_status(const char *xattr_name)
>  {
>  	return false;
> diff --git a/security/integrity/evm/evm_main.c b/security/integrity/evm/evm_main.c
> index 8b5c472f78b..c45bc97277c 100644
> --- a/security/integrity/evm/evm_main.c
> +++ b/security/integrity/evm/evm_main.c
> @@ -19,6 +19,7 @@
>  #include <linux/xattr.h>
>  #include <linux/integrity.h>
>  #include <linux/evm.h>
> +#include <linux/lsm_hooks.h>
>  #include <linux/magic.h>
>  #include <linux/posix_acl_xattr.h>
>  
> @@ -566,9 +567,9 @@ static int evm_protect_xattr(struct mnt_idmap *idmap,
>   * userspace from writing HMAC value.  Writing 'security.evm' requires
>   * requires CAP_SYS_ADMIN privileges.
>   */
> -int evm_inode_setxattr(struct mnt_idmap *idmap, struct dentry *dentry,
> -		       const char *xattr_name, const void *xattr_value,
> -		       size_t xattr_value_len, int flags)
> +static int evm_inode_setxattr(struct mnt_idmap *idmap, struct dentry *dentry,
> +			      const char *xattr_name, const void *xattr_value,
> +			      size_t xattr_value_len, int flags)
>  {
>  	const struct evm_ima_xattr_data *xattr_data = xattr_value;
>  
> @@ -598,8 +599,8 @@ int evm_inode_setxattr(struct mnt_idmap *idmap, struct dentry *dentry,
>   * Removing 'security.evm' requires CAP_SYS_ADMIN privileges and that
>   * the current value is valid.
>   */
> -int evm_inode_removexattr(struct mnt_idmap *idmap,
> -			  struct dentry *dentry, const char *xattr_name)
> +static int evm_inode_removexattr(struct mnt_idmap *idmap, struct dentry *dentry,
> +				 const char *xattr_name)
>  {
>  	/* Policy permits modification of the protected xattrs even though
>  	 * there's no HMAC key loaded
> @@ -649,9 +650,11 @@ static inline int evm_inode_set_acl_change(struct mnt_idmap *idmap,
>   * Prevent modifying posix acls causing the EVM HMAC to be re-calculated
>   * and 'security.evm' xattr updated, unless the existing 'security.evm' is
>   * valid.
> + *
> + * Return: zero on success, -EPERM on failure.
>   */
> -int evm_inode_set_acl(struct mnt_idmap *idmap, struct dentry *dentry,
> -		      const char *acl_name, struct posix_acl *kacl)
> +static int evm_inode_set_acl(struct mnt_idmap *idmap, struct dentry *dentry,
> +			     const char *acl_name, struct posix_acl *kacl)
>  {
>  	enum integrity_status evm_status;
>  
> @@ -690,6 +693,24 @@ int evm_inode_set_acl(struct mnt_idmap *idmap, struct dentry *dentry,
>  	return -EPERM;
>  }
>  
> +/**
> + * evm_inode_remove_acl - Protect the EVM extended attribute from posix acls
> + * @idmap: idmap of the mount
> + * @dentry: pointer to the affected dentry
> + * @acl_name: name of the posix acl
> + *
> + * Prevent removing posix acls causing the EVM HMAC to be re-calculated
> + * and 'security.evm' xattr updated, unless the existing 'security.evm' is
> + * valid.
> + *
> + * Return: zero on success, -EPERM on failure.
> + */
> +static int evm_inode_remove_acl(struct mnt_idmap *idmap, struct dentry *dentry,
> +				const char *acl_name)
> +{
> +	return evm_inode_set_acl(idmap, dentry, acl_name, NULL);
> +}
> +
>  static void evm_reset_status(struct inode *inode)
>  {
>  	struct integrity_iint_cache *iint;
> @@ -738,9 +759,11 @@ bool evm_revalidate_status(const char *xattr_name)
>   * __vfs_setxattr_noperm().  The caller of which has taken the inode's
>   * i_mutex lock.
>   */
> -void evm_inode_post_setxattr(struct dentry *dentry, const char *xattr_name,
> -			     const void *xattr_value, size_t xattr_value_len,
> -			     int flags)
> +static void evm_inode_post_setxattr(struct dentry *dentry,
> +				    const char *xattr_name,
> +				    const void *xattr_value,
> +				    size_t xattr_value_len,
> +				    int flags)
>  {
>  	if (!evm_revalidate_status(xattr_name))
>  		return;
> @@ -756,6 +779,21 @@ void evm_inode_post_setxattr(struct dentry *dentry, const char *xattr_name,
>  	evm_update_evmxattr(dentry, xattr_name, xattr_value, xattr_value_len);
>  }
>  
> +/**
> + * evm_inode_post_set_acl - Update the EVM extended attribute from posix acls
> + * @dentry: pointer to the affected dentry
> + * @acl_name: name of the posix acl
> + * @kacl: pointer to the posix acls
> + *
> + * Update the 'security.evm' xattr with the EVM HMAC re-calculated after setting
> + * posix acls.
> + */
> +static void evm_inode_post_set_acl(struct dentry *dentry, const char *acl_name,
> +				   struct posix_acl *kacl)
> +{
> +	return evm_inode_post_setxattr(dentry, acl_name, NULL, 0, 0);
> +}
> +
>  /**
>   * evm_inode_post_removexattr - update 'security.evm' after removing the xattr
>   * @dentry: pointer to the affected dentry
> @@ -766,7 +804,8 @@ void evm_inode_post_setxattr(struct dentry *dentry, const char *xattr_name,
>   * No need to take the i_mutex lock here, as this function is called from
>   * vfs_removexattr() which takes the i_mutex.
>   */
> -void evm_inode_post_removexattr(struct dentry *dentry, const char *xattr_name)
> +static void evm_inode_post_removexattr(struct dentry *dentry,
> +				       const char *xattr_name)
>  {
>  	if (!evm_revalidate_status(xattr_name))
>  		return;
> @@ -782,6 +821,22 @@ void evm_inode_post_removexattr(struct dentry *dentry, const char *xattr_name)
>  	evm_update_evmxattr(dentry, xattr_name, NULL, 0);
>  }
>  
> +/**
> + * evm_inode_post_remove_acl - Update the EVM extended attribute from posix acls
> + * @idmap: idmap of the mount
> + * @dentry: pointer to the affected dentry
> + * @acl_name: name of the posix acl
> + *
> + * Update the 'security.evm' xattr with the EVM HMAC re-calculated after
> + * removing posix acls.
> + */
> +static inline void evm_inode_post_remove_acl(struct mnt_idmap *idmap,
> +					     struct dentry *dentry,
> +					     const char *acl_name)
> +{
> +	evm_inode_post_removexattr(dentry, acl_name);
> +}
> +
>  static int evm_attr_change(struct mnt_idmap *idmap,
>  			   struct dentry *dentry, struct iattr *attr)
>  {
> @@ -805,8 +860,8 @@ static int evm_attr_change(struct mnt_idmap *idmap,
>   * Permit update of file attributes when files have a valid EVM signature,
>   * except in the case of them having an immutable portable signature.
>   */
> -int evm_inode_setattr(struct mnt_idmap *idmap, struct dentry *dentry,
> -		      struct iattr *attr)
> +static int evm_inode_setattr(struct mnt_idmap *idmap, struct dentry *dentry,
> +			     struct iattr *attr)
>  {
>  	unsigned int ia_valid = attr->ia_valid;
>  	enum integrity_status evm_status;
> @@ -853,8 +908,8 @@ int evm_inode_setattr(struct mnt_idmap *idmap, struct dentry *dentry,
>   * This function is called from notify_change(), which expects the caller
>   * to lock the inode's i_mutex.
>   */
> -void evm_inode_post_setattr(struct mnt_idmap *idmap, struct dentry *dentry,
> -			    int ia_valid)
> +static void evm_inode_post_setattr(struct mnt_idmap *idmap,
> +				   struct dentry *dentry, int ia_valid)
>  {
>  	if (!evm_revalidate_status(NULL))
>  		return;
> @@ -892,7 +947,7 @@ int evm_inode_init_security(struct inode *inode, struct inode *dir,
>  	if (!evm_protected_xattrs)
>  		return -EOPNOTSUPP;
>  
> -	evm_xattr = xattr;
> +	evm_xattr = xattrs + integrity_blob_sizes.lbs_xattr;

Please don't do this inline. Convention is to use a function,
intergrity_xattrs() for this.

>  
>  	xattr_data = kzalloc(sizeof(*xattr_data), GFP_NOFS);
>  	if (!xattr_data)
> @@ -952,4 +1007,23 @@ static int __init init_evm(void)
>  	return error;
>  }
>  
> +static struct security_hook_list evm_hooks[] __lsm_ro_after_init = {
> +	LSM_HOOK_INIT(inode_setattr, evm_inode_setattr),
> +	LSM_HOOK_INIT(inode_post_setattr, evm_inode_post_setattr),
> +	LSM_HOOK_INIT(inode_setxattr, evm_inode_setxattr),
> +	LSM_HOOK_INIT(inode_set_acl, evm_inode_set_acl),
> +	LSM_HOOK_INIT(inode_post_set_acl, evm_inode_post_set_acl),
> +	LSM_HOOK_INIT(inode_remove_acl, evm_inode_remove_acl),
> +	LSM_HOOK_INIT(inode_post_remove_acl, evm_inode_post_remove_acl),
> +	LSM_HOOK_INIT(inode_post_setxattr, evm_inode_post_setxattr),
> +	LSM_HOOK_INIT(inode_removexattr, evm_inode_removexattr),
> +	LSM_HOOK_INIT(inode_post_removexattr, evm_inode_post_removexattr),
> +	LSM_HOOK_INIT(inode_init_security, evm_inode_init_security),
> +};
> +
> +void __init init_evm_lsm(void)
> +{
> +	security_add_hooks(evm_hooks, ARRAY_SIZE(evm_hooks), "integrity");
> +}
> +
>  late_initcall(init_evm);
> diff --git a/security/integrity/iint.c b/security/integrity/iint.c
> index bbadf974b31..952d5ea4e18 100644
> --- a/security/integrity/iint.c
> +++ b/security/integrity/iint.c
> @@ -179,12 +179,19 @@ static int __init integrity_lsm_init(void)
>  			      0, SLAB_PANIC, init_once);
>  
>  	init_ima_lsm();
> +	init_evm_lsm();
>  	return 0;
>  }
> +
> +struct lsm_blob_sizes integrity_blob_sizes __lsm_ro_after_init = {
> +	.lbs_xattr = 1,

Really? 1 byte? Don't even think of storing number of elements in lbs_xattr.
The linux_blob_size structure contains sizes of blobs, not number of elements.

> +};
> +
>  DEFINE_LSM(integrity) = {
>  	.name = "integrity",
>  	.init = integrity_lsm_init,
>  	.order = LSM_ORDER_LAST,
> +	.blobs = &integrity_blob_sizes,
>  };
>  
>  /*
> diff --git a/security/integrity/integrity.h b/security/integrity/integrity.h
> index c72d375a356..76e7eda6651 100644
> --- a/security/integrity/integrity.h
> +++ b/security/integrity/integrity.h
> @@ -188,6 +188,7 @@ int integrity_kernel_read(struct file *file, loff_t offset,
>  #define INTEGRITY_KEYRING_MAX		4
>  
>  extern struct dentry *integrity_dir;
> +extern struct lsm_blob_sizes integrity_blob_sizes;
>  
>  struct modsig;
>  
> @@ -199,6 +200,14 @@ static inline void __init init_ima_lsm(void)
>  }
>  #endif
>  
> +#ifdef CONFIG_EVM
> +void __init init_evm_lsm(void);
> +#else
> +static inline void __init init_evm_lsm(void)
> +{
> +}
> +#endif
> +
>  #ifdef CONFIG_INTEGRITY_SIGNATURE
>  
>  int integrity_digsig_verify(const unsigned int id, const char *sig, int siglen,
> diff --git a/security/security.c b/security/security.c
> index 9bc6a4ef758..74abf04feef 100644
> --- a/security/security.c
> +++ b/security/security.c
> @@ -20,13 +20,13 @@
>  #include <linux/kernel_read_file.h>
>  #include <linux/lsm_hooks.h>
>  #include <linux/integrity.h>
> -#include <linux/evm.h>
>  #include <linux/fsnotify.h>
>  #include <linux/mman.h>
>  #include <linux/mount.h>
>  #include <linux/personality.h>
>  #include <linux/backing-dev.h>
>  #include <linux/string.h>
> +#include <linux/xattr.h>
>  #include <linux/msg.h>
>  #include <net/flow.h>
>  
> @@ -1662,8 +1662,8 @@ int security_inode_init_security(struct inode *inode, struct inode *dir,
>  	if (!initxattrs)
>  		return call_int_hook(inode_init_security, -EOPNOTSUPP, inode,
>  				    dir, qstr, NULL);
> -	/* Allocate +1 for EVM and +1 as terminator. */
> -	new_xattrs = kcalloc(blob_sizes.lbs_xattr + 2, sizeof(*new_xattrs),
> +	/* Allocate +1 for terminator. */
> +	new_xattrs = kcalloc(blob_sizes.lbs_xattr + 1, sizeof(*new_xattrs),
>  			     GFP_NOFS);
>  	if (!new_xattrs)
>  		return -ENOMEM;
> @@ -1699,9 +1699,6 @@ int security_inode_init_security(struct inode *inode, struct inode *dir,
>  	if (!num_filled_xattrs)
>  		goto out;
>  
> -	ret = evm_inode_init_security(inode, dir, qstr, new_xattrs);
> -	if (ret && ret != -EOPNOTSUPP)
> -		goto out;
>  	ret = initxattrs(inode, new_xattrs, fs_data);
>  out:
>  	for (xattr = new_xattrs; xattr->value != NULL; xattr++)
> @@ -2201,14 +2198,9 @@ int security_inode_permission(struct inode *inode, int mask)
>  int security_inode_setattr(struct mnt_idmap *idmap,
>  			   struct dentry *dentry, struct iattr *attr)
>  {
> -	int ret;
> -
>  	if (unlikely(IS_PRIVATE(d_backing_inode(dentry))))
>  		return 0;
> -	ret = call_int_hook(inode_setattr, 0, idmap, dentry, attr);
> -	if (ret)
> -		return ret;
> -	return evm_inode_setattr(idmap, dentry, attr);
> +	return call_int_hook(inode_setattr, 0, idmap, dentry, attr);
>  }
>  EXPORT_SYMBOL_GPL(security_inode_setattr);
>  
> @@ -2272,9 +2264,7 @@ int security_inode_setxattr(struct mnt_idmap *idmap,
>  
>  	if (ret == 1)
>  		ret = cap_inode_setxattr(dentry, name, value, size, flags);
> -	if (ret)
> -		return ret;
> -	return evm_inode_setxattr(idmap, dentry, name, value, size, flags);
> +	return ret;
>  }
>  
>  /**
> @@ -2293,15 +2283,10 @@ int security_inode_set_acl(struct mnt_idmap *idmap,
>  			   struct dentry *dentry, const char *acl_name,
>  			   struct posix_acl *kacl)
>  {
> -	int ret;
> -
>  	if (unlikely(IS_PRIVATE(d_backing_inode(dentry))))
>  		return 0;
> -	ret = call_int_hook(inode_set_acl, 0, idmap, dentry, acl_name,
> -			    kacl);
> -	if (ret)
> -		return ret;
> -	return evm_inode_set_acl(idmap, dentry, acl_name, kacl);
> +	return call_int_hook(inode_set_acl, 0, idmap, dentry, acl_name,
> +			     kacl);
>  }
>  
>  /**
> @@ -2354,14 +2339,9 @@ int security_inode_get_acl(struct mnt_idmap *idmap,
>  int security_inode_remove_acl(struct mnt_idmap *idmap,
>  			      struct dentry *dentry, const char *acl_name)
>  {
> -	int ret;
> -
>  	if (unlikely(IS_PRIVATE(d_backing_inode(dentry))))
>  		return 0;
> -	ret = call_int_hook(inode_remove_acl, 0, idmap, dentry, acl_name);
> -	if (ret)
> -		return ret;
> -	return evm_inode_remove_acl(idmap, dentry, acl_name);
> +	return call_int_hook(inode_remove_acl, 0, idmap, dentry, acl_name);
>  }
>  
>  /**
> @@ -2397,7 +2377,6 @@ void security_inode_post_setxattr(struct dentry *dentry, const char *name,
>  	if (unlikely(IS_PRIVATE(d_backing_inode(dentry))))
>  		return;
>  	call_void_hook(inode_post_setxattr, dentry, name, value, size, flags);
> -	evm_inode_post_setxattr(dentry, name, value, size, flags);
>  }
>  
>  /**
> @@ -2458,9 +2437,7 @@ int security_inode_removexattr(struct mnt_idmap *idmap,
>  	ret = call_int_hook(inode_removexattr, 1, idmap, dentry, name);
>  	if (ret == 1)
>  		ret = cap_inode_removexattr(idmap, dentry, name);
> -	if (ret)
> -		return ret;
> -	return evm_inode_removexattr(idmap, dentry, name);
> +	return ret;
>  }
>  
>  /**

^ permalink raw reply	[flat|nested] 79+ messages in thread

* Re: [PATCH 13/28] security: Align inode_setattr hook definition with EVM
  2023-03-03 18:18 ` [PATCH 13/28] security: Align inode_setattr hook definition with EVM Roberto Sassu
@ 2023-03-05  0:42   ` Casey Schaufler
  2023-03-06 17:06   ` Stefan Berger
  1 sibling, 0 replies; 79+ messages in thread
From: Casey Schaufler @ 2023-03-05  0:42 UTC (permalink / raw)
  To: Roberto Sassu, viro, chuck.lever, jlayton, zohar,
	dmitry.kasatkin, paul, jmorris, serge, dhowells, jarkko,
	stephen.smalley.work, eparis, brauner
  Cc: linux-fsdevel, linux-nfs, linux-integrity, linux-security-module,
	keyrings, selinux, linux-kernel, stefanb, Roberto Sassu, casey

On 3/3/2023 10:18 AM, Roberto Sassu wrote:
> From: Roberto Sassu <roberto.sassu@huawei.com>
>
> Add the idmap parameter to the definition, so that evm_inode_setattr() can
> be registered as this hook implementation.
>
> Signed-off-by: Roberto Sassu <roberto.sassu@huawei.com>

For the Smack bits:

Acked-by: Casey Schaufler <casey@schaufler-ca.com>

> ---
>  include/linux/lsm_hook_defs.h | 3 ++-
>  security/security.c           | 2 +-
>  security/selinux/hooks.c      | 3 ++-
>  security/smack/smack_lsm.c    | 4 +++-
>  4 files changed, 8 insertions(+), 4 deletions(-)
>
> diff --git a/include/linux/lsm_hook_defs.h b/include/linux/lsm_hook_defs.h
> index 2e10945622a..4372a6b2632 100644
> --- a/include/linux/lsm_hook_defs.h
> +++ b/include/linux/lsm_hook_defs.h
> @@ -133,7 +133,8 @@ LSM_HOOK(int, 0, inode_readlink, struct dentry *dentry)
>  LSM_HOOK(int, 0, inode_follow_link, struct dentry *dentry, struct inode *inode,
>  	 bool rcu)
>  LSM_HOOK(int, 0, inode_permission, struct inode *inode, int mask)
> -LSM_HOOK(int, 0, inode_setattr, struct dentry *dentry, struct iattr *attr)
> +LSM_HOOK(int, 0, inode_setattr, struct mnt_idmap *idmap, struct dentry *dentry,
> +	 struct iattr *attr)
>  LSM_HOOK(int, 0, inode_getattr, const struct path *path)
>  LSM_HOOK(int, 0, inode_setxattr, struct mnt_idmap *idmap,
>  	 struct dentry *dentry, const char *name, const void *value,
> diff --git a/security/security.c b/security/security.c
> index df6714aa19d..f7fe252e9d3 100644
> --- a/security/security.c
> +++ b/security/security.c
> @@ -2168,7 +2168,7 @@ int security_inode_setattr(struct mnt_idmap *idmap,
>  
>  	if (unlikely(IS_PRIVATE(d_backing_inode(dentry))))
>  		return 0;
> -	ret = call_int_hook(inode_setattr, 0, dentry, attr);
> +	ret = call_int_hook(inode_setattr, 0, idmap, dentry, attr);
>  	if (ret)
>  		return ret;
>  	return evm_inode_setattr(idmap, dentry, attr);
> diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
> index 3e4308dd336..b31ad6109b0 100644
> --- a/security/selinux/hooks.c
> +++ b/security/selinux/hooks.c
> @@ -3104,7 +3104,8 @@ static int selinux_inode_permission(struct inode *inode, int mask)
>  	return rc;
>  }
>  
> -static int selinux_inode_setattr(struct dentry *dentry, struct iattr *iattr)
> +static int selinux_inode_setattr(struct mnt_idmap *idmap, struct dentry *dentry,
> +				 struct iattr *iattr)
>  {
>  	const struct cred *cred = current_cred();
>  	struct inode *inode = d_backing_inode(dentry);
> diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c
> index 598b398c62e..09cfd3c31dc 100644
> --- a/security/smack/smack_lsm.c
> +++ b/security/smack/smack_lsm.c
> @@ -1173,12 +1173,14 @@ static int smack_inode_permission(struct inode *inode, int mask)
>  
>  /**
>   * smack_inode_setattr - Smack check for setting attributes
> + * @idmap: idmap of the mount
>   * @dentry: the object
>   * @iattr: for the force flag
>   *
>   * Returns 0 if access is permitted, an error code otherwise
>   */
> -static int smack_inode_setattr(struct dentry *dentry, struct iattr *iattr)
> +static int smack_inode_setattr(struct mnt_idmap *idmap, struct dentry *dentry,
> +			       struct iattr *iattr)
>  {
>  	struct smk_audit_info ad;
>  	int rc;

^ permalink raw reply	[flat|nested] 79+ messages in thread

* Re: [PATCH 26/28] evm: Move to LSM infrastructure
  2023-03-04 21:36   ` Casey Schaufler
@ 2023-03-06  9:21     ` Roberto Sassu
  2023-03-07 16:54       ` Casey Schaufler
  0 siblings, 1 reply; 79+ messages in thread
From: Roberto Sassu @ 2023-03-06  9:21 UTC (permalink / raw)
  To: Casey Schaufler, viro, chuck.lever, jlayton, zohar,
	dmitry.kasatkin, paul, jmorris, serge, dhowells, jarkko,
	stephen.smalley.work, eparis, brauner
  Cc: linux-fsdevel, linux-nfs, linux-integrity, linux-security-module,
	keyrings, selinux, linux-kernel, stefanb, Roberto Sassu

On Sat, 2023-03-04 at 13:36 -0800, Casey Schaufler wrote:
> On 3/3/2023 10:26 AM, Roberto Sassu wrote:
> > From: Roberto Sassu <roberto.sassu@huawei.com>
> > 
> > As for IMA, remove hardcoded EVM function calls from the LSM infrastructure
> > and the VFS. Make EVM functions as static (except for
> > evm_inode_init_security(), which is exported), and register them as hook
> > implementations in init_evm_lsm(), called from integrity_lsm_init().
> > 
> > Finally, switch to the LSM reservation mechanism for the EVM xattr, by
> > setting the lbs_xattr field of the lsm_blob_sizes structure, and
> > consequently decrement the number of xattrs to allocate in
> > security_inode_init_security().
> > 
> > Signed-off-by: Roberto Sassu <roberto.sassu@huawei.com>
> > ---
> >  fs/attr.c                         |   2 -
> >  fs/posix_acl.c                    |   3 -
> >  fs/xattr.c                        |   2 -
> >  include/linux/evm.h               | 116 ------------------------------
> >  security/integrity/evm/evm_main.c | 106 ++++++++++++++++++++++-----
> >  security/integrity/iint.c         |   7 ++
> >  security/integrity/integrity.h    |   9 +++
> >  security/security.c               |  41 +++--------
> >  8 files changed, 115 insertions(+), 171 deletions(-)
> > 
> > diff --git a/fs/attr.c b/fs/attr.c
> > index 406d782dfab..1b911a627fe 100644
> > --- a/fs/attr.c
> > +++ b/fs/attr.c
> > @@ -16,7 +16,6 @@
> >  #include <linux/fcntl.h>
> >  #include <linux/filelock.h>
> >  #include <linux/security.h>
> > -#include <linux/evm.h>
> >  
> >  #include "internal.h"
> >  
> > @@ -485,7 +484,6 @@ int notify_change(struct mnt_idmap *idmap, struct dentry *dentry,
> >  	if (!error) {
> >  		fsnotify_change(dentry, ia_valid);
> >  		security_inode_post_setattr(idmap, dentry, ia_valid);
> > -		evm_inode_post_setattr(idmap, dentry, ia_valid);
> >  	}
> >  
> >  	return error;
> > diff --git a/fs/posix_acl.c b/fs/posix_acl.c
> > index 5b8c92fce0c..608cb0a9f84 100644
> > --- a/fs/posix_acl.c
> > +++ b/fs/posix_acl.c
> > @@ -26,7 +26,6 @@
> >  #include <linux/mnt_idmapping.h>
> >  #include <linux/iversion.h>
> >  #include <linux/security.h>
> > -#include <linux/evm.h>
> >  #include <linux/fsnotify.h>
> >  #include <linux/filelock.h>
> >  
> > @@ -1103,7 +1102,6 @@ int vfs_set_acl(struct mnt_idmap *idmap, struct dentry *dentry,
> >  	if (!error) {
> >  		fsnotify_xattr(dentry);
> >  		security_inode_post_set_acl(dentry, acl_name, kacl);
> > -		evm_inode_post_set_acl(dentry, acl_name, kacl);
> >  	}
> >  
> >  out_inode_unlock:
> > @@ -1214,7 +1212,6 @@ int vfs_remove_acl(struct mnt_idmap *idmap, struct dentry *dentry,
> >  	if (!error) {
> >  		fsnotify_xattr(dentry);
> >  		security_inode_post_remove_acl(idmap, dentry, acl_name);
> > -		evm_inode_post_remove_acl(idmap, dentry, acl_name);
> >  	}
> >  
> >  out_inode_unlock:
> > diff --git a/fs/xattr.c b/fs/xattr.c
> > index 10c959d9fc6..7708ffdacca 100644
> > --- a/fs/xattr.c
> > +++ b/fs/xattr.c
> > @@ -16,7 +16,6 @@
> >  #include <linux/mount.h>
> >  #include <linux/namei.h>
> >  #include <linux/security.h>
> > -#include <linux/evm.h>
> >  #include <linux/syscalls.h>
> >  #include <linux/export.h>
> >  #include <linux/fsnotify.h>
> > @@ -535,7 +534,6 @@ __vfs_removexattr_locked(struct mnt_idmap *idmap,
> >  	if (!error) {
> >  		fsnotify_xattr(dentry);
> >  		security_inode_post_removexattr(dentry, name);
> > -		evm_inode_post_removexattr(dentry, name);
> >  	}
> >  
> >  out:
> > diff --git a/include/linux/evm.h b/include/linux/evm.h
> > index 8c043273552..61794299f09 100644
> > --- a/include/linux/evm.h
> > +++ b/include/linux/evm.h
> > @@ -21,46 +21,6 @@ extern enum integrity_status evm_verifyxattr(struct dentry *dentry,
> >  					     void *xattr_value,
> >  					     size_t xattr_value_len,
> >  					     struct integrity_iint_cache *iint);
> > -extern int evm_inode_setattr(struct mnt_idmap *idmap,
> > -			     struct dentry *dentry, struct iattr *attr);
> > -extern void evm_inode_post_setattr(struct mnt_idmap *idmap,
> > -				   struct dentry *dentry, int ia_valid);
> > -extern int evm_inode_setxattr(struct mnt_idmap *idmap,
> > -			      struct dentry *dentry, const char *name,
> > -			      const void *value, size_t size, int flags);
> > -extern void evm_inode_post_setxattr(struct dentry *dentry,
> > -				    const char *xattr_name,
> > -				    const void *xattr_value,
> > -				    size_t xattr_value_len,
> > -				    int flags);
> > -extern int evm_inode_removexattr(struct mnt_idmap *idmap,
> > -				 struct dentry *dentry, const char *xattr_name);
> > -extern void evm_inode_post_removexattr(struct dentry *dentry,
> > -				       const char *xattr_name);
> > -static inline void evm_inode_post_remove_acl(struct mnt_idmap *idmap,
> > -					     struct dentry *dentry,
> > -					     const char *acl_name)
> > -{
> > -	evm_inode_post_removexattr(dentry, acl_name);
> > -}
> > -extern int evm_inode_set_acl(struct mnt_idmap *idmap,
> > -			     struct dentry *dentry, const char *acl_name,
> > -			     struct posix_acl *kacl);
> > -static inline int evm_inode_remove_acl(struct mnt_idmap *idmap,
> > -				       struct dentry *dentry,
> > -				       const char *acl_name)
> > -{
> > -	return evm_inode_set_acl(idmap, dentry, acl_name, NULL);
> > -}
> > -static inline void evm_inode_post_set_acl(struct dentry *dentry,
> > -					  const char *acl_name,
> > -					  struct posix_acl *kacl)
> > -{
> > -	return evm_inode_post_setxattr(dentry, acl_name, NULL, 0, 0);
> > -}
> > -extern int evm_inode_init_security(struct inode *inode, struct inode *dir,
> > -				   const struct qstr *qstr,
> > -				   struct xattr *xattrs);
> >  extern bool evm_revalidate_status(const char *xattr_name);
> >  extern int evm_protected_xattr_if_enabled(const char *req_xattr_name);
> >  extern int evm_read_protected_xattrs(struct dentry *dentry, u8 *buffer,
> > @@ -92,82 +52,6 @@ static inline enum integrity_status evm_verifyxattr(struct dentry *dentry,
> >  }
> >  #endif
> >  
> > -static inline int evm_inode_setattr(struct mnt_idmap *idmap,
> > -				    struct dentry *dentry, struct iattr *attr)
> > -{
> > -	return 0;
> > -}
> > -
> > -static inline void evm_inode_post_setattr(struct mnt_idmap *idmap,
> > -					  struct dentry *dentry, int ia_valid)
> > -{
> > -	return;
> > -}
> > -
> > -static inline int evm_inode_setxattr(struct mnt_idmap *idmap,
> > -				     struct dentry *dentry, const char *name,
> > -				     const void *value, size_t size, int flags)
> > -{
> > -	return 0;
> > -}
> > -
> > -static inline void evm_inode_post_setxattr(struct dentry *dentry,
> > -					   const char *xattr_name,
> > -					   const void *xattr_value,
> > -					   size_t xattr_value_len,
> > -					   int flags)
> > -{
> > -	return;
> > -}
> > -
> > -static inline int evm_inode_removexattr(struct mnt_idmap *idmap,
> > -					struct dentry *dentry,
> > -					const char *xattr_name)
> > -{
> > -	return 0;
> > -}
> > -
> > -static inline void evm_inode_post_removexattr(struct dentry *dentry,
> > -					      const char *xattr_name)
> > -{
> > -	return;
> > -}
> > -
> > -static inline void evm_inode_post_remove_acl(struct mnt_idmap *idmap,
> > -					     struct dentry *dentry,
> > -					     const char *acl_name)
> > -{
> > -	return;
> > -}
> > -
> > -static inline int evm_inode_set_acl(struct mnt_idmap *idmap,
> > -				    struct dentry *dentry, const char *acl_name,
> > -				    struct posix_acl *kacl)
> > -{
> > -	return 0;
> > -}
> > -
> > -static inline int evm_inode_remove_acl(struct mnt_idmap *idmap,
> > -				       struct dentry *dentry,
> > -				       const char *acl_name)
> > -{
> > -	return 0;
> > -}
> > -
> > -static inline void evm_inode_post_set_acl(struct dentry *dentry,
> > -					  const char *acl_name,
> > -					  struct posix_acl *kacl)
> > -{
> > -	return;
> > -}
> > -
> > -static inline int evm_inode_init_security(struct inode *inode, struct inode *dir,
> > -					  const struct qstr *qstr,
> > -					  struct xattr *xattrs)
> > -{
> > -	return 0;
> > -}
> > -
> >  static inline bool evm_revalidate_status(const char *xattr_name)
> >  {
> >  	return false;
> > diff --git a/security/integrity/evm/evm_main.c b/security/integrity/evm/evm_main.c
> > index 8b5c472f78b..c45bc97277c 100644
> > --- a/security/integrity/evm/evm_main.c
> > +++ b/security/integrity/evm/evm_main.c
> > @@ -19,6 +19,7 @@
> >  #include <linux/xattr.h>
> >  #include <linux/integrity.h>
> >  #include <linux/evm.h>
> > +#include <linux/lsm_hooks.h>
> >  #include <linux/magic.h>
> >  #include <linux/posix_acl_xattr.h>
> >  
> > @@ -566,9 +567,9 @@ static int evm_protect_xattr(struct mnt_idmap *idmap,
> >   * userspace from writing HMAC value.  Writing 'security.evm' requires
> >   * requires CAP_SYS_ADMIN privileges.
> >   */
> > -int evm_inode_setxattr(struct mnt_idmap *idmap, struct dentry *dentry,
> > -		       const char *xattr_name, const void *xattr_value,
> > -		       size_t xattr_value_len, int flags)
> > +static int evm_inode_setxattr(struct mnt_idmap *idmap, struct dentry *dentry,
> > +			      const char *xattr_name, const void *xattr_value,
> > +			      size_t xattr_value_len, int flags)
> >  {
> >  	const struct evm_ima_xattr_data *xattr_data = xattr_value;
> >  
> > @@ -598,8 +599,8 @@ int evm_inode_setxattr(struct mnt_idmap *idmap, struct dentry *dentry,
> >   * Removing 'security.evm' requires CAP_SYS_ADMIN privileges and that
> >   * the current value is valid.
> >   */
> > -int evm_inode_removexattr(struct mnt_idmap *idmap,
> > -			  struct dentry *dentry, const char *xattr_name)
> > +static int evm_inode_removexattr(struct mnt_idmap *idmap, struct dentry *dentry,
> > +				 const char *xattr_name)
> >  {
> >  	/* Policy permits modification of the protected xattrs even though
> >  	 * there's no HMAC key loaded
> > @@ -649,9 +650,11 @@ static inline int evm_inode_set_acl_change(struct mnt_idmap *idmap,
> >   * Prevent modifying posix acls causing the EVM HMAC to be re-calculated
> >   * and 'security.evm' xattr updated, unless the existing 'security.evm' is
> >   * valid.
> > + *
> > + * Return: zero on success, -EPERM on failure.
> >   */
> > -int evm_inode_set_acl(struct mnt_idmap *idmap, struct dentry *dentry,
> > -		      const char *acl_name, struct posix_acl *kacl)
> > +static int evm_inode_set_acl(struct mnt_idmap *idmap, struct dentry *dentry,
> > +			     const char *acl_name, struct posix_acl *kacl)
> >  {
> >  	enum integrity_status evm_status;
> >  
> > @@ -690,6 +693,24 @@ int evm_inode_set_acl(struct mnt_idmap *idmap, struct dentry *dentry,
> >  	return -EPERM;
> >  }
> >  
> > +/**
> > + * evm_inode_remove_acl - Protect the EVM extended attribute from posix acls
> > + * @idmap: idmap of the mount
> > + * @dentry: pointer to the affected dentry
> > + * @acl_name: name of the posix acl
> > + *
> > + * Prevent removing posix acls causing the EVM HMAC to be re-calculated
> > + * and 'security.evm' xattr updated, unless the existing 'security.evm' is
> > + * valid.
> > + *
> > + * Return: zero on success, -EPERM on failure.
> > + */
> > +static int evm_inode_remove_acl(struct mnt_idmap *idmap, struct dentry *dentry,
> > +				const char *acl_name)
> > +{
> > +	return evm_inode_set_acl(idmap, dentry, acl_name, NULL);
> > +}
> > +
> >  static void evm_reset_status(struct inode *inode)
> >  {
> >  	struct integrity_iint_cache *iint;
> > @@ -738,9 +759,11 @@ bool evm_revalidate_status(const char *xattr_name)
> >   * __vfs_setxattr_noperm().  The caller of which has taken the inode's
> >   * i_mutex lock.
> >   */
> > -void evm_inode_post_setxattr(struct dentry *dentry, const char *xattr_name,
> > -			     const void *xattr_value, size_t xattr_value_len,
> > -			     int flags)
> > +static void evm_inode_post_setxattr(struct dentry *dentry,
> > +				    const char *xattr_name,
> > +				    const void *xattr_value,
> > +				    size_t xattr_value_len,
> > +				    int flags)
> >  {
> >  	if (!evm_revalidate_status(xattr_name))
> >  		return;
> > @@ -756,6 +779,21 @@ void evm_inode_post_setxattr(struct dentry *dentry, const char *xattr_name,
> >  	evm_update_evmxattr(dentry, xattr_name, xattr_value, xattr_value_len);
> >  }
> >  
> > +/**
> > + * evm_inode_post_set_acl - Update the EVM extended attribute from posix acls
> > + * @dentry: pointer to the affected dentry
> > + * @acl_name: name of the posix acl
> > + * @kacl: pointer to the posix acls
> > + *
> > + * Update the 'security.evm' xattr with the EVM HMAC re-calculated after setting
> > + * posix acls.
> > + */
> > +static void evm_inode_post_set_acl(struct dentry *dentry, const char *acl_name,
> > +				   struct posix_acl *kacl)
> > +{
> > +	return evm_inode_post_setxattr(dentry, acl_name, NULL, 0, 0);
> > +}
> > +
> >  /**
> >   * evm_inode_post_removexattr - update 'security.evm' after removing the xattr
> >   * @dentry: pointer to the affected dentry
> > @@ -766,7 +804,8 @@ void evm_inode_post_setxattr(struct dentry *dentry, const char *xattr_name,
> >   * No need to take the i_mutex lock here, as this function is called from
> >   * vfs_removexattr() which takes the i_mutex.
> >   */
> > -void evm_inode_post_removexattr(struct dentry *dentry, const char *xattr_name)
> > +static void evm_inode_post_removexattr(struct dentry *dentry,
> > +				       const char *xattr_name)
> >  {
> >  	if (!evm_revalidate_status(xattr_name))
> >  		return;
> > @@ -782,6 +821,22 @@ void evm_inode_post_removexattr(struct dentry *dentry, const char *xattr_name)
> >  	evm_update_evmxattr(dentry, xattr_name, NULL, 0);
> >  }
> >  
> > +/**
> > + * evm_inode_post_remove_acl - Update the EVM extended attribute from posix acls
> > + * @idmap: idmap of the mount
> > + * @dentry: pointer to the affected dentry
> > + * @acl_name: name of the posix acl
> > + *
> > + * Update the 'security.evm' xattr with the EVM HMAC re-calculated after
> > + * removing posix acls.
> > + */
> > +static inline void evm_inode_post_remove_acl(struct mnt_idmap *idmap,
> > +					     struct dentry *dentry,
> > +					     const char *acl_name)
> > +{
> > +	evm_inode_post_removexattr(dentry, acl_name);
> > +}
> > +
> >  static int evm_attr_change(struct mnt_idmap *idmap,
> >  			   struct dentry *dentry, struct iattr *attr)
> >  {
> > @@ -805,8 +860,8 @@ static int evm_attr_change(struct mnt_idmap *idmap,
> >   * Permit update of file attributes when files have a valid EVM signature,
> >   * except in the case of them having an immutable portable signature.
> >   */
> > -int evm_inode_setattr(struct mnt_idmap *idmap, struct dentry *dentry,
> > -		      struct iattr *attr)
> > +static int evm_inode_setattr(struct mnt_idmap *idmap, struct dentry *dentry,
> > +			     struct iattr *attr)
> >  {
> >  	unsigned int ia_valid = attr->ia_valid;
> >  	enum integrity_status evm_status;
> > @@ -853,8 +908,8 @@ int evm_inode_setattr(struct mnt_idmap *idmap, struct dentry *dentry,
> >   * This function is called from notify_change(), which expects the caller
> >   * to lock the inode's i_mutex.
> >   */
> > -void evm_inode_post_setattr(struct mnt_idmap *idmap, struct dentry *dentry,
> > -			    int ia_valid)
> > +static void evm_inode_post_setattr(struct mnt_idmap *idmap,
> > +				   struct dentry *dentry, int ia_valid)
> >  {
> >  	if (!evm_revalidate_status(NULL))
> >  		return;
> > @@ -892,7 +947,7 @@ int evm_inode_init_security(struct inode *inode, struct inode *dir,
> >  	if (!evm_protected_xattrs)
> >  		return -EOPNOTSUPP;
> >  
> > -	evm_xattr = xattr;
> > +	evm_xattr = xattrs + integrity_blob_sizes.lbs_xattr;
> 
> Please don't do this inline. Convention is to use a function,
> intergrity_xattrs() for this.

Ok.

> >  
> >  	xattr_data = kzalloc(sizeof(*xattr_data), GFP_NOFS);
> >  	if (!xattr_data)
> > @@ -952,4 +1007,23 @@ static int __init init_evm(void)
> >  	return error;
> >  }
> >  
> > +static struct security_hook_list evm_hooks[] __lsm_ro_after_init = {
> > +	LSM_HOOK_INIT(inode_setattr, evm_inode_setattr),
> > +	LSM_HOOK_INIT(inode_post_setattr, evm_inode_post_setattr),
> > +	LSM_HOOK_INIT(inode_setxattr, evm_inode_setxattr),
> > +	LSM_HOOK_INIT(inode_set_acl, evm_inode_set_acl),
> > +	LSM_HOOK_INIT(inode_post_set_acl, evm_inode_post_set_acl),
> > +	LSM_HOOK_INIT(inode_remove_acl, evm_inode_remove_acl),
> > +	LSM_HOOK_INIT(inode_post_remove_acl, evm_inode_post_remove_acl),
> > +	LSM_HOOK_INIT(inode_post_setxattr, evm_inode_post_setxattr),
> > +	LSM_HOOK_INIT(inode_removexattr, evm_inode_removexattr),
> > +	LSM_HOOK_INIT(inode_post_removexattr, evm_inode_post_removexattr),
> > +	LSM_HOOK_INIT(inode_init_security, evm_inode_init_security),
> > +};
> > +
> > +void __init init_evm_lsm(void)
> > +{
> > +	security_add_hooks(evm_hooks, ARRAY_SIZE(evm_hooks), "integrity");
> > +}
> > +
> >  late_initcall(init_evm);
> > diff --git a/security/integrity/iint.c b/security/integrity/iint.c
> > index bbadf974b31..952d5ea4e18 100644
> > --- a/security/integrity/iint.c
> > +++ b/security/integrity/iint.c
> > @@ -179,12 +179,19 @@ static int __init integrity_lsm_init(void)
> >  			      0, SLAB_PANIC, init_once);
> >  
> >  	init_ima_lsm();
> > +	init_evm_lsm();
> >  	return 0;
> >  }
> > +
> > +struct lsm_blob_sizes integrity_blob_sizes __lsm_ro_after_init = {
> > +	.lbs_xattr = 1,
> 
> Really? 1 byte? Don't even think of storing number of elements in lbs_xattr.
> The linux_blob_size structure contains sizes of blobs, not number of elements.

Oh, I see it can be confusing.

However, lbs_xattr does not help to position in the security blob but
in the new_xattrs array, allocated in security_inode_init_security()
(see below). Any suggestion on how to make this part better?

Thanks

Roberto

> > +};
> > +
> >  DEFINE_LSM(integrity) = {
> >  	.name = "integrity",
> >  	.init = integrity_lsm_init,
> >  	.order = LSM_ORDER_LAST,
> > +	.blobs = &integrity_blob_sizes,
> >  };
> >  
> >  /*
> > diff --git a/security/integrity/integrity.h b/security/integrity/integrity.h
> > index c72d375a356..76e7eda6651 100644
> > --- a/security/integrity/integrity.h
> > +++ b/security/integrity/integrity.h
> > @@ -188,6 +188,7 @@ int integrity_kernel_read(struct file *file, loff_t offset,
> >  #define INTEGRITY_KEYRING_MAX		4
> >  
> >  extern struct dentry *integrity_dir;
> > +extern struct lsm_blob_sizes integrity_blob_sizes;
> >  
> >  struct modsig;
> >  
> > @@ -199,6 +200,14 @@ static inline void __init init_ima_lsm(void)
> >  }
> >  #endif
> >  
> > +#ifdef CONFIG_EVM
> > +void __init init_evm_lsm(void);
> > +#else
> > +static inline void __init init_evm_lsm(void)
> > +{
> > +}
> > +#endif
> > +
> >  #ifdef CONFIG_INTEGRITY_SIGNATURE
> >  
> >  int integrity_digsig_verify(const unsigned int id, const char *sig, int siglen,
> > diff --git a/security/security.c b/security/security.c
> > index 9bc6a4ef758..74abf04feef 100644
> > --- a/security/security.c
> > +++ b/security/security.c
> > @@ -20,13 +20,13 @@
> >  #include <linux/kernel_read_file.h>
> >  #include <linux/lsm_hooks.h>
> >  #include <linux/integrity.h>
> > -#include <linux/evm.h>
> >  #include <linux/fsnotify.h>
> >  #include <linux/mman.h>
> >  #include <linux/mount.h>
> >  #include <linux/personality.h>
> >  #include <linux/backing-dev.h>
> >  #include <linux/string.h>
> > +#include <linux/xattr.h>
> >  #include <linux/msg.h>
> >  #include <net/flow.h>
> >  
> > @@ -1662,8 +1662,8 @@ int security_inode_init_security(struct inode *inode, struct inode *dir,
> >  	if (!initxattrs)
> >  		return call_int_hook(inode_init_security, -EOPNOTSUPP, inode,
> >  				    dir, qstr, NULL);
> > -	/* Allocate +1 for EVM and +1 as terminator. */
> > -	new_xattrs = kcalloc(blob_sizes.lbs_xattr + 2, sizeof(*new_xattrs),
> > +	/* Allocate +1 for terminator. */
> > +	new_xattrs = kcalloc(blob_sizes.lbs_xattr + 1, sizeof(*new_xattrs),
> >  			     GFP_NOFS);
> >  	if (!new_xattrs)
> >  		return -ENOMEM;
> > @@ -1699,9 +1699,6 @@ int security_inode_init_security(struct inode *inode, struct inode *dir,
> >  	if (!num_filled_xattrs)
> >  		goto out;
> >  
> > -	ret = evm_inode_init_security(inode, dir, qstr, new_xattrs);
> > -	if (ret && ret != -EOPNOTSUPP)
> > -		goto out;
> >  	ret = initxattrs(inode, new_xattrs, fs_data);
> >  out:
> >  	for (xattr = new_xattrs; xattr->value != NULL; xattr++)
> > @@ -2201,14 +2198,9 @@ int security_inode_permission(struct inode *inode, int mask)
> >  int security_inode_setattr(struct mnt_idmap *idmap,
> >  			   struct dentry *dentry, struct iattr *attr)
> >  {
> > -	int ret;
> > -
> >  	if (unlikely(IS_PRIVATE(d_backing_inode(dentry))))
> >  		return 0;
> > -	ret = call_int_hook(inode_setattr, 0, idmap, dentry, attr);
> > -	if (ret)
> > -		return ret;
> > -	return evm_inode_setattr(idmap, dentry, attr);
> > +	return call_int_hook(inode_setattr, 0, idmap, dentry, attr);
> >  }
> >  EXPORT_SYMBOL_GPL(security_inode_setattr);
> >  
> > @@ -2272,9 +2264,7 @@ int security_inode_setxattr(struct mnt_idmap *idmap,
> >  
> >  	if (ret == 1)
> >  		ret = cap_inode_setxattr(dentry, name, value, size, flags);
> > -	if (ret)
> > -		return ret;
> > -	return evm_inode_setxattr(idmap, dentry, name, value, size, flags);
> > +	return ret;
> >  }
> >  
> >  /**
> > @@ -2293,15 +2283,10 @@ int security_inode_set_acl(struct mnt_idmap *idmap,
> >  			   struct dentry *dentry, const char *acl_name,
> >  			   struct posix_acl *kacl)
> >  {
> > -	int ret;
> > -
> >  	if (unlikely(IS_PRIVATE(d_backing_inode(dentry))))
> >  		return 0;
> > -	ret = call_int_hook(inode_set_acl, 0, idmap, dentry, acl_name,
> > -			    kacl);
> > -	if (ret)
> > -		return ret;
> > -	return evm_inode_set_acl(idmap, dentry, acl_name, kacl);
> > +	return call_int_hook(inode_set_acl, 0, idmap, dentry, acl_name,
> > +			     kacl);
> >  }
> >  
> >  /**
> > @@ -2354,14 +2339,9 @@ int security_inode_get_acl(struct mnt_idmap *idmap,
> >  int security_inode_remove_acl(struct mnt_idmap *idmap,
> >  			      struct dentry *dentry, const char *acl_name)
> >  {
> > -	int ret;
> > -
> >  	if (unlikely(IS_PRIVATE(d_backing_inode(dentry))))
> >  		return 0;
> > -	ret = call_int_hook(inode_remove_acl, 0, idmap, dentry, acl_name);
> > -	if (ret)
> > -		return ret;
> > -	return evm_inode_remove_acl(idmap, dentry, acl_name);
> > +	return call_int_hook(inode_remove_acl, 0, idmap, dentry, acl_name);
> >  }
> >  
> >  /**
> > @@ -2397,7 +2377,6 @@ void security_inode_post_setxattr(struct dentry *dentry, const char *name,
> >  	if (unlikely(IS_PRIVATE(d_backing_inode(dentry))))
> >  		return;
> >  	call_void_hook(inode_post_setxattr, dentry, name, value, size, flags);
> > -	evm_inode_post_setxattr(dentry, name, value, size, flags);
> >  }
> >  
> >  /**
> > @@ -2458,9 +2437,7 @@ int security_inode_removexattr(struct mnt_idmap *idmap,
> >  	ret = call_int_hook(inode_removexattr, 1, idmap, dentry, name);
> >  	if (ret == 1)
> >  		ret = cap_inode_removexattr(idmap, dentry, name);
> > -	if (ret)
> > -		return ret;
> > -	return evm_inode_removexattr(idmap, dentry, name);
> > +	return ret;
> >  }
> >  
> >  /**


^ permalink raw reply	[flat|nested] 79+ messages in thread

* Re: [PATCH 12/28] fs: Fix description of vfs_tmpfile()
  2023-03-03 18:18 ` [PATCH 12/28] fs: Fix description of vfs_tmpfile() Roberto Sassu
@ 2023-03-06 10:28   ` Christian Brauner
  2023-03-06 10:31     ` Roberto Sassu
  0 siblings, 1 reply; 79+ messages in thread
From: Christian Brauner @ 2023-03-06 10:28 UTC (permalink / raw)
  To: Roberto Sassu
  Cc: viro, chuck.lever, jlayton, zohar, dmitry.kasatkin, paul,
	jmorris, serge, dhowells, jarkko, stephen.smalley.work, eparis,
	casey, linux-fsdevel, linux-nfs, linux-integrity,
	linux-security-module, keyrings, selinux, linux-kernel, stefanb,
	Roberto Sassu

On Fri, Mar 03, 2023 at 07:18:26PM +0100, Roberto Sassu wrote:
> From: Roberto Sassu <roberto.sassu@huawei.com>
> 
> Update the description of vfs_tmpfile() to match the current parameters of
> that function.
> 
> Fixes: 9751b338656f ("vfs: move open right after ->tmpfile()")
> Signed-off-by: Roberto Sassu <roberto.sassu@huawei.com>
> ---

Trivially correct. But this shouldn't need to be a part of this series
afaict. Please send a this separately to fsdevel so we can pick it up
right now,

Acked-by: Christian Brauner <brauner@kernel.org>

^ permalink raw reply	[flat|nested] 79+ messages in thread

* Re: [PATCH 12/28] fs: Fix description of vfs_tmpfile()
  2023-03-06 10:28   ` Christian Brauner
@ 2023-03-06 10:31     ` Roberto Sassu
  0 siblings, 0 replies; 79+ messages in thread
From: Roberto Sassu @ 2023-03-06 10:31 UTC (permalink / raw)
  To: Christian Brauner
  Cc: viro, chuck.lever, jlayton, zohar, dmitry.kasatkin, paul,
	jmorris, serge, dhowells, jarkko, stephen.smalley.work, eparis,
	casey, linux-fsdevel, linux-nfs, linux-integrity,
	linux-security-module, keyrings, selinux, linux-kernel, stefanb,
	Roberto Sassu

On Mon, 2023-03-06 at 11:28 +0100, Christian Brauner wrote:
> On Fri, Mar 03, 2023 at 07:18:26PM +0100, Roberto Sassu wrote:
> > From: Roberto Sassu <roberto.sassu@huawei.com>
> > 
> > Update the description of vfs_tmpfile() to match the current parameters of
> > that function.
> > 
> > Fixes: 9751b338656f ("vfs: move open right after ->tmpfile()")
> > Signed-off-by: Roberto Sassu <roberto.sassu@huawei.com>
> > ---
> 
> Trivially correct. But this shouldn't need to be a part of this series
> afaict. Please send a this separately to fsdevel so we can pick it up
> right now,
> 
> Acked-by: Christian Brauner <brauner@kernel.org>

Ok, thanks. I do the same for the EVM one.

Roberto


^ permalink raw reply	[flat|nested] 79+ messages in thread

* Re: [PATCH 21/28] security: Introduce inode_post_remove_acl hook
  2023-03-03 18:18 ` [PATCH 21/28] security: Introduce inode_post_remove_acl hook Roberto Sassu
@ 2023-03-06 15:22   ` Stefan Berger
  2023-03-06 15:34     ` Roberto Sassu
  0 siblings, 1 reply; 79+ messages in thread
From: Stefan Berger @ 2023-03-06 15:22 UTC (permalink / raw)
  To: Roberto Sassu, viro, chuck.lever, jlayton, zohar,
	dmitry.kasatkin, paul, jmorris, serge, dhowells, jarkko,
	stephen.smalley.work, eparis, casey, brauner
  Cc: linux-fsdevel, linux-nfs, linux-integrity, linux-security-module,
	keyrings, selinux, linux-kernel, Roberto Sassu



On 3/3/23 13:18, 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_remove_acl hook.
> 
> Signed-off-by: Roberto Sassu <roberto.sassu@huawei.com>
> ---

>   
> +/**
> + * security_inode_post_remove_acl() - Update inode sec after remove_acl op
> + * @idmap: idmap of the mount
> + * @dentry: file
> + * @acl_name: acl name
> + *
> + * Update inode security field after successful remove_acl operation on @dentry
> + * in @idmap. The posix acls are identified by @acl_name.
> + */
> +void security_inode_post_remove_acl(struct mnt_idmap *idmap,
> +				    struct dentry *dentry, const char *acl_name)
> +{
> +	if (unlikely(IS_PRIVATE(d_backing_inode(dentry))))
> +		return;

Was that a mistake before that EVM and IMA functions did not filtered out private inodes?

    Stefan


^ permalink raw reply	[flat|nested] 79+ messages in thread

* Re: [PATCH 21/28] security: Introduce inode_post_remove_acl hook
  2023-03-06 15:22   ` Stefan Berger
@ 2023-03-06 15:34     ` Roberto Sassu
  2023-03-06 16:16       ` Stefan Berger
  0 siblings, 1 reply; 79+ messages in thread
From: Roberto Sassu @ 2023-03-06 15:34 UTC (permalink / raw)
  To: Stefan Berger, viro, chuck.lever, jlayton, zohar,
	dmitry.kasatkin, paul, jmorris, serge, dhowells, jarkko,
	stephen.smalley.work, eparis, casey, brauner
  Cc: linux-fsdevel, linux-nfs, linux-integrity, linux-security-module,
	keyrings, selinux, linux-kernel, Roberto Sassu

On Mon, 2023-03-06 at 10:22 -0500, Stefan Berger wrote:
> 
> On 3/3/23 13:18, 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_remove_acl hook.
> > 
> > Signed-off-by: Roberto Sassu <roberto.sassu@huawei.com>
> > ---
> >   
> > +/**
> > + * security_inode_post_remove_acl() - Update inode sec after remove_acl op
> > + * @idmap: idmap of the mount
> > + * @dentry: file
> > + * @acl_name: acl name
> > + *
> > + * Update inode security field after successful remove_acl operation on @dentry
> > + * in @idmap. The posix acls are identified by @acl_name.
> > + */
> > +void security_inode_post_remove_acl(struct mnt_idmap *idmap,
> > +				    struct dentry *dentry, const char *acl_name)
> > +{
> > +	if (unlikely(IS_PRIVATE(d_backing_inode(dentry))))
> > +		return;
> 
> Was that a mistake before that EVM and IMA functions did not filtered out private inodes?

Looks like that. At least for hooks that are not called from
security.c.

Thanks

Roberto


^ permalink raw reply	[flat|nested] 79+ messages in thread

* Re: [PATCH 21/28] security: Introduce inode_post_remove_acl hook
  2023-03-06 15:34     ` Roberto Sassu
@ 2023-03-06 16:16       ` Stefan Berger
  2023-03-06 16:50         ` Roberto Sassu
  0 siblings, 1 reply; 79+ messages in thread
From: Stefan Berger @ 2023-03-06 16:16 UTC (permalink / raw)
  To: Roberto Sassu, viro, chuck.lever, jlayton, zohar,
	dmitry.kasatkin, paul, jmorris, serge, dhowells, jarkko,
	stephen.smalley.work, eparis, casey, brauner
  Cc: linux-fsdevel, linux-nfs, linux-integrity, linux-security-module,
	keyrings, selinux, linux-kernel, Roberto Sassu



On 3/6/23 10:34, Roberto Sassu wrote:
> On Mon, 2023-03-06 at 10:22 -0500, Stefan Berger wrote:
>>
>> On 3/3/23 13:18, 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_remove_acl hook.
>>>
>>> Signed-off-by: Roberto Sassu <roberto.sassu@huawei.com>
>>> ---
>>>    
>>> +/**
>>> + * security_inode_post_remove_acl() - Update inode sec after remove_acl op
>>> + * @idmap: idmap of the mount
>>> + * @dentry: file
>>> + * @acl_name: acl name
>>> + *
>>> + * Update inode security field after successful remove_acl operation on @dentry
>>> + * in @idmap. The posix acls are identified by @acl_name.
>>> + */
>>> +void security_inode_post_remove_acl(struct mnt_idmap *idmap,
>>> +				    struct dentry *dentry, const char *acl_name)
>>> +{
>>> +	if (unlikely(IS_PRIVATE(d_backing_inode(dentry))))
>>> +		return;
>>
>> Was that a mistake before that EVM and IMA functions did not filtered out private inodes?
> 
> Looks like that. At least for hooks that are not called from
> security.c.

It seems like that all security_* functions are filtering on private inodes. Anonymous inodes have them and some filesystem set the S_PRIVATE flag. So it may not make a difference fro IMA and EVM then.

     Stefan

> 
> Thanks
> 
> Roberto
> 

^ permalink raw reply	[flat|nested] 79+ messages in thread

* Re: [PATCH 01/28] ima: Align ima_inode_post_setattr() definition with LSM infrastructure
  2023-03-03 18:18 ` [PATCH 01/28] ima: Align ima_inode_post_setattr() definition with " Roberto Sassu
@ 2023-03-06 16:46   ` Stefan Berger
  0 siblings, 0 replies; 79+ messages in thread
From: Stefan Berger @ 2023-03-06 16:46 UTC (permalink / raw)
  To: Roberto Sassu, viro, chuck.lever, jlayton, zohar,
	dmitry.kasatkin, paul, jmorris, serge, dhowells, jarkko,
	stephen.smalley.work, eparis, casey, brauner
  Cc: linux-fsdevel, linux-nfs, linux-integrity, linux-security-module,
	keyrings, selinux, linux-kernel, Roberto Sassu



On 3/3/23 13:18, Roberto Sassu wrote:
> From: Roberto Sassu <roberto.sassu@huawei.com>
> 
> Change ima_inode_post_setattr() definition, so that it can be registered as
> implementation of the inode_post_setattr hook.
> 
> Signed-off-by: Roberto Sassu <roberto.sassu@huawei.com>

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

^ permalink raw reply	[flat|nested] 79+ messages in thread

* Re: [PATCH 21/28] security: Introduce inode_post_remove_acl hook
  2023-03-06 16:16       ` Stefan Berger
@ 2023-03-06 16:50         ` Roberto Sassu
  0 siblings, 0 replies; 79+ messages in thread
From: Roberto Sassu @ 2023-03-06 16:50 UTC (permalink / raw)
  To: Stefan Berger, viro, chuck.lever, jlayton, zohar,
	dmitry.kasatkin, paul, jmorris, serge, dhowells, jarkko,
	stephen.smalley.work, eparis, casey, brauner
  Cc: linux-fsdevel, linux-nfs, linux-integrity, linux-security-module,
	keyrings, selinux, linux-kernel, Roberto Sassu

On Mon, 2023-03-06 at 11:16 -0500, Stefan Berger wrote:
> 
> On 3/6/23 10:34, Roberto Sassu wrote:
> > On Mon, 2023-03-06 at 10:22 -0500, Stefan Berger wrote:
> > > On 3/3/23 13:18, 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_remove_acl hook.
> > > > 
> > > > Signed-off-by: Roberto Sassu <roberto.sassu@huawei.com>
> > > > ---
> > > >    
> > > > +/**
> > > > + * security_inode_post_remove_acl() - Update inode sec after remove_acl op
> > > > + * @idmap: idmap of the mount
> > > > + * @dentry: file
> > > > + * @acl_name: acl name
> > > > + *
> > > > + * Update inode security field after successful remove_acl operation on @dentry
> > > > + * in @idmap. The posix acls are identified by @acl_name.
> > > > + */
> > > > +void security_inode_post_remove_acl(struct mnt_idmap *idmap,
> > > > +				    struct dentry *dentry, const char *acl_name)
> > > > +{
> > > > +	if (unlikely(IS_PRIVATE(d_backing_inode(dentry))))
> > > > +		return;
> > > 
> > > Was that a mistake before that EVM and IMA functions did not filtered out private inodes?
> > 
> > Looks like that. At least for hooks that are not called from
> > security.c.
> 
> It seems like that all security_* functions are filtering on private inodes. Anonymous inodes have them and some filesystem set the S_PRIVATE flag. So it may not make a difference fro IMA and EVM then.

Currently, what it would happen is that the HMAC would be updated
without check, since the check function is usually in security.c
(skipped) and the post elsewhere.

With this patch set, also the post function would not be executed for
private inodes. Maybe, it is worth mentioning it in the next version.

Thanks

Roberto


^ permalink raw reply	[flat|nested] 79+ messages in thread

* Re: [PATCH 02/28] ima: Align ima_post_path_mknod() definition with LSM infrastructure
  2023-03-03 18:18 ` [PATCH 02/28] ima: Align ima_post_path_mknod() " Roberto Sassu
@ 2023-03-06 16:52   ` Stefan Berger
  0 siblings, 0 replies; 79+ messages in thread
From: Stefan Berger @ 2023-03-06 16:52 UTC (permalink / raw)
  To: Roberto Sassu, viro, chuck.lever, jlayton, zohar,
	dmitry.kasatkin, paul, jmorris, serge, dhowells, jarkko,
	stephen.smalley.work, eparis, casey, brauner
  Cc: linux-fsdevel, linux-nfs, linux-integrity, linux-security-module,
	keyrings, selinux, linux-kernel, Roberto Sassu



On 3/3/23 13:18, Roberto Sassu wrote:
> From: Roberto Sassu <roberto.sassu@huawei.com>
> 
> Change ima_post_path_mknod() definition, so that it can be registered as
> implementation of the path_post_mknod hook.
> 
> Also, make sure that ima_post_path_mknod() is executed only if
> (mode & S_IFMT) is equal to zero or S_IFREG.
> 
> Add this check to take into account the different placement of the
> path_post_mknod hook (to be introduced) in do_mknodat(). Since the new hook
> will be placed after the switch(), the check ensures that
> ima_post_path_mknod() is invoked as originally intended when it is
> registered as implementation of path_post_mknod.

                 case 0: case S_IFREG:    <---- this here
                         error = vfs_create(mnt_userns, path.dentry->d_inode,
                                            dentry, mode, true);
                         if (!error)
                                 ima_post_path_mknod(mnt_userns, dentry);

> 
> Signed-off-by: Roberto Sassu <roberto.sassu@huawei.com>

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

^ permalink raw reply	[flat|nested] 79+ messages in thread

* Re: [PATCH 03/28] ima: Align ima_post_create_tmpfile() definition with LSM infrastructure
  2023-03-03 18:18 ` [PATCH 03/28] ima: Align ima_post_create_tmpfile() " Roberto Sassu
@ 2023-03-06 16:53   ` Stefan Berger
  2023-03-08 15:15   ` Mimi Zohar
  1 sibling, 0 replies; 79+ messages in thread
From: Stefan Berger @ 2023-03-06 16:53 UTC (permalink / raw)
  To: Roberto Sassu, viro, chuck.lever, jlayton, zohar,
	dmitry.kasatkin, paul, jmorris, serge, dhowells, jarkko,
	stephen.smalley.work, eparis, casey, brauner
  Cc: linux-fsdevel, linux-nfs, linux-integrity, linux-security-module,
	keyrings, selinux, linux-kernel, Roberto Sassu



On 3/3/23 13:18, Roberto Sassu wrote:
> From: Roberto Sassu <roberto.sassu@huawei.com>
> 
> Change ima_post_create_tmpfile() definition, so that it can be registered
> as implementation of the post_create_tmpfile hook.
> 
> Signed-off-by: Roberto Sassu <roberto.sassu@huawei.com>

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

^ permalink raw reply	[flat|nested] 79+ messages in thread

* Re: [PATCH 04/28] ima: Align ima_file_mprotect() definition with LSM infrastructure
  2023-03-03 18:18 ` [PATCH 04/28] ima: Align ima_file_mprotect() " Roberto Sassu
@ 2023-03-06 16:56   ` Stefan Berger
  0 siblings, 0 replies; 79+ messages in thread
From: Stefan Berger @ 2023-03-06 16:56 UTC (permalink / raw)
  To: Roberto Sassu, viro, chuck.lever, jlayton, zohar,
	dmitry.kasatkin, paul, jmorris, serge, dhowells, jarkko,
	stephen.smalley.work, eparis, casey, brauner
  Cc: linux-fsdevel, linux-nfs, linux-integrity, linux-security-module,
	keyrings, selinux, linux-kernel, Roberto Sassu



On 3/3/23 13:18, Roberto Sassu wrote:
> From: Roberto Sassu <roberto.sassu@huawei.com>
> 
> Change ima_file_mprotect() definition, so that it can be registered
> as implementation of the file_mprotect hook.
> 
> Signed-off-by: Roberto Sassu <roberto.sassu@huawei.com>
> ---
Reviewed-by: Stefan Berger <stefanb@linux.ibm.com>

^ permalink raw reply	[flat|nested] 79+ messages in thread

* Re: [PATCH 05/28] ima: Align ima_inode_setxattr() definition with LSM infrastructure
  2023-03-03 18:18 ` [PATCH 05/28] ima: Align ima_inode_setxattr() " Roberto Sassu
@ 2023-03-06 16:57   ` Stefan Berger
  0 siblings, 0 replies; 79+ messages in thread
From: Stefan Berger @ 2023-03-06 16:57 UTC (permalink / raw)
  To: Roberto Sassu, viro, chuck.lever, jlayton, zohar,
	dmitry.kasatkin, paul, jmorris, serge, dhowells, jarkko,
	stephen.smalley.work, eparis, casey, brauner
  Cc: linux-fsdevel, linux-nfs, linux-integrity, linux-security-module,
	keyrings, selinux, linux-kernel, Roberto Sassu



On 3/3/23 13:18, Roberto Sassu wrote:
> From: Roberto Sassu <roberto.sassu@huawei.com>
> 
> Change ima_inode_setxattr() definition, so that it can be registered as
> implementation of the inode_setxattr hook.
> 
> Signed-off-by: Roberto Sassu <roberto.sassu@huawei.com>

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

^ permalink raw reply	[flat|nested] 79+ messages in thread

* Re: [PATCH 06/28] ima: Align ima_inode_removexattr() definition with LSM infrastructure
  2023-03-03 18:18 ` [PATCH 06/28] ima: Align ima_inode_removexattr() " Roberto Sassu
@ 2023-03-06 16:58   ` Stefan Berger
  0 siblings, 0 replies; 79+ messages in thread
From: Stefan Berger @ 2023-03-06 16:58 UTC (permalink / raw)
  To: Roberto Sassu, viro, chuck.lever, jlayton, zohar,
	dmitry.kasatkin, paul, jmorris, serge, dhowells, jarkko,
	stephen.smalley.work, eparis, casey, brauner
  Cc: linux-fsdevel, linux-nfs, linux-integrity, linux-security-module,
	keyrings, selinux, linux-kernel, Roberto Sassu



On 3/3/23 13:18, Roberto Sassu wrote:
> From: Roberto Sassu <roberto.sassu@huawei.com>
> 
> Change ima_inode_removexattr() definition, so that it can be registered as
> implementation of the inode_removexattr hook.
> 
> Signed-off-by: Roberto Sassu <roberto.sassu@huawei.com>

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

^ permalink raw reply	[flat|nested] 79+ messages in thread

* Re: [PATCH 07/28] ima: Align ima_post_read_file() definition with LSM infrastructure
  2023-03-03 18:18 ` [PATCH 07/28] ima: Align ima_post_read_file() " Roberto Sassu
@ 2023-03-06 16:59   ` Stefan Berger
  0 siblings, 0 replies; 79+ messages in thread
From: Stefan Berger @ 2023-03-06 16:59 UTC (permalink / raw)
  To: Roberto Sassu, viro, chuck.lever, jlayton, zohar,
	dmitry.kasatkin, paul, jmorris, serge, dhowells, jarkko,
	stephen.smalley.work, eparis, casey, brauner
  Cc: linux-fsdevel, linux-nfs, linux-integrity, linux-security-module,
	keyrings, selinux, linux-kernel, Roberto Sassu



On 3/3/23 13:18, Roberto Sassu wrote:
> From: Roberto Sassu <roberto.sassu@huawei.com>
> 
> Change ima_post_read_file() definition, so that it can be registered as
> implementation of the post_read_file hook.
> 
> Signed-off-by: Roberto Sassu <roberto.sassu@huawei.com>

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

^ permalink raw reply	[flat|nested] 79+ messages in thread

* Re: [PATCH 08/28] evm: Align evm_inode_post_setattr() definition with LSM infrastructure
  2023-03-03 18:18 ` [PATCH 08/28] evm: Align evm_inode_post_setattr() " Roberto Sassu
@ 2023-03-06 17:00   ` Stefan Berger
  0 siblings, 0 replies; 79+ messages in thread
From: Stefan Berger @ 2023-03-06 17:00 UTC (permalink / raw)
  To: Roberto Sassu, viro, chuck.lever, jlayton, zohar,
	dmitry.kasatkin, paul, jmorris, serge, dhowells, jarkko,
	stephen.smalley.work, eparis, casey, brauner
  Cc: linux-fsdevel, linux-nfs, linux-integrity, linux-security-module,
	keyrings, selinux, linux-kernel, Roberto Sassu



On 3/3/23 13:18, Roberto Sassu wrote:
> From: Roberto Sassu <roberto.sassu@huawei.com>
> 
> Change evm_inode_post_setattr() definition, so that it can be registered as
> implementation of the inode_post_setattr hook.
> 
> Signed-off-by: Roberto Sassu <roberto.sassu@huawei.com>

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

^ permalink raw reply	[flat|nested] 79+ messages in thread

* Re: [PATCH 09/28] evm: Align evm_inode_setxattr() definition with LSM infrastructure
  2023-03-03 18:18 ` [PATCH 09/28] evm: Align evm_inode_setxattr() " Roberto Sassu
@ 2023-03-06 17:01   ` Stefan Berger
  0 siblings, 0 replies; 79+ messages in thread
From: Stefan Berger @ 2023-03-06 17:01 UTC (permalink / raw)
  To: Roberto Sassu, viro, chuck.lever, jlayton, zohar,
	dmitry.kasatkin, paul, jmorris, serge, dhowells, jarkko,
	stephen.smalley.work, eparis, casey, brauner
  Cc: linux-fsdevel, linux-nfs, linux-integrity, linux-security-module,
	keyrings, selinux, linux-kernel, Roberto Sassu



On 3/3/23 13:18, Roberto Sassu wrote:
> From: Roberto Sassu <roberto.sassu@huawei.com>
> 
> Change evm_inode_setxattr() definition, so that it can be registered as
> implementation of the inode_setxattr hook.

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

^ permalink raw reply	[flat|nested] 79+ messages in thread

* Re: [PATCH 10/28] evm: Align evm_inode_post_setxattr() definition with LSM infrastructure
  2023-03-03 18:18 ` [PATCH 10/28] evm: Align evm_inode_post_setxattr() " Roberto Sassu
@ 2023-03-06 17:02   ` Stefan Berger
  0 siblings, 0 replies; 79+ messages in thread
From: Stefan Berger @ 2023-03-06 17:02 UTC (permalink / raw)
  To: Roberto Sassu, viro, chuck.lever, jlayton, zohar,
	dmitry.kasatkin, paul, jmorris, serge, dhowells, jarkko,
	stephen.smalley.work, eparis, casey, brauner
  Cc: linux-fsdevel, linux-nfs, linux-integrity, linux-security-module,
	keyrings, selinux, linux-kernel, Roberto Sassu



On 3/3/23 13:18, Roberto Sassu wrote:
> From: Roberto Sassu <roberto.sassu@huawei.com>
> 
> Change evm_inode_post_setxattr() definition, so that it can be registered
> as implementation of the inode_post_setxattr hook.
> 
> Signed-off-by: Roberto Sassu <roberto.sassu@huawei.com>

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

^ permalink raw reply	[flat|nested] 79+ messages in thread

* Re: [PATCH 11/28] evm: Complete description of evm_inode_setattr()
  2023-03-03 18:18 ` [PATCH 11/28] evm: Complete description of evm_inode_setattr() Roberto Sassu
@ 2023-03-06 17:04   ` Stefan Berger
  2023-03-07  8:58     ` Roberto Sassu
  0 siblings, 1 reply; 79+ messages in thread
From: Stefan Berger @ 2023-03-06 17:04 UTC (permalink / raw)
  To: Roberto Sassu, viro, chuck.lever, jlayton, zohar,
	dmitry.kasatkin, paul, jmorris, serge, dhowells, jarkko,
	stephen.smalley.work, eparis, casey, brauner
  Cc: linux-fsdevel, linux-nfs, linux-integrity, linux-security-module,
	keyrings, selinux, linux-kernel, Roberto Sassu



On 3/3/23 13:18, Roberto Sassu wrote:
> From: Roberto Sassu <roberto.sassu@huawei.com>
> 
> Add the description for missing parameters of evm_inode_setattr() to
> avoid the warning arising with W=n compile option.
> 
> Fixes: 817b54aa45db ("evm: add evm_inode_setattr to prevent updating an invalid security.evm")
> Fixes: c1632a0f1120 ("fs: port ->setattr() to pass mnt_idmap")
> Signed-off-by: Roberto Sassu <roberto.sassu@huawei.com>

Among the previous patches I think there were 2 fixes like this one you could possibly also split off.

Reviewed-by: Stefan Berger <stefanb@linux.ibm.com>
> ---
>   security/integrity/evm/evm_main.c | 2 ++
>   1 file changed, 2 insertions(+)
> 
> diff --git a/security/integrity/evm/evm_main.c b/security/integrity/evm/evm_main.c
> index 1155a58ae87..8b5c472f78b 100644
> --- a/security/integrity/evm/evm_main.c
> +++ b/security/integrity/evm/evm_main.c
> @@ -798,7 +798,9 @@ static int evm_attr_change(struct mnt_idmap *idmap,
>   
>   /**
>    * evm_inode_setattr - prevent updating an invalid EVM extended attribute
> + * @idmap: idmap of the mount
>    * @dentry: pointer to the affected dentry
> + * @attr: iattr structure containing the new file attributes
>    *
>    * Permit update of file attributes when files have a valid EVM signature,
>    * except in the case of them having an immutable portable signature.

^ permalink raw reply	[flat|nested] 79+ messages in thread

* Re: [PATCH 13/28] security: Align inode_setattr hook definition with EVM
  2023-03-03 18:18 ` [PATCH 13/28] security: Align inode_setattr hook definition with EVM Roberto Sassu
  2023-03-05  0:42   ` Casey Schaufler
@ 2023-03-06 17:06   ` Stefan Berger
  1 sibling, 0 replies; 79+ messages in thread
From: Stefan Berger @ 2023-03-06 17:06 UTC (permalink / raw)
  To: Roberto Sassu, viro, chuck.lever, jlayton, zohar,
	dmitry.kasatkin, paul, jmorris, serge, dhowells, jarkko,
	stephen.smalley.work, eparis, casey, brauner
  Cc: linux-fsdevel, linux-nfs, linux-integrity, linux-security-module,
	keyrings, selinux, linux-kernel, Roberto Sassu



On 3/3/23 13:18, Roberto Sassu wrote:
> From: Roberto Sassu <roberto.sassu@huawei.com>
> 
> Add the idmap parameter to the definition, so that evm_inode_setattr() can
> be registered as this hook implementation.
> 
> Signed-off-by: Roberto Sassu <roberto.sassu@huawei.com>

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

^ permalink raw reply	[flat|nested] 79+ messages in thread

* Re: [PATCH 14/28] security: Introduce inode_post_setattr hook
  2023-03-03 18:18 ` [PATCH 14/28] security: Introduce inode_post_setattr hook Roberto Sassu
@ 2023-03-06 17:08   ` Stefan Berger
  2023-03-08 15:19   ` Mimi Zohar
  1 sibling, 0 replies; 79+ messages in thread
From: Stefan Berger @ 2023-03-06 17:08 UTC (permalink / raw)
  To: Roberto Sassu, viro, chuck.lever, jlayton, zohar,
	dmitry.kasatkin, paul, jmorris, serge, dhowells, jarkko,
	stephen.smalley.work, eparis, casey, brauner
  Cc: linux-fsdevel, linux-nfs, linux-integrity, linux-security-module,
	keyrings, selinux, linux-kernel, Roberto Sassu



On 3/3/23 13:18, 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_setattr hook.
> 
> Signed-off-by: Roberto Sassu <roberto.sassu@huawei.com>

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

^ permalink raw reply	[flat|nested] 79+ messages in thread

* Re: [PATCH 15/28] security: Introduce inode_post_removexattr hook
  2023-03-03 18:18 ` [PATCH 15/28] security: Introduce inode_post_removexattr hook Roberto Sassu
@ 2023-03-06 19:17   ` Stefan Berger
  2023-03-08 15:43   ` Mimi Zohar
  1 sibling, 0 replies; 79+ messages in thread
From: Stefan Berger @ 2023-03-06 19:17 UTC (permalink / raw)
  To: Roberto Sassu, viro, chuck.lever, jlayton, zohar,
	dmitry.kasatkin, paul, jmorris, serge, dhowells, jarkko,
	stephen.smalley.work, eparis, casey, brauner
  Cc: linux-fsdevel, linux-nfs, linux-integrity, linux-security-module,
	keyrings, selinux, linux-kernel, Roberto Sassu



On 3/3/23 13:18, 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_removexattr hook.
> 
> Signed-off-by: Roberto Sassu <roberto.sassu@huawei.com>

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

^ permalink raw reply	[flat|nested] 79+ messages in thread

* Re: [PATCH 16/28] security: Introduce file_post_open hook
  2023-03-03 18:18 ` [PATCH 16/28] security: Introduce file_post_open hook Roberto Sassu
@ 2023-03-06 19:24   ` Stefan Berger
  0 siblings, 0 replies; 79+ messages in thread
From: Stefan Berger @ 2023-03-06 19:24 UTC (permalink / raw)
  To: Roberto Sassu, viro, chuck.lever, jlayton, zohar,
	dmitry.kasatkin, paul, jmorris, serge, dhowells, jarkko,
	stephen.smalley.work, eparis, casey, brauner
  Cc: linux-fsdevel, linux-nfs, linux-integrity, linux-security-module,
	keyrings, selinux, linux-kernel, Roberto Sassu



On 3/3/23 13:18, Roberto Sassu wrote:
> From: Roberto Sassu <roberto.sassu@huawei.com>
> 
> In preparation to move IMA and EVM to the LSM infrastructure, introduce the
> file_post_open hook. Also, export security_file_post_open() for NFS.
> 
> Signed-off-by: Roberto Sassu <roberto.sassu@huawei.com>

>   
> +/**
> + * security_file_post_open() - Recheck access to a file after it has been opened
> + * @file: the file
> + * @mask: access mask
> + *
> + * Recheck access with mask after the file has been opened. The hook is useful
> + * for LSMs that require the file content to be available in order to make
> + * decisions.
> + *
> + * Return: Returns 0 if permission is granted.
> + */
> +int security_file_post_open(struct file *file, int mask)
> +{

Files with private inodes don't seem to checked for in any existing functions, either, so no check. Good..

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

> +	return call_int_hook(file_post_open, 0, file, mask);
> +}
> +EXPORT_SYMBOL_GPL(security_file_post_open);
> +
>   /**
>    * security_file_truncate() - Check if truncating a file is allowed
>    * @file: file

^ permalink raw reply	[flat|nested] 79+ messages in thread

* Re: [PATCH 17/28] security: Introduce file_pre_free_security hook
  2023-03-03 18:18 ` [PATCH 17/28] security: Introduce file_pre_free_security hook Roberto Sassu
@ 2023-03-06 19:26   ` Stefan Berger
  0 siblings, 0 replies; 79+ messages in thread
From: Stefan Berger @ 2023-03-06 19:26 UTC (permalink / raw)
  To: Roberto Sassu, viro, chuck.lever, jlayton, zohar,
	dmitry.kasatkin, paul, jmorris, serge, dhowells, jarkko,
	stephen.smalley.work, eparis, casey, brauner
  Cc: linux-fsdevel, linux-nfs, linux-integrity, linux-security-module,
	keyrings, selinux, linux-kernel, Roberto Sassu



On 3/3/23 13:18, Roberto Sassu wrote:
> From: Roberto Sassu <roberto.sassu@huawei.com>
> 
> In preparation for moving IMA and EVM to the LSM infrastructure, introduce
> the file_pre_free_security hook.
> 
> Signed-off-by: Roberto Sassu <roberto.sassu@huawei.com>


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

^ permalink raw reply	[flat|nested] 79+ messages in thread

* Re: [PATCH 18/28] security: Introduce path_post_mknod hook
  2023-03-03 18:18 ` [PATCH 18/28] security: Introduce path_post_mknod hook Roberto Sassu
@ 2023-03-06 19:29   ` Stefan Berger
  2023-03-08 15:47   ` Mimi Zohar
  1 sibling, 0 replies; 79+ messages in thread
From: Stefan Berger @ 2023-03-06 19:29 UTC (permalink / raw)
  To: Roberto Sassu, viro, chuck.lever, jlayton, zohar,
	dmitry.kasatkin, paul, jmorris, serge, dhowells, jarkko,
	stephen.smalley.work, eparis, casey, brauner
  Cc: linux-fsdevel, linux-nfs, linux-integrity, linux-security-module,
	keyrings, selinux, linux-kernel, Roberto Sassu



On 3/3/23 13:18, Roberto Sassu wrote:
> From: Roberto Sassu <roberto.sassu@huawei.com>
> 
> In preparation for moving IMA and EVM to the LSM infrastructure, introduce
> the path_post_mknod hook.
> 
> Signed-off-by: Roberto Sassu <roberto.sassu@huawei.com>

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


^ permalink raw reply	[flat|nested] 79+ messages in thread

* Re: [PATCH 19/28] security: Introduce inode_post_create_tmpfile hook
  2023-03-03 18:18 ` [PATCH 19/28] security: Introduce inode_post_create_tmpfile hook Roberto Sassu
@ 2023-03-06 19:35   ` Stefan Berger
  0 siblings, 0 replies; 79+ messages in thread
From: Stefan Berger @ 2023-03-06 19:35 UTC (permalink / raw)
  To: Roberto Sassu, viro, chuck.lever, jlayton, zohar,
	dmitry.kasatkin, paul, jmorris, serge, dhowells, jarkko,
	stephen.smalley.work, eparis, casey, brauner
  Cc: linux-fsdevel, linux-nfs, linux-integrity, linux-security-module,
	keyrings, selinux, linux-kernel, Roberto Sassu



On 3/3/23 13:18, 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.
> 
> 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 3f2747521d3..8c4fdfd81d4 100644
> --- a/fs/namei.c
> +++ b/fs/namei.c
> @@ -3624,6 +3624,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_dentry(file), mode);
>   	ima_post_create_tmpfile(idmap, dir, file_dentry(file), mode);
>   	return 0;
>   }
> diff --git a/include/linux/lsm_hook_defs.h b/include/linux/lsm_hook_defs.h
> index 32c801a3ea2..5dc2a7c3d9a 100644
> --- a/include/linux/lsm_hook_defs.h
> +++ b/include/linux/lsm_hook_defs.h
> @@ -120,6 +120,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 dentry *dentry, 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 fb6e9d434c6..b3e201404dc 100644
> --- a/include/linux/security.h
> +++ b/include/linux/security.h
> @@ -337,6 +337,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 dentry *dentry, 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);
> @@ -787,6 +790,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 dentry *dentry, 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 f5f367e2064..8883082b686 100644
> --- a/security/security.c
> +++ b/security/security.c
> @@ -1971,6 +1971,24 @@ int security_inode_create(struct inode *dir, struct dentry *dentry,
>   }
>   EXPORT_SYMBOL_GPL(security_inode_create);
>   
> +/**
> + * security_inode_post_create_tmpfile() - Update inode sec after tmpfile created

'sec'? -> Update inode security field after creation of tmpfile



> + * @idmap: idmap of the mount
> + * @dir: the inode of the base directory
> + * @dentry: the dentry of the new tmpfile
> + * @mode: the mode of the new tmpfile
> + *
> + * Update inode security field after a tmpfile has been created.

With the nit above:

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


> + */
> +void security_inode_post_create_tmpfile(struct mnt_idmap *idmap,
> +					struct inode *dir,
> +					struct dentry *dentry, umode_t mode)
> +{
> +	if (unlikely(IS_PRIVATE(dir)))
> +		return;
> +	call_void_hook(inode_post_create_tmpfile, idmap, dir, dentry, mode);
> +}
> +
>   /**
>    * security_inode_link() - Check if creating a hard link is allowed
>    * @old_dentry: existing file

^ permalink raw reply	[flat|nested] 79+ messages in thread

* Re: [PATCH 20/28] security: Introduce inode_post_set_acl hook
  2023-03-03 18:18 ` [PATCH 20/28] security: Introduce inode_post_set_acl hook Roberto Sassu
@ 2023-03-06 19:45   ` Stefan Berger
  0 siblings, 0 replies; 79+ messages in thread
From: Stefan Berger @ 2023-03-06 19:45 UTC (permalink / raw)
  To: Roberto Sassu, viro, chuck.lever, jlayton, zohar,
	dmitry.kasatkin, paul, jmorris, serge, dhowells, jarkko,
	stephen.smalley.work, eparis, casey, brauner
  Cc: linux-fsdevel, linux-nfs, linux-integrity, linux-security-module,
	keyrings, selinux, linux-kernel, Roberto Sassu



On 3/3/23 13:18, 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_set_acl hook.
> 
> Signed-off-by: Roberto Sassu <roberto.sassu@huawei.com>
> ---
>   fs/posix_acl.c                |  1 +
>   include/linux/lsm_hook_defs.h |  2 ++
>   include/linux/security.h      |  7 +++++++
>   security/security.c           | 17 +++++++++++++++++
>   4 files changed, 27 insertions(+)
> 
> diff --git a/fs/posix_acl.c b/fs/posix_acl.c
> index 5a76fb35923..acddf2dff4c 100644
> --- a/fs/posix_acl.c
> +++ b/fs/posix_acl.c
> @@ -1102,6 +1102,7 @@ int vfs_set_acl(struct mnt_idmap *idmap, struct dentry *dentry,
>   		error = -EOPNOTSUPP;
>   	if (!error) {
>   		fsnotify_xattr(dentry);
> +		security_inode_post_set_acl(dentry, acl_name, kacl);
>   		evm_inode_post_set_acl(dentry, acl_name, kacl);
>   	}
>   
> diff --git a/include/linux/lsm_hook_defs.h b/include/linux/lsm_hook_defs.h
> index 5dc2a7c3d9a..9a3e14db0af 100644
> --- a/include/linux/lsm_hook_defs.h
> +++ b/include/linux/lsm_hook_defs.h
> @@ -156,6 +156,8 @@ LSM_HOOK(void, LSM_RET_VOID, inode_post_removexattr, struct dentry *dentry,
>   	 const char *name)
>   LSM_HOOK(int, 0, inode_set_acl, struct mnt_idmap *idmap,
>   	 struct dentry *dentry, const char *acl_name, struct posix_acl *kacl)
> +LSM_HOOK(void, LSM_RET_VOID, inode_post_set_acl, struct dentry *dentry,
> +	 const char *acl_name, struct posix_acl *kacl)
>   LSM_HOOK(int, 0, inode_get_acl, struct mnt_idmap *idmap,
>   	 struct dentry *dentry, const char *acl_name)
>   LSM_HOOK(int, 0, inode_remove_acl, struct mnt_idmap *idmap,
> diff --git a/include/linux/security.h b/include/linux/security.h
> index b3e201404dc..b0691bf7237 100644
> --- a/include/linux/security.h
> +++ b/include/linux/security.h
> @@ -366,6 +366,8 @@ int security_inode_setxattr(struct mnt_idmap *idmap,
>   int security_inode_set_acl(struct mnt_idmap *idmap,
>   			   struct dentry *dentry, const char *acl_name,
>   			   struct posix_acl *kacl);
> +void security_inode_post_set_acl(struct dentry *dentry, const char *acl_name,
> +				 struct posix_acl *kacl);
>   int security_inode_get_acl(struct mnt_idmap *idmap,
>   			   struct dentry *dentry, const char *acl_name);
>   int security_inode_remove_acl(struct mnt_idmap *idmap,
> @@ -893,6 +895,11 @@ static inline int security_inode_set_acl(struct mnt_idmap *idmap,
>   	return 0;
>   }
>   
> +static inline void security_inode_post_set_acl(struct dentry *dentry,
> +					       const char *acl_name,
> +					       struct posix_acl *kacl)
> +{ }
> +
>   static inline int security_inode_get_acl(struct mnt_idmap *idmap,
>   					 struct dentry *dentry,
>   					 const char *acl_name)
> diff --git a/security/security.c b/security/security.c
> index 8883082b686..fc11d70bb02 100644
> --- a/security/security.c
> +++ b/security/security.c
> @@ -2310,6 +2310,23 @@ int security_inode_set_acl(struct mnt_idmap *idmap,
>   	return evm_inode_set_acl(idmap, dentry, acl_name, kacl);
>   }
>   
> +/**
> + * security_inode_post_set_acl() - Update inode sec after set_acl operation

'sec' because 'security' doesn't let this fit into 80 characters for the line?

Update inode security after set_acl op     :-/
Update inode security after set_acl()      :-)

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

^ permalink raw reply	[flat|nested] 79+ messages in thread

* Re: [PATCH 11/28] evm: Complete description of evm_inode_setattr()
  2023-03-06 17:04   ` Stefan Berger
@ 2023-03-07  8:58     ` Roberto Sassu
  0 siblings, 0 replies; 79+ messages in thread
From: Roberto Sassu @ 2023-03-07  8:58 UTC (permalink / raw)
  To: Stefan Berger, viro, chuck.lever, jlayton, zohar,
	dmitry.kasatkin, paul, jmorris, serge, dhowells, jarkko,
	stephen.smalley.work, eparis, casey, brauner
  Cc: linux-fsdevel, linux-nfs, linux-integrity, linux-security-module,
	keyrings, selinux, linux-kernel, Roberto Sassu

On Mon, 2023-03-06 at 12:04 -0500, Stefan Berger wrote:
> 
> On 3/3/23 13:18, Roberto Sassu wrote:
> > From: Roberto Sassu <roberto.sassu@huawei.com>
> > 
> > Add the description for missing parameters of evm_inode_setattr() to
> > avoid the warning arising with W=n compile option.
> > 
> > Fixes: 817b54aa45db ("evm: add evm_inode_setattr to prevent updating an invalid security.evm")
> > Fixes: c1632a0f1120 ("fs: port ->setattr() to pass mnt_idmap")
> > Signed-off-by: Roberto Sassu <roberto.sassu@huawei.com>
> 
> Among the previous patches I think there were 2 fixes like this one you could possibly also split off.

Didn't find it.

Thanks

Roberto

> Reviewed-by: Stefan Berger <stefanb@linux.ibm.com>
> > ---
> >   security/integrity/evm/evm_main.c | 2 ++
> >   1 file changed, 2 insertions(+)
> > 
> > diff --git a/security/integrity/evm/evm_main.c b/security/integrity/evm/evm_main.c
> > index 1155a58ae87..8b5c472f78b 100644
> > --- a/security/integrity/evm/evm_main.c
> > +++ b/security/integrity/evm/evm_main.c
> > @@ -798,7 +798,9 @@ static int evm_attr_change(struct mnt_idmap *idmap,
> >   
> >   /**
> >    * evm_inode_setattr - prevent updating an invalid EVM extended attribute
> > + * @idmap: idmap of the mount
> >    * @dentry: pointer to the affected dentry
> > + * @attr: iattr structure containing the new file attributes
> >    *
> >    * Permit update of file attributes when files have a valid EVM signature,
> >    * except in the case of them having an immutable portable signature.


^ permalink raw reply	[flat|nested] 79+ messages in thread

* Re: [PATCH 26/28] evm: Move to LSM infrastructure
  2023-03-06  9:21     ` Roberto Sassu
@ 2023-03-07 16:54       ` Casey Schaufler
  2023-03-07 16:57         ` Roberto Sassu
  0 siblings, 1 reply; 79+ messages in thread
From: Casey Schaufler @ 2023-03-07 16:54 UTC (permalink / raw)
  To: Roberto Sassu, viro, chuck.lever, jlayton, zohar,
	dmitry.kasatkin, paul, jmorris, serge, dhowells, jarkko,
	stephen.smalley.work, eparis, brauner
  Cc: linux-fsdevel, linux-nfs, linux-integrity, linux-security-module,
	keyrings, selinux, linux-kernel, stefanb, Roberto Sassu, casey

On 3/6/2023 1:21 AM, Roberto Sassu wrote:
> On Sat, 2023-03-04 at 13:36 -0800, Casey Schaufler wrote:
>> On 3/3/2023 10:26 AM, Roberto Sassu wrote:
>>> From: Roberto Sassu <roberto.sassu@huawei.com>
>>>
>>> As for IMA, remove hardcoded EVM function calls from the LSM infrastructure
>>> and the VFS. Make EVM functions as static (except for
>>> evm_inode_init_security(), which is exported), and register them as hook
>>> implementations in init_evm_lsm(), called from integrity_lsm_init().
>>>
>>> Finally, switch to the LSM reservation mechanism for the EVM xattr, by
>>> setting the lbs_xattr field of the lsm_blob_sizes structure, and
>>> consequently decrement the number of xattrs to allocate in
>>> security_inode_init_security().
>>>
>>> Signed-off-by: Roberto Sassu <roberto.sassu@huawei.com>
>>> ---
>>>  fs/attr.c                         |   2 -
>>>  fs/posix_acl.c                    |   3 -
>>>  fs/xattr.c                        |   2 -
>>>  include/linux/evm.h               | 116 ------------------------------
>>>  security/integrity/evm/evm_main.c | 106 ++++++++++++++++++++++-----
>>>  security/integrity/iint.c         |   7 ++
>>>  security/integrity/integrity.h    |   9 +++
>>>  security/security.c               |  41 +++--------
>>>  8 files changed, 115 insertions(+), 171 deletions(-)
>>>
>>> diff --git a/fs/attr.c b/fs/attr.c
>>> index 406d782dfab..1b911a627fe 100644
>>> --- a/fs/attr.c
>>> +++ b/fs/attr.c
>>> @@ -16,7 +16,6 @@
>>>  #include <linux/fcntl.h>
>>>  #include <linux/filelock.h>
>>>  #include <linux/security.h>
>>> -#include <linux/evm.h>
>>>  
>>>  #include "internal.h"
>>>  
>>> @@ -485,7 +484,6 @@ int notify_change(struct mnt_idmap *idmap, struct dentry *dentry,
>>>  	if (!error) {
>>>  		fsnotify_change(dentry, ia_valid);
>>>  		security_inode_post_setattr(idmap, dentry, ia_valid);
>>> -		evm_inode_post_setattr(idmap, dentry, ia_valid);
>>>  	}
>>>  
>>>  	return error;
>>> diff --git a/fs/posix_acl.c b/fs/posix_acl.c
>>> index 5b8c92fce0c..608cb0a9f84 100644
>>> --- a/fs/posix_acl.c
>>> +++ b/fs/posix_acl.c
>>> @@ -26,7 +26,6 @@
>>>  #include <linux/mnt_idmapping.h>
>>>  #include <linux/iversion.h>
>>>  #include <linux/security.h>
>>> -#include <linux/evm.h>
>>>  #include <linux/fsnotify.h>
>>>  #include <linux/filelock.h>
>>>  
>>> @@ -1103,7 +1102,6 @@ int vfs_set_acl(struct mnt_idmap *idmap, struct dentry *dentry,
>>>  	if (!error) {
>>>  		fsnotify_xattr(dentry);
>>>  		security_inode_post_set_acl(dentry, acl_name, kacl);
>>> -		evm_inode_post_set_acl(dentry, acl_name, kacl);
>>>  	}
>>>  
>>>  out_inode_unlock:
>>> @@ -1214,7 +1212,6 @@ int vfs_remove_acl(struct mnt_idmap *idmap, struct dentry *dentry,
>>>  	if (!error) {
>>>  		fsnotify_xattr(dentry);
>>>  		security_inode_post_remove_acl(idmap, dentry, acl_name);
>>> -		evm_inode_post_remove_acl(idmap, dentry, acl_name);
>>>  	}
>>>  
>>>  out_inode_unlock:
>>> diff --git a/fs/xattr.c b/fs/xattr.c
>>> index 10c959d9fc6..7708ffdacca 100644
>>> --- a/fs/xattr.c
>>> +++ b/fs/xattr.c
>>> @@ -16,7 +16,6 @@
>>>  #include <linux/mount.h>
>>>  #include <linux/namei.h>
>>>  #include <linux/security.h>
>>> -#include <linux/evm.h>
>>>  #include <linux/syscalls.h>
>>>  #include <linux/export.h>
>>>  #include <linux/fsnotify.h>
>>> @@ -535,7 +534,6 @@ __vfs_removexattr_locked(struct mnt_idmap *idmap,
>>>  	if (!error) {
>>>  		fsnotify_xattr(dentry);
>>>  		security_inode_post_removexattr(dentry, name);
>>> -		evm_inode_post_removexattr(dentry, name);
>>>  	}
>>>  
>>>  out:
>>> diff --git a/include/linux/evm.h b/include/linux/evm.h
>>> index 8c043273552..61794299f09 100644
>>> --- a/include/linux/evm.h
>>> +++ b/include/linux/evm.h
>>> @@ -21,46 +21,6 @@ extern enum integrity_status evm_verifyxattr(struct dentry *dentry,
>>>  					     void *xattr_value,
>>>  					     size_t xattr_value_len,
>>>  					     struct integrity_iint_cache *iint);
>>> -extern int evm_inode_setattr(struct mnt_idmap *idmap,
>>> -			     struct dentry *dentry, struct iattr *attr);
>>> -extern void evm_inode_post_setattr(struct mnt_idmap *idmap,
>>> -				   struct dentry *dentry, int ia_valid);
>>> -extern int evm_inode_setxattr(struct mnt_idmap *idmap,
>>> -			      struct dentry *dentry, const char *name,
>>> -			      const void *value, size_t size, int flags);
>>> -extern void evm_inode_post_setxattr(struct dentry *dentry,
>>> -				    const char *xattr_name,
>>> -				    const void *xattr_value,
>>> -				    size_t xattr_value_len,
>>> -				    int flags);
>>> -extern int evm_inode_removexattr(struct mnt_idmap *idmap,
>>> -				 struct dentry *dentry, const char *xattr_name);
>>> -extern void evm_inode_post_removexattr(struct dentry *dentry,
>>> -				       const char *xattr_name);
>>> -static inline void evm_inode_post_remove_acl(struct mnt_idmap *idmap,
>>> -					     struct dentry *dentry,
>>> -					     const char *acl_name)
>>> -{
>>> -	evm_inode_post_removexattr(dentry, acl_name);
>>> -}
>>> -extern int evm_inode_set_acl(struct mnt_idmap *idmap,
>>> -			     struct dentry *dentry, const char *acl_name,
>>> -			     struct posix_acl *kacl);
>>> -static inline int evm_inode_remove_acl(struct mnt_idmap *idmap,
>>> -				       struct dentry *dentry,
>>> -				       const char *acl_name)
>>> -{
>>> -	return evm_inode_set_acl(idmap, dentry, acl_name, NULL);
>>> -}
>>> -static inline void evm_inode_post_set_acl(struct dentry *dentry,
>>> -					  const char *acl_name,
>>> -					  struct posix_acl *kacl)
>>> -{
>>> -	return evm_inode_post_setxattr(dentry, acl_name, NULL, 0, 0);
>>> -}
>>> -extern int evm_inode_init_security(struct inode *inode, struct inode *dir,
>>> -				   const struct qstr *qstr,
>>> -				   struct xattr *xattrs);
>>>  extern bool evm_revalidate_status(const char *xattr_name);
>>>  extern int evm_protected_xattr_if_enabled(const char *req_xattr_name);
>>>  extern int evm_read_protected_xattrs(struct dentry *dentry, u8 *buffer,
>>> @@ -92,82 +52,6 @@ static inline enum integrity_status evm_verifyxattr(struct dentry *dentry,
>>>  }
>>>  #endif
>>>  
>>> -static inline int evm_inode_setattr(struct mnt_idmap *idmap,
>>> -				    struct dentry *dentry, struct iattr *attr)
>>> -{
>>> -	return 0;
>>> -}
>>> -
>>> -static inline void evm_inode_post_setattr(struct mnt_idmap *idmap,
>>> -					  struct dentry *dentry, int ia_valid)
>>> -{
>>> -	return;
>>> -}
>>> -
>>> -static inline int evm_inode_setxattr(struct mnt_idmap *idmap,
>>> -				     struct dentry *dentry, const char *name,
>>> -				     const void *value, size_t size, int flags)
>>> -{
>>> -	return 0;
>>> -}
>>> -
>>> -static inline void evm_inode_post_setxattr(struct dentry *dentry,
>>> -					   const char *xattr_name,
>>> -					   const void *xattr_value,
>>> -					   size_t xattr_value_len,
>>> -					   int flags)
>>> -{
>>> -	return;
>>> -}
>>> -
>>> -static inline int evm_inode_removexattr(struct mnt_idmap *idmap,
>>> -					struct dentry *dentry,
>>> -					const char *xattr_name)
>>> -{
>>> -	return 0;
>>> -}
>>> -
>>> -static inline void evm_inode_post_removexattr(struct dentry *dentry,
>>> -					      const char *xattr_name)
>>> -{
>>> -	return;
>>> -}
>>> -
>>> -static inline void evm_inode_post_remove_acl(struct mnt_idmap *idmap,
>>> -					     struct dentry *dentry,
>>> -					     const char *acl_name)
>>> -{
>>> -	return;
>>> -}
>>> -
>>> -static inline int evm_inode_set_acl(struct mnt_idmap *idmap,
>>> -				    struct dentry *dentry, const char *acl_name,
>>> -				    struct posix_acl *kacl)
>>> -{
>>> -	return 0;
>>> -}
>>> -
>>> -static inline int evm_inode_remove_acl(struct mnt_idmap *idmap,
>>> -				       struct dentry *dentry,
>>> -				       const char *acl_name)
>>> -{
>>> -	return 0;
>>> -}
>>> -
>>> -static inline void evm_inode_post_set_acl(struct dentry *dentry,
>>> -					  const char *acl_name,
>>> -					  struct posix_acl *kacl)
>>> -{
>>> -	return;
>>> -}
>>> -
>>> -static inline int evm_inode_init_security(struct inode *inode, struct inode *dir,
>>> -					  const struct qstr *qstr,
>>> -					  struct xattr *xattrs)
>>> -{
>>> -	return 0;
>>> -}
>>> -
>>>  static inline bool evm_revalidate_status(const char *xattr_name)
>>>  {
>>>  	return false;
>>> diff --git a/security/integrity/evm/evm_main.c b/security/integrity/evm/evm_main.c
>>> index 8b5c472f78b..c45bc97277c 100644
>>> --- a/security/integrity/evm/evm_main.c
>>> +++ b/security/integrity/evm/evm_main.c
>>> @@ -19,6 +19,7 @@
>>>  #include <linux/xattr.h>
>>>  #include <linux/integrity.h>
>>>  #include <linux/evm.h>
>>> +#include <linux/lsm_hooks.h>
>>>  #include <linux/magic.h>
>>>  #include <linux/posix_acl_xattr.h>
>>>  
>>> @@ -566,9 +567,9 @@ static int evm_protect_xattr(struct mnt_idmap *idmap,
>>>   * userspace from writing HMAC value.  Writing 'security.evm' requires
>>>   * requires CAP_SYS_ADMIN privileges.
>>>   */
>>> -int evm_inode_setxattr(struct mnt_idmap *idmap, struct dentry *dentry,
>>> -		       const char *xattr_name, const void *xattr_value,
>>> -		       size_t xattr_value_len, int flags)
>>> +static int evm_inode_setxattr(struct mnt_idmap *idmap, struct dentry *dentry,
>>> +			      const char *xattr_name, const void *xattr_value,
>>> +			      size_t xattr_value_len, int flags)
>>>  {
>>>  	const struct evm_ima_xattr_data *xattr_data = xattr_value;
>>>  
>>> @@ -598,8 +599,8 @@ int evm_inode_setxattr(struct mnt_idmap *idmap, struct dentry *dentry,
>>>   * Removing 'security.evm' requires CAP_SYS_ADMIN privileges and that
>>>   * the current value is valid.
>>>   */
>>> -int evm_inode_removexattr(struct mnt_idmap *idmap,
>>> -			  struct dentry *dentry, const char *xattr_name)
>>> +static int evm_inode_removexattr(struct mnt_idmap *idmap, struct dentry *dentry,
>>> +				 const char *xattr_name)
>>>  {
>>>  	/* Policy permits modification of the protected xattrs even though
>>>  	 * there's no HMAC key loaded
>>> @@ -649,9 +650,11 @@ static inline int evm_inode_set_acl_change(struct mnt_idmap *idmap,
>>>   * Prevent modifying posix acls causing the EVM HMAC to be re-calculated
>>>   * and 'security.evm' xattr updated, unless the existing 'security.evm' is
>>>   * valid.
>>> + *
>>> + * Return: zero on success, -EPERM on failure.
>>>   */
>>> -int evm_inode_set_acl(struct mnt_idmap *idmap, struct dentry *dentry,
>>> -		      const char *acl_name, struct posix_acl *kacl)
>>> +static int evm_inode_set_acl(struct mnt_idmap *idmap, struct dentry *dentry,
>>> +			     const char *acl_name, struct posix_acl *kacl)
>>>  {
>>>  	enum integrity_status evm_status;
>>>  
>>> @@ -690,6 +693,24 @@ int evm_inode_set_acl(struct mnt_idmap *idmap, struct dentry *dentry,
>>>  	return -EPERM;
>>>  }
>>>  
>>> +/**
>>> + * evm_inode_remove_acl - Protect the EVM extended attribute from posix acls
>>> + * @idmap: idmap of the mount
>>> + * @dentry: pointer to the affected dentry
>>> + * @acl_name: name of the posix acl
>>> + *
>>> + * Prevent removing posix acls causing the EVM HMAC to be re-calculated
>>> + * and 'security.evm' xattr updated, unless the existing 'security.evm' is
>>> + * valid.
>>> + *
>>> + * Return: zero on success, -EPERM on failure.
>>> + */
>>> +static int evm_inode_remove_acl(struct mnt_idmap *idmap, struct dentry *dentry,
>>> +				const char *acl_name)
>>> +{
>>> +	return evm_inode_set_acl(idmap, dentry, acl_name, NULL);
>>> +}
>>> +
>>>  static void evm_reset_status(struct inode *inode)
>>>  {
>>>  	struct integrity_iint_cache *iint;
>>> @@ -738,9 +759,11 @@ bool evm_revalidate_status(const char *xattr_name)
>>>   * __vfs_setxattr_noperm().  The caller of which has taken the inode's
>>>   * i_mutex lock.
>>>   */
>>> -void evm_inode_post_setxattr(struct dentry *dentry, const char *xattr_name,
>>> -			     const void *xattr_value, size_t xattr_value_len,
>>> -			     int flags)
>>> +static void evm_inode_post_setxattr(struct dentry *dentry,
>>> +				    const char *xattr_name,
>>> +				    const void *xattr_value,
>>> +				    size_t xattr_value_len,
>>> +				    int flags)
>>>  {
>>>  	if (!evm_revalidate_status(xattr_name))
>>>  		return;
>>> @@ -756,6 +779,21 @@ void evm_inode_post_setxattr(struct dentry *dentry, const char *xattr_name,
>>>  	evm_update_evmxattr(dentry, xattr_name, xattr_value, xattr_value_len);
>>>  }
>>>  
>>> +/**
>>> + * evm_inode_post_set_acl - Update the EVM extended attribute from posix acls
>>> + * @dentry: pointer to the affected dentry
>>> + * @acl_name: name of the posix acl
>>> + * @kacl: pointer to the posix acls
>>> + *
>>> + * Update the 'security.evm' xattr with the EVM HMAC re-calculated after setting
>>> + * posix acls.
>>> + */
>>> +static void evm_inode_post_set_acl(struct dentry *dentry, const char *acl_name,
>>> +				   struct posix_acl *kacl)
>>> +{
>>> +	return evm_inode_post_setxattr(dentry, acl_name, NULL, 0, 0);
>>> +}
>>> +
>>>  /**
>>>   * evm_inode_post_removexattr - update 'security.evm' after removing the xattr
>>>   * @dentry: pointer to the affected dentry
>>> @@ -766,7 +804,8 @@ void evm_inode_post_setxattr(struct dentry *dentry, const char *xattr_name,
>>>   * No need to take the i_mutex lock here, as this function is called from
>>>   * vfs_removexattr() which takes the i_mutex.
>>>   */
>>> -void evm_inode_post_removexattr(struct dentry *dentry, const char *xattr_name)
>>> +static void evm_inode_post_removexattr(struct dentry *dentry,
>>> +				       const char *xattr_name)
>>>  {
>>>  	if (!evm_revalidate_status(xattr_name))
>>>  		return;
>>> @@ -782,6 +821,22 @@ void evm_inode_post_removexattr(struct dentry *dentry, const char *xattr_name)
>>>  	evm_update_evmxattr(dentry, xattr_name, NULL, 0);
>>>  }
>>>  
>>> +/**
>>> + * evm_inode_post_remove_acl - Update the EVM extended attribute from posix acls
>>> + * @idmap: idmap of the mount
>>> + * @dentry: pointer to the affected dentry
>>> + * @acl_name: name of the posix acl
>>> + *
>>> + * Update the 'security.evm' xattr with the EVM HMAC re-calculated after
>>> + * removing posix acls.
>>> + */
>>> +static inline void evm_inode_post_remove_acl(struct mnt_idmap *idmap,
>>> +					     struct dentry *dentry,
>>> +					     const char *acl_name)
>>> +{
>>> +	evm_inode_post_removexattr(dentry, acl_name);
>>> +}
>>> +
>>>  static int evm_attr_change(struct mnt_idmap *idmap,
>>>  			   struct dentry *dentry, struct iattr *attr)
>>>  {
>>> @@ -805,8 +860,8 @@ static int evm_attr_change(struct mnt_idmap *idmap,
>>>   * Permit update of file attributes when files have a valid EVM signature,
>>>   * except in the case of them having an immutable portable signature.
>>>   */
>>> -int evm_inode_setattr(struct mnt_idmap *idmap, struct dentry *dentry,
>>> -		      struct iattr *attr)
>>> +static int evm_inode_setattr(struct mnt_idmap *idmap, struct dentry *dentry,
>>> +			     struct iattr *attr)
>>>  {
>>>  	unsigned int ia_valid = attr->ia_valid;
>>>  	enum integrity_status evm_status;
>>> @@ -853,8 +908,8 @@ int evm_inode_setattr(struct mnt_idmap *idmap, struct dentry *dentry,
>>>   * This function is called from notify_change(), which expects the caller
>>>   * to lock the inode's i_mutex.
>>>   */
>>> -void evm_inode_post_setattr(struct mnt_idmap *idmap, struct dentry *dentry,
>>> -			    int ia_valid)
>>> +static void evm_inode_post_setattr(struct mnt_idmap *idmap,
>>> +				   struct dentry *dentry, int ia_valid)
>>>  {
>>>  	if (!evm_revalidate_status(NULL))
>>>  		return;
>>> @@ -892,7 +947,7 @@ int evm_inode_init_security(struct inode *inode, struct inode *dir,
>>>  	if (!evm_protected_xattrs)
>>>  		return -EOPNOTSUPP;
>>>  
>>> -	evm_xattr = xattr;
>>> +	evm_xattr = xattrs + integrity_blob_sizes.lbs_xattr;
>> Please don't do this inline. Convention is to use a function,
>> intergrity_xattrs() for this.
> Ok.
>
>>>  
>>>  	xattr_data = kzalloc(sizeof(*xattr_data), GFP_NOFS);
>>>  	if (!xattr_data)
>>> @@ -952,4 +1007,23 @@ static int __init init_evm(void)
>>>  	return error;
>>>  }
>>>  
>>> +static struct security_hook_list evm_hooks[] __lsm_ro_after_init = {
>>> +	LSM_HOOK_INIT(inode_setattr, evm_inode_setattr),
>>> +	LSM_HOOK_INIT(inode_post_setattr, evm_inode_post_setattr),
>>> +	LSM_HOOK_INIT(inode_setxattr, evm_inode_setxattr),
>>> +	LSM_HOOK_INIT(inode_set_acl, evm_inode_set_acl),
>>> +	LSM_HOOK_INIT(inode_post_set_acl, evm_inode_post_set_acl),
>>> +	LSM_HOOK_INIT(inode_remove_acl, evm_inode_remove_acl),
>>> +	LSM_HOOK_INIT(inode_post_remove_acl, evm_inode_post_remove_acl),
>>> +	LSM_HOOK_INIT(inode_post_setxattr, evm_inode_post_setxattr),
>>> +	LSM_HOOK_INIT(inode_removexattr, evm_inode_removexattr),
>>> +	LSM_HOOK_INIT(inode_post_removexattr, evm_inode_post_removexattr),
>>> +	LSM_HOOK_INIT(inode_init_security, evm_inode_init_security),
>>> +};
>>> +
>>> +void __init init_evm_lsm(void)
>>> +{
>>> +	security_add_hooks(evm_hooks, ARRAY_SIZE(evm_hooks), "integrity");
>>> +}
>>> +
>>>  late_initcall(init_evm);
>>> diff --git a/security/integrity/iint.c b/security/integrity/iint.c
>>> index bbadf974b31..952d5ea4e18 100644
>>> --- a/security/integrity/iint.c
>>> +++ b/security/integrity/iint.c
>>> @@ -179,12 +179,19 @@ static int __init integrity_lsm_init(void)
>>>  			      0, SLAB_PANIC, init_once);
>>>  
>>>  	init_ima_lsm();
>>> +	init_evm_lsm();
>>>  	return 0;
>>>  }
>>> +
>>> +struct lsm_blob_sizes integrity_blob_sizes __lsm_ro_after_init = {
>>> +	.lbs_xattr = 1,
>> Really? 1 byte? Don't even think of storing number of elements in lbs_xattr.
>> The linux_blob_size structure contains sizes of blobs, not number of elements.
> Oh, I see it can be confusing.
>
> However, lbs_xattr does not help to position in the security blob but
> in the new_xattrs array, allocated in security_inode_init_security()
> (see below). Any suggestion on how to make this part better?

On further review, your current use is perfectly reasonable.
The patch that introduces lbs_xattr (not in this set, I see)
needs to document the use so other LSMs can use is correctly.

>
> Thanks
>
> Roberto
>
>>> +};
>>> +
>>>  DEFINE_LSM(integrity) = {
>>>  	.name = "integrity",
>>>  	.init = integrity_lsm_init,
>>>  	.order = LSM_ORDER_LAST,
>>> +	.blobs = &integrity_blob_sizes,
>>>  };
>>>  
>>>  /*
>>> diff --git a/security/integrity/integrity.h b/security/integrity/integrity.h
>>> index c72d375a356..76e7eda6651 100644
>>> --- a/security/integrity/integrity.h
>>> +++ b/security/integrity/integrity.h
>>> @@ -188,6 +188,7 @@ int integrity_kernel_read(struct file *file, loff_t offset,
>>>  #define INTEGRITY_KEYRING_MAX		4
>>>  
>>>  extern struct dentry *integrity_dir;
>>> +extern struct lsm_blob_sizes integrity_blob_sizes;
>>>  
>>>  struct modsig;
>>>  
>>> @@ -199,6 +200,14 @@ static inline void __init init_ima_lsm(void)
>>>  }
>>>  #endif
>>>  
>>> +#ifdef CONFIG_EVM
>>> +void __init init_evm_lsm(void);
>>> +#else
>>> +static inline void __init init_evm_lsm(void)
>>> +{
>>> +}
>>> +#endif
>>> +
>>>  #ifdef CONFIG_INTEGRITY_SIGNATURE
>>>  
>>>  int integrity_digsig_verify(const unsigned int id, const char *sig, int siglen,
>>> diff --git a/security/security.c b/security/security.c
>>> index 9bc6a4ef758..74abf04feef 100644
>>> --- a/security/security.c
>>> +++ b/security/security.c
>>> @@ -20,13 +20,13 @@
>>>  #include <linux/kernel_read_file.h>
>>>  #include <linux/lsm_hooks.h>
>>>  #include <linux/integrity.h>
>>> -#include <linux/evm.h>
>>>  #include <linux/fsnotify.h>
>>>  #include <linux/mman.h>
>>>  #include <linux/mount.h>
>>>  #include <linux/personality.h>
>>>  #include <linux/backing-dev.h>
>>>  #include <linux/string.h>
>>> +#include <linux/xattr.h>
>>>  #include <linux/msg.h>
>>>  #include <net/flow.h>
>>>  
>>> @@ -1662,8 +1662,8 @@ int security_inode_init_security(struct inode *inode, struct inode *dir,
>>>  	if (!initxattrs)
>>>  		return call_int_hook(inode_init_security, -EOPNOTSUPP, inode,
>>>  				    dir, qstr, NULL);
>>> -	/* Allocate +1 for EVM and +1 as terminator. */
>>> -	new_xattrs = kcalloc(blob_sizes.lbs_xattr + 2, sizeof(*new_xattrs),
>>> +	/* Allocate +1 for terminator. */
>>> +	new_xattrs = kcalloc(blob_sizes.lbs_xattr + 1, sizeof(*new_xattrs),
>>>  			     GFP_NOFS);
>>>  	if (!new_xattrs)
>>>  		return -ENOMEM;
>>> @@ -1699,9 +1699,6 @@ int security_inode_init_security(struct inode *inode, struct inode *dir,
>>>  	if (!num_filled_xattrs)
>>>  		goto out;
>>>  
>>> -	ret = evm_inode_init_security(inode, dir, qstr, new_xattrs);
>>> -	if (ret && ret != -EOPNOTSUPP)
>>> -		goto out;
>>>  	ret = initxattrs(inode, new_xattrs, fs_data);
>>>  out:
>>>  	for (xattr = new_xattrs; xattr->value != NULL; xattr++)
>>> @@ -2201,14 +2198,9 @@ int security_inode_permission(struct inode *inode, int mask)
>>>  int security_inode_setattr(struct mnt_idmap *idmap,
>>>  			   struct dentry *dentry, struct iattr *attr)
>>>  {
>>> -	int ret;
>>> -
>>>  	if (unlikely(IS_PRIVATE(d_backing_inode(dentry))))
>>>  		return 0;
>>> -	ret = call_int_hook(inode_setattr, 0, idmap, dentry, attr);
>>> -	if (ret)
>>> -		return ret;
>>> -	return evm_inode_setattr(idmap, dentry, attr);
>>> +	return call_int_hook(inode_setattr, 0, idmap, dentry, attr);
>>>  }
>>>  EXPORT_SYMBOL_GPL(security_inode_setattr);
>>>  
>>> @@ -2272,9 +2264,7 @@ int security_inode_setxattr(struct mnt_idmap *idmap,
>>>  
>>>  	if (ret == 1)
>>>  		ret = cap_inode_setxattr(dentry, name, value, size, flags);
>>> -	if (ret)
>>> -		return ret;
>>> -	return evm_inode_setxattr(idmap, dentry, name, value, size, flags);
>>> +	return ret;
>>>  }
>>>  
>>>  /**
>>> @@ -2293,15 +2283,10 @@ int security_inode_set_acl(struct mnt_idmap *idmap,
>>>  			   struct dentry *dentry, const char *acl_name,
>>>  			   struct posix_acl *kacl)
>>>  {
>>> -	int ret;
>>> -
>>>  	if (unlikely(IS_PRIVATE(d_backing_inode(dentry))))
>>>  		return 0;
>>> -	ret = call_int_hook(inode_set_acl, 0, idmap, dentry, acl_name,
>>> -			    kacl);
>>> -	if (ret)
>>> -		return ret;
>>> -	return evm_inode_set_acl(idmap, dentry, acl_name, kacl);
>>> +	return call_int_hook(inode_set_acl, 0, idmap, dentry, acl_name,
>>> +			     kacl);
>>>  }
>>>  
>>>  /**
>>> @@ -2354,14 +2339,9 @@ int security_inode_get_acl(struct mnt_idmap *idmap,
>>>  int security_inode_remove_acl(struct mnt_idmap *idmap,
>>>  			      struct dentry *dentry, const char *acl_name)
>>>  {
>>> -	int ret;
>>> -
>>>  	if (unlikely(IS_PRIVATE(d_backing_inode(dentry))))
>>>  		return 0;
>>> -	ret = call_int_hook(inode_remove_acl, 0, idmap, dentry, acl_name);
>>> -	if (ret)
>>> -		return ret;
>>> -	return evm_inode_remove_acl(idmap, dentry, acl_name);
>>> +	return call_int_hook(inode_remove_acl, 0, idmap, dentry, acl_name);
>>>  }
>>>  
>>>  /**
>>> @@ -2397,7 +2377,6 @@ void security_inode_post_setxattr(struct dentry *dentry, const char *name,
>>>  	if (unlikely(IS_PRIVATE(d_backing_inode(dentry))))
>>>  		return;
>>>  	call_void_hook(inode_post_setxattr, dentry, name, value, size, flags);
>>> -	evm_inode_post_setxattr(dentry, name, value, size, flags);
>>>  }
>>>  
>>>  /**
>>> @@ -2458,9 +2437,7 @@ int security_inode_removexattr(struct mnt_idmap *idmap,
>>>  	ret = call_int_hook(inode_removexattr, 1, idmap, dentry, name);
>>>  	if (ret == 1)
>>>  		ret = cap_inode_removexattr(idmap, dentry, name);
>>> -	if (ret)
>>> -		return ret;
>>> -	return evm_inode_removexattr(idmap, dentry, name);
>>> +	return ret;
>>>  }
>>>  
>>>  /**

^ permalink raw reply	[flat|nested] 79+ messages in thread

* Re: [PATCH 26/28] evm: Move to LSM infrastructure
  2023-03-07 16:54       ` Casey Schaufler
@ 2023-03-07 16:57         ` Roberto Sassu
  0 siblings, 0 replies; 79+ messages in thread
From: Roberto Sassu @ 2023-03-07 16:57 UTC (permalink / raw)
  To: Casey Schaufler, viro, chuck.lever, jlayton, zohar,
	dmitry.kasatkin, paul, jmorris, serge, dhowells, jarkko,
	stephen.smalley.work, eparis, brauner
  Cc: linux-fsdevel, linux-nfs, linux-integrity, linux-security-module,
	keyrings, selinux, linux-kernel, stefanb, Roberto Sassu

On Tue, 2023-03-07 at 08:54 -0800, Casey Schaufler wrote:
> On 3/6/2023 1:21 AM, Roberto Sassu wrote:
> > On Sat, 2023-03-04 at 13:36 -0800, Casey Schaufler wrote:
> > > On 3/3/2023 10:26 AM, Roberto Sassu wrote:
> > > > From: Roberto Sassu <roberto.sassu@huawei.com>
> > > > 
> > > > As for IMA, remove hardcoded EVM function calls from the LSM infrastructure
> > > > and the VFS. Make EVM functions as static (except for
> > > > evm_inode_init_security(), which is exported), and register them as hook
> > > > implementations in init_evm_lsm(), called from integrity_lsm_init().
> > > > 
> > > > Finally, switch to the LSM reservation mechanism for the EVM xattr, by
> > > > setting the lbs_xattr field of the lsm_blob_sizes structure, and
> > > > consequently decrement the number of xattrs to allocate in
> > > > security_inode_init_security().
> > > > 
> > > > Signed-off-by: Roberto Sassu <roberto.sassu@huawei.com>
> > > > ---
> > > >  fs/attr.c                         |   2 -
> > > >  fs/posix_acl.c                    |   3 -
> > > >  fs/xattr.c                        |   2 -
> > > >  include/linux/evm.h               | 116 ------------------------------
> > > >  security/integrity/evm/evm_main.c | 106 ++++++++++++++++++++++-----
> > > >  security/integrity/iint.c         |   7 ++
> > > >  security/integrity/integrity.h    |   9 +++
> > > >  security/security.c               |  41 +++--------
> > > >  8 files changed, 115 insertions(+), 171 deletions(-)
> > > > 
> > > > diff --git a/fs/attr.c b/fs/attr.c
> > > > index 406d782dfab..1b911a627fe 100644
> > > > --- a/fs/attr.c
> > > > +++ b/fs/attr.c
> > > > @@ -16,7 +16,6 @@
> > > >  #include <linux/fcntl.h>
> > > >  #include <linux/filelock.h>
> > > >  #include <linux/security.h>
> > > > -#include <linux/evm.h>
> > > >  
> > > >  #include "internal.h"
> > > >  
> > > > @@ -485,7 +484,6 @@ int notify_change(struct mnt_idmap *idmap, struct dentry *dentry,
> > > >  	if (!error) {
> > > >  		fsnotify_change(dentry, ia_valid);
> > > >  		security_inode_post_setattr(idmap, dentry, ia_valid);
> > > > -		evm_inode_post_setattr(idmap, dentry, ia_valid);
> > > >  	}
> > > >  
> > > >  	return error;
> > > > diff --git a/fs/posix_acl.c b/fs/posix_acl.c
> > > > index 5b8c92fce0c..608cb0a9f84 100644
> > > > --- a/fs/posix_acl.c
> > > > +++ b/fs/posix_acl.c
> > > > @@ -26,7 +26,6 @@
> > > >  #include <linux/mnt_idmapping.h>
> > > >  #include <linux/iversion.h>
> > > >  #include <linux/security.h>
> > > > -#include <linux/evm.h>
> > > >  #include <linux/fsnotify.h>
> > > >  #include <linux/filelock.h>
> > > >  
> > > > @@ -1103,7 +1102,6 @@ int vfs_set_acl(struct mnt_idmap *idmap, struct dentry *dentry,
> > > >  	if (!error) {
> > > >  		fsnotify_xattr(dentry);
> > > >  		security_inode_post_set_acl(dentry, acl_name, kacl);
> > > > -		evm_inode_post_set_acl(dentry, acl_name, kacl);
> > > >  	}
> > > >  
> > > >  out_inode_unlock:
> > > > @@ -1214,7 +1212,6 @@ int vfs_remove_acl(struct mnt_idmap *idmap, struct dentry *dentry,
> > > >  	if (!error) {
> > > >  		fsnotify_xattr(dentry);
> > > >  		security_inode_post_remove_acl(idmap, dentry, acl_name);
> > > > -		evm_inode_post_remove_acl(idmap, dentry, acl_name);
> > > >  	}
> > > >  
> > > >  out_inode_unlock:
> > > > diff --git a/fs/xattr.c b/fs/xattr.c
> > > > index 10c959d9fc6..7708ffdacca 100644
> > > > --- a/fs/xattr.c
> > > > +++ b/fs/xattr.c
> > > > @@ -16,7 +16,6 @@
> > > >  #include <linux/mount.h>
> > > >  #include <linux/namei.h>
> > > >  #include <linux/security.h>
> > > > -#include <linux/evm.h>
> > > >  #include <linux/syscalls.h>
> > > >  #include <linux/export.h>
> > > >  #include <linux/fsnotify.h>
> > > > @@ -535,7 +534,6 @@ __vfs_removexattr_locked(struct mnt_idmap *idmap,
> > > >  	if (!error) {
> > > >  		fsnotify_xattr(dentry);
> > > >  		security_inode_post_removexattr(dentry, name);
> > > > -		evm_inode_post_removexattr(dentry, name);
> > > >  	}
> > > >  
> > > >  out:
> > > > diff --git a/include/linux/evm.h b/include/linux/evm.h
> > > > index 8c043273552..61794299f09 100644
> > > > --- a/include/linux/evm.h
> > > > +++ b/include/linux/evm.h
> > > > @@ -21,46 +21,6 @@ extern enum integrity_status evm_verifyxattr(struct dentry *dentry,
> > > >  					     void *xattr_value,
> > > >  					     size_t xattr_value_len,
> > > >  					     struct integrity_iint_cache *iint);
> > > > -extern int evm_inode_setattr(struct mnt_idmap *idmap,
> > > > -			     struct dentry *dentry, struct iattr *attr);
> > > > -extern void evm_inode_post_setattr(struct mnt_idmap *idmap,
> > > > -				   struct dentry *dentry, int ia_valid);
> > > > -extern int evm_inode_setxattr(struct mnt_idmap *idmap,
> > > > -			      struct dentry *dentry, const char *name,
> > > > -			      const void *value, size_t size, int flags);
> > > > -extern void evm_inode_post_setxattr(struct dentry *dentry,
> > > > -				    const char *xattr_name,
> > > > -				    const void *xattr_value,
> > > > -				    size_t xattr_value_len,
> > > > -				    int flags);
> > > > -extern int evm_inode_removexattr(struct mnt_idmap *idmap,
> > > > -				 struct dentry *dentry, const char *xattr_name);
> > > > -extern void evm_inode_post_removexattr(struct dentry *dentry,
> > > > -				       const char *xattr_name);
> > > > -static inline void evm_inode_post_remove_acl(struct mnt_idmap *idmap,
> > > > -					     struct dentry *dentry,
> > > > -					     const char *acl_name)
> > > > -{
> > > > -	evm_inode_post_removexattr(dentry, acl_name);
> > > > -}
> > > > -extern int evm_inode_set_acl(struct mnt_idmap *idmap,
> > > > -			     struct dentry *dentry, const char *acl_name,
> > > > -			     struct posix_acl *kacl);
> > > > -static inline int evm_inode_remove_acl(struct mnt_idmap *idmap,
> > > > -				       struct dentry *dentry,
> > > > -				       const char *acl_name)
> > > > -{
> > > > -	return evm_inode_set_acl(idmap, dentry, acl_name, NULL);
> > > > -}
> > > > -static inline void evm_inode_post_set_acl(struct dentry *dentry,
> > > > -					  const char *acl_name,
> > > > -					  struct posix_acl *kacl)
> > > > -{
> > > > -	return evm_inode_post_setxattr(dentry, acl_name, NULL, 0, 0);
> > > > -}
> > > > -extern int evm_inode_init_security(struct inode *inode, struct inode *dir,
> > > > -				   const struct qstr *qstr,
> > > > -				   struct xattr *xattrs);
> > > >  extern bool evm_revalidate_status(const char *xattr_name);
> > > >  extern int evm_protected_xattr_if_enabled(const char *req_xattr_name);
> > > >  extern int evm_read_protected_xattrs(struct dentry *dentry, u8 *buffer,
> > > > @@ -92,82 +52,6 @@ static inline enum integrity_status evm_verifyxattr(struct dentry *dentry,
> > > >  }
> > > >  #endif
> > > >  
> > > > -static inline int evm_inode_setattr(struct mnt_idmap *idmap,
> > > > -				    struct dentry *dentry, struct iattr *attr)
> > > > -{
> > > > -	return 0;
> > > > -}
> > > > -
> > > > -static inline void evm_inode_post_setattr(struct mnt_idmap *idmap,
> > > > -					  struct dentry *dentry, int ia_valid)
> > > > -{
> > > > -	return;
> > > > -}
> > > > -
> > > > -static inline int evm_inode_setxattr(struct mnt_idmap *idmap,
> > > > -				     struct dentry *dentry, const char *name,
> > > > -				     const void *value, size_t size, int flags)
> > > > -{
> > > > -	return 0;
> > > > -}
> > > > -
> > > > -static inline void evm_inode_post_setxattr(struct dentry *dentry,
> > > > -					   const char *xattr_name,
> > > > -					   const void *xattr_value,
> > > > -					   size_t xattr_value_len,
> > > > -					   int flags)
> > > > -{
> > > > -	return;
> > > > -}
> > > > -
> > > > -static inline int evm_inode_removexattr(struct mnt_idmap *idmap,
> > > > -					struct dentry *dentry,
> > > > -					const char *xattr_name)
> > > > -{
> > > > -	return 0;
> > > > -}
> > > > -
> > > > -static inline void evm_inode_post_removexattr(struct dentry *dentry,
> > > > -					      const char *xattr_name)
> > > > -{
> > > > -	return;
> > > > -}
> > > > -
> > > > -static inline void evm_inode_post_remove_acl(struct mnt_idmap *idmap,
> > > > -					     struct dentry *dentry,
> > > > -					     const char *acl_name)
> > > > -{
> > > > -	return;
> > > > -}
> > > > -
> > > > -static inline int evm_inode_set_acl(struct mnt_idmap *idmap,
> > > > -				    struct dentry *dentry, const char *acl_name,
> > > > -				    struct posix_acl *kacl)
> > > > -{
> > > > -	return 0;
> > > > -}
> > > > -
> > > > -static inline int evm_inode_remove_acl(struct mnt_idmap *idmap,
> > > > -				       struct dentry *dentry,
> > > > -				       const char *acl_name)
> > > > -{
> > > > -	return 0;
> > > > -}
> > > > -
> > > > -static inline void evm_inode_post_set_acl(struct dentry *dentry,
> > > > -					  const char *acl_name,
> > > > -					  struct posix_acl *kacl)
> > > > -{
> > > > -	return;
> > > > -}
> > > > -
> > > > -static inline int evm_inode_init_security(struct inode *inode, struct inode *dir,
> > > > -					  const struct qstr *qstr,
> > > > -					  struct xattr *xattrs)
> > > > -{
> > > > -	return 0;
> > > > -}
> > > > -
> > > >  static inline bool evm_revalidate_status(const char *xattr_name)
> > > >  {
> > > >  	return false;
> > > > diff --git a/security/integrity/evm/evm_main.c b/security/integrity/evm/evm_main.c
> > > > index 8b5c472f78b..c45bc97277c 100644
> > > > --- a/security/integrity/evm/evm_main.c
> > > > +++ b/security/integrity/evm/evm_main.c
> > > > @@ -19,6 +19,7 @@
> > > >  #include <linux/xattr.h>
> > > >  #include <linux/integrity.h>
> > > >  #include <linux/evm.h>
> > > > +#include <linux/lsm_hooks.h>
> > > >  #include <linux/magic.h>
> > > >  #include <linux/posix_acl_xattr.h>
> > > >  
> > > > @@ -566,9 +567,9 @@ static int evm_protect_xattr(struct mnt_idmap *idmap,
> > > >   * userspace from writing HMAC value.  Writing 'security.evm' requires
> > > >   * requires CAP_SYS_ADMIN privileges.
> > > >   */
> > > > -int evm_inode_setxattr(struct mnt_idmap *idmap, struct dentry *dentry,
> > > > -		       const char *xattr_name, const void *xattr_value,
> > > > -		       size_t xattr_value_len, int flags)
> > > > +static int evm_inode_setxattr(struct mnt_idmap *idmap, struct dentry *dentry,
> > > > +			      const char *xattr_name, const void *xattr_value,
> > > > +			      size_t xattr_value_len, int flags)
> > > >  {
> > > >  	const struct evm_ima_xattr_data *xattr_data = xattr_value;
> > > >  
> > > > @@ -598,8 +599,8 @@ int evm_inode_setxattr(struct mnt_idmap *idmap, struct dentry *dentry,
> > > >   * Removing 'security.evm' requires CAP_SYS_ADMIN privileges and that
> > > >   * the current value is valid.
> > > >   */
> > > > -int evm_inode_removexattr(struct mnt_idmap *idmap,
> > > > -			  struct dentry *dentry, const char *xattr_name)
> > > > +static int evm_inode_removexattr(struct mnt_idmap *idmap, struct dentry *dentry,
> > > > +				 const char *xattr_name)
> > > >  {
> > > >  	/* Policy permits modification of the protected xattrs even though
> > > >  	 * there's no HMAC key loaded
> > > > @@ -649,9 +650,11 @@ static inline int evm_inode_set_acl_change(struct mnt_idmap *idmap,
> > > >   * Prevent modifying posix acls causing the EVM HMAC to be re-calculated
> > > >   * and 'security.evm' xattr updated, unless the existing 'security.evm' is
> > > >   * valid.
> > > > + *
> > > > + * Return: zero on success, -EPERM on failure.
> > > >   */
> > > > -int evm_inode_set_acl(struct mnt_idmap *idmap, struct dentry *dentry,
> > > > -		      const char *acl_name, struct posix_acl *kacl)
> > > > +static int evm_inode_set_acl(struct mnt_idmap *idmap, struct dentry *dentry,
> > > > +			     const char *acl_name, struct posix_acl *kacl)
> > > >  {
> > > >  	enum integrity_status evm_status;
> > > >  
> > > > @@ -690,6 +693,24 @@ int evm_inode_set_acl(struct mnt_idmap *idmap, struct dentry *dentry,
> > > >  	return -EPERM;
> > > >  }
> > > >  
> > > > +/**
> > > > + * evm_inode_remove_acl - Protect the EVM extended attribute from posix acls
> > > > + * @idmap: idmap of the mount
> > > > + * @dentry: pointer to the affected dentry
> > > > + * @acl_name: name of the posix acl
> > > > + *
> > > > + * Prevent removing posix acls causing the EVM HMAC to be re-calculated
> > > > + * and 'security.evm' xattr updated, unless the existing 'security.evm' is
> > > > + * valid.
> > > > + *
> > > > + * Return: zero on success, -EPERM on failure.
> > > > + */
> > > > +static int evm_inode_remove_acl(struct mnt_idmap *idmap, struct dentry *dentry,
> > > > +				const char *acl_name)
> > > > +{
> > > > +	return evm_inode_set_acl(idmap, dentry, acl_name, NULL);
> > > > +}
> > > > +
> > > >  static void evm_reset_status(struct inode *inode)
> > > >  {
> > > >  	struct integrity_iint_cache *iint;
> > > > @@ -738,9 +759,11 @@ bool evm_revalidate_status(const char *xattr_name)
> > > >   * __vfs_setxattr_noperm().  The caller of which has taken the inode's
> > > >   * i_mutex lock.
> > > >   */
> > > > -void evm_inode_post_setxattr(struct dentry *dentry, const char *xattr_name,
> > > > -			     const void *xattr_value, size_t xattr_value_len,
> > > > -			     int flags)
> > > > +static void evm_inode_post_setxattr(struct dentry *dentry,
> > > > +				    const char *xattr_name,
> > > > +				    const void *xattr_value,
> > > > +				    size_t xattr_value_len,
> > > > +				    int flags)
> > > >  {
> > > >  	if (!evm_revalidate_status(xattr_name))
> > > >  		return;
> > > > @@ -756,6 +779,21 @@ void evm_inode_post_setxattr(struct dentry *dentry, const char *xattr_name,
> > > >  	evm_update_evmxattr(dentry, xattr_name, xattr_value, xattr_value_len);
> > > >  }
> > > >  
> > > > +/**
> > > > + * evm_inode_post_set_acl - Update the EVM extended attribute from posix acls
> > > > + * @dentry: pointer to the affected dentry
> > > > + * @acl_name: name of the posix acl
> > > > + * @kacl: pointer to the posix acls
> > > > + *
> > > > + * Update the 'security.evm' xattr with the EVM HMAC re-calculated after setting
> > > > + * posix acls.
> > > > + */
> > > > +static void evm_inode_post_set_acl(struct dentry *dentry, const char *acl_name,
> > > > +				   struct posix_acl *kacl)
> > > > +{
> > > > +	return evm_inode_post_setxattr(dentry, acl_name, NULL, 0, 0);
> > > > +}
> > > > +
> > > >  /**
> > > >   * evm_inode_post_removexattr - update 'security.evm' after removing the xattr
> > > >   * @dentry: pointer to the affected dentry
> > > > @@ -766,7 +804,8 @@ void evm_inode_post_setxattr(struct dentry *dentry, const char *xattr_name,
> > > >   * No need to take the i_mutex lock here, as this function is called from
> > > >   * vfs_removexattr() which takes the i_mutex.
> > > >   */
> > > > -void evm_inode_post_removexattr(struct dentry *dentry, const char *xattr_name)
> > > > +static void evm_inode_post_removexattr(struct dentry *dentry,
> > > > +				       const char *xattr_name)
> > > >  {
> > > >  	if (!evm_revalidate_status(xattr_name))
> > > >  		return;
> > > > @@ -782,6 +821,22 @@ void evm_inode_post_removexattr(struct dentry *dentry, const char *xattr_name)
> > > >  	evm_update_evmxattr(dentry, xattr_name, NULL, 0);
> > > >  }
> > > >  
> > > > +/**
> > > > + * evm_inode_post_remove_acl - Update the EVM extended attribute from posix acls
> > > > + * @idmap: idmap of the mount
> > > > + * @dentry: pointer to the affected dentry
> > > > + * @acl_name: name of the posix acl
> > > > + *
> > > > + * Update the 'security.evm' xattr with the EVM HMAC re-calculated after
> > > > + * removing posix acls.
> > > > + */
> > > > +static inline void evm_inode_post_remove_acl(struct mnt_idmap *idmap,
> > > > +					     struct dentry *dentry,
> > > > +					     const char *acl_name)
> > > > +{
> > > > +	evm_inode_post_removexattr(dentry, acl_name);
> > > > +}
> > > > +
> > > >  static int evm_attr_change(struct mnt_idmap *idmap,
> > > >  			   struct dentry *dentry, struct iattr *attr)
> > > >  {
> > > > @@ -805,8 +860,8 @@ static int evm_attr_change(struct mnt_idmap *idmap,
> > > >   * Permit update of file attributes when files have a valid EVM signature,
> > > >   * except in the case of them having an immutable portable signature.
> > > >   */
> > > > -int evm_inode_setattr(struct mnt_idmap *idmap, struct dentry *dentry,
> > > > -		      struct iattr *attr)
> > > > +static int evm_inode_setattr(struct mnt_idmap *idmap, struct dentry *dentry,
> > > > +			     struct iattr *attr)
> > > >  {
> > > >  	unsigned int ia_valid = attr->ia_valid;
> > > >  	enum integrity_status evm_status;
> > > > @@ -853,8 +908,8 @@ int evm_inode_setattr(struct mnt_idmap *idmap, struct dentry *dentry,
> > > >   * This function is called from notify_change(), which expects the caller
> > > >   * to lock the inode's i_mutex.
> > > >   */
> > > > -void evm_inode_post_setattr(struct mnt_idmap *idmap, struct dentry *dentry,
> > > > -			    int ia_valid)
> > > > +static void evm_inode_post_setattr(struct mnt_idmap *idmap,
> > > > +				   struct dentry *dentry, int ia_valid)
> > > >  {
> > > >  	if (!evm_revalidate_status(NULL))
> > > >  		return;
> > > > @@ -892,7 +947,7 @@ int evm_inode_init_security(struct inode *inode, struct inode *dir,
> > > >  	if (!evm_protected_xattrs)
> > > >  		return -EOPNOTSUPP;
> > > >  
> > > > -	evm_xattr = xattr;
> > > > +	evm_xattr = xattrs + integrity_blob_sizes.lbs_xattr;
> > > Please don't do this inline. Convention is to use a function,
> > > intergrity_xattrs() for this.
> > Ok.
> > 
> > > >  
> > > >  	xattr_data = kzalloc(sizeof(*xattr_data), GFP_NOFS);
> > > >  	if (!xattr_data)
> > > > @@ -952,4 +1007,23 @@ static int __init init_evm(void)
> > > >  	return error;
> > > >  }
> > > >  
> > > > +static struct security_hook_list evm_hooks[] __lsm_ro_after_init = {
> > > > +	LSM_HOOK_INIT(inode_setattr, evm_inode_setattr),
> > > > +	LSM_HOOK_INIT(inode_post_setattr, evm_inode_post_setattr),
> > > > +	LSM_HOOK_INIT(inode_setxattr, evm_inode_setxattr),
> > > > +	LSM_HOOK_INIT(inode_set_acl, evm_inode_set_acl),
> > > > +	LSM_HOOK_INIT(inode_post_set_acl, evm_inode_post_set_acl),
> > > > +	LSM_HOOK_INIT(inode_remove_acl, evm_inode_remove_acl),
> > > > +	LSM_HOOK_INIT(inode_post_remove_acl, evm_inode_post_remove_acl),
> > > > +	LSM_HOOK_INIT(inode_post_setxattr, evm_inode_post_setxattr),
> > > > +	LSM_HOOK_INIT(inode_removexattr, evm_inode_removexattr),
> > > > +	LSM_HOOK_INIT(inode_post_removexattr, evm_inode_post_removexattr),
> > > > +	LSM_HOOK_INIT(inode_init_security, evm_inode_init_security),
> > > > +};
> > > > +
> > > > +void __init init_evm_lsm(void)
> > > > +{
> > > > +	security_add_hooks(evm_hooks, ARRAY_SIZE(evm_hooks), "integrity");
> > > > +}
> > > > +
> > > >  late_initcall(init_evm);
> > > > diff --git a/security/integrity/iint.c b/security/integrity/iint.c
> > > > index bbadf974b31..952d5ea4e18 100644
> > > > --- a/security/integrity/iint.c
> > > > +++ b/security/integrity/iint.c
> > > > @@ -179,12 +179,19 @@ static int __init integrity_lsm_init(void)
> > > >  			      0, SLAB_PANIC, init_once);
> > > >  
> > > >  	init_ima_lsm();
> > > > +	init_evm_lsm();
> > > >  	return 0;
> > > >  }
> > > > +
> > > > +struct lsm_blob_sizes integrity_blob_sizes __lsm_ro_after_init = {
> > > > +	.lbs_xattr = 1,
> > > Really? 1 byte? Don't even think of storing number of elements in lbs_xattr.
> > > The linux_blob_size structure contains sizes of blobs, not number of elements.
> > Oh, I see it can be confusing.
> > 
> > However, lbs_xattr does not help to position in the security blob but
> > in the new_xattrs array, allocated in security_inode_init_security()
> > (see below). Any suggestion on how to make this part better?
> 
> On further review, your current use is perfectly reasonable.
> The patch that introduces lbs_xattr (not in this set, I see)
> needs to document the use so other LSMs can use is correctly.

Ok, will add it.

So far, Paul's review should be the last.

Thanks

Roberto

> > Thanks
> > 
> > Roberto
> > 
> > > > +};
> > > > +
> > > >  DEFINE_LSM(integrity) = {
> > > >  	.name = "integrity",
> > > >  	.init = integrity_lsm_init,
> > > >  	.order = LSM_ORDER_LAST,
> > > > +	.blobs = &integrity_blob_sizes,
> > > >  };
> > > >  
> > > >  /*
> > > > diff --git a/security/integrity/integrity.h b/security/integrity/integrity.h
> > > > index c72d375a356..76e7eda6651 100644
> > > > --- a/security/integrity/integrity.h
> > > > +++ b/security/integrity/integrity.h
> > > > @@ -188,6 +188,7 @@ int integrity_kernel_read(struct file *file, loff_t offset,
> > > >  #define INTEGRITY_KEYRING_MAX		4
> > > >  
> > > >  extern struct dentry *integrity_dir;
> > > > +extern struct lsm_blob_sizes integrity_blob_sizes;
> > > >  
> > > >  struct modsig;
> > > >  
> > > > @@ -199,6 +200,14 @@ static inline void __init init_ima_lsm(void)
> > > >  }
> > > >  #endif
> > > >  
> > > > +#ifdef CONFIG_EVM
> > > > +void __init init_evm_lsm(void);
> > > > +#else
> > > > +static inline void __init init_evm_lsm(void)
> > > > +{
> > > > +}
> > > > +#endif
> > > > +
> > > >  #ifdef CONFIG_INTEGRITY_SIGNATURE
> > > >  
> > > >  int integrity_digsig_verify(const unsigned int id, const char *sig, int siglen,
> > > > diff --git a/security/security.c b/security/security.c
> > > > index 9bc6a4ef758..74abf04feef 100644
> > > > --- a/security/security.c
> > > > +++ b/security/security.c
> > > > @@ -20,13 +20,13 @@
> > > >  #include <linux/kernel_read_file.h>
> > > >  #include <linux/lsm_hooks.h>
> > > >  #include <linux/integrity.h>
> > > > -#include <linux/evm.h>
> > > >  #include <linux/fsnotify.h>
> > > >  #include <linux/mman.h>
> > > >  #include <linux/mount.h>
> > > >  #include <linux/personality.h>
> > > >  #include <linux/backing-dev.h>
> > > >  #include <linux/string.h>
> > > > +#include <linux/xattr.h>
> > > >  #include <linux/msg.h>
> > > >  #include <net/flow.h>
> > > >  
> > > > @@ -1662,8 +1662,8 @@ int security_inode_init_security(struct inode *inode, struct inode *dir,
> > > >  	if (!initxattrs)
> > > >  		return call_int_hook(inode_init_security, -EOPNOTSUPP, inode,
> > > >  				    dir, qstr, NULL);
> > > > -	/* Allocate +1 for EVM and +1 as terminator. */
> > > > -	new_xattrs = kcalloc(blob_sizes.lbs_xattr + 2, sizeof(*new_xattrs),
> > > > +	/* Allocate +1 for terminator. */
> > > > +	new_xattrs = kcalloc(blob_sizes.lbs_xattr + 1, sizeof(*new_xattrs),
> > > >  			     GFP_NOFS);
> > > >  	if (!new_xattrs)
> > > >  		return -ENOMEM;
> > > > @@ -1699,9 +1699,6 @@ int security_inode_init_security(struct inode *inode, struct inode *dir,
> > > >  	if (!num_filled_xattrs)
> > > >  		goto out;
> > > >  
> > > > -	ret = evm_inode_init_security(inode, dir, qstr, new_xattrs);
> > > > -	if (ret && ret != -EOPNOTSUPP)
> > > > -		goto out;
> > > >  	ret = initxattrs(inode, new_xattrs, fs_data);
> > > >  out:
> > > >  	for (xattr = new_xattrs; xattr->value != NULL; xattr++)
> > > > @@ -2201,14 +2198,9 @@ int security_inode_permission(struct inode *inode, int mask)
> > > >  int security_inode_setattr(struct mnt_idmap *idmap,
> > > >  			   struct dentry *dentry, struct iattr *attr)
> > > >  {
> > > > -	int ret;
> > > > -
> > > >  	if (unlikely(IS_PRIVATE(d_backing_inode(dentry))))
> > > >  		return 0;
> > > > -	ret = call_int_hook(inode_setattr, 0, idmap, dentry, attr);
> > > > -	if (ret)
> > > > -		return ret;
> > > > -	return evm_inode_setattr(idmap, dentry, attr);
> > > > +	return call_int_hook(inode_setattr, 0, idmap, dentry, attr);
> > > >  }
> > > >  EXPORT_SYMBOL_GPL(security_inode_setattr);
> > > >  
> > > > @@ -2272,9 +2264,7 @@ int security_inode_setxattr(struct mnt_idmap *idmap,
> > > >  
> > > >  	if (ret == 1)
> > > >  		ret = cap_inode_setxattr(dentry, name, value, size, flags);
> > > > -	if (ret)
> > > > -		return ret;
> > > > -	return evm_inode_setxattr(idmap, dentry, name, value, size, flags);
> > > > +	return ret;
> > > >  }
> > > >  
> > > >  /**
> > > > @@ -2293,15 +2283,10 @@ int security_inode_set_acl(struct mnt_idmap *idmap,
> > > >  			   struct dentry *dentry, const char *acl_name,
> > > >  			   struct posix_acl *kacl)
> > > >  {
> > > > -	int ret;
> > > > -
> > > >  	if (unlikely(IS_PRIVATE(d_backing_inode(dentry))))
> > > >  		return 0;
> > > > -	ret = call_int_hook(inode_set_acl, 0, idmap, dentry, acl_name,
> > > > -			    kacl);
> > > > -	if (ret)
> > > > -		return ret;
> > > > -	return evm_inode_set_acl(idmap, dentry, acl_name, kacl);
> > > > +	return call_int_hook(inode_set_acl, 0, idmap, dentry, acl_name,
> > > > +			     kacl);
> > > >  }
> > > >  
> > > >  /**
> > > > @@ -2354,14 +2339,9 @@ int security_inode_get_acl(struct mnt_idmap *idmap,
> > > >  int security_inode_remove_acl(struct mnt_idmap *idmap,
> > > >  			      struct dentry *dentry, const char *acl_name)
> > > >  {
> > > > -	int ret;
> > > > -
> > > >  	if (unlikely(IS_PRIVATE(d_backing_inode(dentry))))
> > > >  		return 0;
> > > > -	ret = call_int_hook(inode_remove_acl, 0, idmap, dentry, acl_name);
> > > > -	if (ret)
> > > > -		return ret;
> > > > -	return evm_inode_remove_acl(idmap, dentry, acl_name);
> > > > +	return call_int_hook(inode_remove_acl, 0, idmap, dentry, acl_name);
> > > >  }
> > > >  
> > > >  /**
> > > > @@ -2397,7 +2377,6 @@ void security_inode_post_setxattr(struct dentry *dentry, const char *name,
> > > >  	if (unlikely(IS_PRIVATE(d_backing_inode(dentry))))
> > > >  		return;
> > > >  	call_void_hook(inode_post_setxattr, dentry, name, value, size, flags);
> > > > -	evm_inode_post_setxattr(dentry, name, value, size, flags);
> > > >  }
> > > >  
> > > >  /**
> > > > @@ -2458,9 +2437,7 @@ int security_inode_removexattr(struct mnt_idmap *idmap,
> > > >  	ret = call_int_hook(inode_removexattr, 1, idmap, dentry, name);
> > > >  	if (ret == 1)
> > > >  		ret = cap_inode_removexattr(idmap, dentry, name);
> > > > -	if (ret)
> > > > -		return ret;
> > > > -	return evm_inode_removexattr(idmap, dentry, name);
> > > > +	return ret;
> > > >  }
> > > >  
> > > >  /**


^ permalink raw reply	[flat|nested] 79+ messages in thread

* Re: [PATCH 22/28] security: Introduce key_post_create_or_update hook
  2023-03-03 18:18 ` [PATCH 22/28] security: Introduce key_post_create_or_update hook Roberto Sassu
@ 2023-03-07 17:48   ` Stefan Berger
  2023-03-08 15:49   ` Mimi Zohar
  1 sibling, 0 replies; 79+ messages in thread
From: Stefan Berger @ 2023-03-07 17:48 UTC (permalink / raw)
  To: Roberto Sassu, viro, chuck.lever, jlayton, zohar,
	dmitry.kasatkin, paul, jmorris, serge, dhowells, jarkko,
	stephen.smalley.work, eparis, casey, brauner
  Cc: linux-fsdevel, linux-nfs, linux-integrity, linux-security-module,
	keyrings, selinux, linux-kernel, Roberto Sassu



On 3/3/23 13:18, Roberto Sassu wrote:
> From: Roberto Sassu <roberto.sassu@huawei.com>
> 
> In preparation for moving IMA and EVM to the LSM infrastructure, introduce
> the key_post_create_or_update hook.
> 
> Signed-off-by: Roberto Sassu <roberto.sassu@huawei.com>

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

^ permalink raw reply	[flat|nested] 79+ messages in thread

* Re: [PATCH 23/28] security: Introduce LSM_ORDER_LAST
  2023-03-03 18:25 ` [PATCH 23/28] security: Introduce LSM_ORDER_LAST Roberto Sassu
@ 2023-03-07 18:04   ` Stefan Berger
  2023-03-08  8:06     ` Roberto Sassu
  2023-03-08 13:13   ` Mimi Zohar
  1 sibling, 1 reply; 79+ messages in thread
From: Stefan Berger @ 2023-03-07 18:04 UTC (permalink / raw)
  To: Roberto Sassu, viro, chuck.lever, jlayton, zohar,
	dmitry.kasatkin, paul, jmorris, serge, dhowells, jarkko,
	stephen.smalley.work, eparis, casey, brauner
  Cc: linux-fsdevel, linux-nfs, linux-integrity, linux-security-module,
	keyrings, selinux, linux-kernel, Roberto Sassu



On 3/3/23 13:25, Roberto Sassu wrote:
> From: Roberto Sassu <roberto.sassu@huawei.com>
> 
> Introduce LSM_ORDER_LAST, to satisfy the requirement of LSMs willing to be
> the last, e.g. the 'integrity' LSM, without changing the kernel command
> line or configuration.
> 
> As for LSM_ORDER_FIRST, LSMs with LSM_ORDER_LAST are always enabled and put
> at the end of the LSM list in no particular order.
> 

I think you should describe the reason for the change for LSM_ORDER_MUTABLE as well.


> Signed-off-by: Roberto Sassu <roberto.sassu@huawei.com>
> ---
>   include/linux/lsm_hooks.h |  1 +
>   security/security.c       | 12 +++++++++---
>   2 files changed, 10 insertions(+), 3 deletions(-)
> 
> diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h
> index 21a8ce23108..05c4b831d99 100644
> --- a/include/linux/lsm_hooks.h
> +++ b/include/linux/lsm_hooks.h
> @@ -93,6 +93,7 @@ extern void security_add_hooks(struct security_hook_list *hooks, int count,
>   enum lsm_order {
>   	LSM_ORDER_FIRST = -1,	/* This is only for capabilities. */
>   	LSM_ORDER_MUTABLE = 0,
> +	LSM_ORDER_LAST = 1,
>   };
>   
>   struct lsm_info {
> diff --git a/security/security.c b/security/security.c
> index 322090a50cd..24f52ba3218 100644
> --- a/security/security.c
> +++ b/security/security.c
> @@ -284,9 +284,9 @@ static void __init ordered_lsm_parse(const char *order, const char *origin)
>   		bool found = false;
>   
>   		for (lsm = __start_lsm_info; lsm < __end_lsm_info; lsm++) {
> -			if (lsm->order == LSM_ORDER_MUTABLE &&
> -			    strcmp(lsm->name, name) == 0) {
> -				append_ordered_lsm(lsm, origin);
> +			if (strcmp(lsm->name, name) == 0) {
> +				if (lsm->order == LSM_ORDER_MUTABLE)
> +					append_ordered_lsm(lsm, origin);
>   				found = true;
>   			}
>   		}
> @@ -306,6 +306,12 @@ static void __init ordered_lsm_parse(const char *order, const char *origin)
>   		}
>   	}
>   
> +	/* LSM_ORDER_LAST is always last. */
> +	for (lsm = __start_lsm_info; lsm < __end_lsm_info; lsm++) {
> +		if (lsm->order == LSM_ORDER_LAST)
> +			append_ordered_lsm(lsm, "   last");
> +	}
> +
>   	/* Disable all LSMs not in the ordered list. */
>   	for (lsm = __start_lsm_info; lsm < __end_lsm_info; lsm++) {
>   		if (exists_ordered_lsm(lsm))

^ permalink raw reply	[flat|nested] 79+ messages in thread

* Re: [PATCH 23/28] security: Introduce LSM_ORDER_LAST
  2023-03-07 18:04   ` Stefan Berger
@ 2023-03-08  8:06     ` Roberto Sassu
  0 siblings, 0 replies; 79+ messages in thread
From: Roberto Sassu @ 2023-03-08  8:06 UTC (permalink / raw)
  To: Stefan Berger, viro, chuck.lever, jlayton, zohar,
	dmitry.kasatkin, paul, jmorris, serge, dhowells, jarkko,
	stephen.smalley.work, eparis, casey, brauner
  Cc: linux-fsdevel, linux-nfs, linux-integrity, linux-security-module,
	keyrings, selinux, linux-kernel, Roberto Sassu

On Tue, 2023-03-07 at 13:04 -0500, Stefan Berger wrote:
> 
> On 3/3/23 13:25, Roberto Sassu wrote:
> > From: Roberto Sassu <roberto.sassu@huawei.com>
> > 
> > Introduce LSM_ORDER_LAST, to satisfy the requirement of LSMs willing to be
> > the last, e.g. the 'integrity' LSM, without changing the kernel command
> > line or configuration.
> > 
> > As for LSM_ORDER_FIRST, LSMs with LSM_ORDER_LAST are always enabled and put
> > at the end of the LSM list in no particular order.
> > 
> 
> I think you should describe the reason for the change for LSM_ORDER_MUTABLE as well.

Right.

Thanks

Roberto

> > Signed-off-by: Roberto Sassu <roberto.sassu@huawei.com>
> > ---
> >   include/linux/lsm_hooks.h |  1 +
> >   security/security.c       | 12 +++++++++---
> >   2 files changed, 10 insertions(+), 3 deletions(-)
> > 
> > diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h
> > index 21a8ce23108..05c4b831d99 100644
> > --- a/include/linux/lsm_hooks.h
> > +++ b/include/linux/lsm_hooks.h
> > @@ -93,6 +93,7 @@ extern void security_add_hooks(struct security_hook_list *hooks, int count,
> >   enum lsm_order {
> >   	LSM_ORDER_FIRST = -1,	/* This is only for capabilities. */
> >   	LSM_ORDER_MUTABLE = 0,
> > +	LSM_ORDER_LAST = 1,
> >   };
> >   
> >   struct lsm_info {
> > diff --git a/security/security.c b/security/security.c
> > index 322090a50cd..24f52ba3218 100644
> > --- a/security/security.c
> > +++ b/security/security.c
> > @@ -284,9 +284,9 @@ static void __init ordered_lsm_parse(const char *order, const char *origin)
> >   		bool found = false;
> >   
> >   		for (lsm = __start_lsm_info; lsm < __end_lsm_info; lsm++) {
> > -			if (lsm->order == LSM_ORDER_MUTABLE &&
> > -			    strcmp(lsm->name, name) == 0) {
> > -				append_ordered_lsm(lsm, origin);
> > +			if (strcmp(lsm->name, name) == 0) {
> > +				if (lsm->order == LSM_ORDER_MUTABLE)
> > +					append_ordered_lsm(lsm, origin);
> >   				found = true;
> >   			}
> >   		}
> > @@ -306,6 +306,12 @@ static void __init ordered_lsm_parse(const char *order, const char *origin)
> >   		}
> >   	}
> >   
> > +	/* LSM_ORDER_LAST is always last. */
> > +	for (lsm = __start_lsm_info; lsm < __end_lsm_info; lsm++) {
> > +		if (lsm->order == LSM_ORDER_LAST)
> > +			append_ordered_lsm(lsm, "   last");
> > +	}
> > +
> >   	/* Disable all LSMs not in the ordered list. */
> >   	for (lsm = __start_lsm_info; lsm < __end_lsm_info; lsm++) {
> >   		if (exists_ordered_lsm(lsm))


^ permalink raw reply	[flat|nested] 79+ messages in thread

* Re: [PATCH 23/28] security: Introduce LSM_ORDER_LAST
  2023-03-03 18:25 ` [PATCH 23/28] security: Introduce LSM_ORDER_LAST Roberto Sassu
  2023-03-07 18:04   ` Stefan Berger
@ 2023-03-08 13:13   ` Mimi Zohar
  2023-03-08 13:26     ` Roberto Sassu
  1 sibling, 1 reply; 79+ messages in thread
From: Mimi Zohar @ 2023-03-08 13:13 UTC (permalink / raw)
  To: Roberto Sassu, viro, chuck.lever, jlayton, dmitry.kasatkin, paul,
	jmorris, serge, dhowells, jarkko, stephen.smalley.work, eparis,
	casey, brauner
  Cc: linux-fsdevel, linux-nfs, linux-integrity, linux-security-module,
	keyrings, selinux, linux-kernel, stefanb, Roberto Sassu

Hi Roberto,

On Fri, 2023-03-03 at 19:25 +0100, Roberto Sassu wrote:
> From: Roberto Sassu <roberto.sassu@huawei.com>
> 
> Introduce LSM_ORDER_LAST, to satisfy the requirement of LSMs willing to be
> the last, e.g. the 'integrity' LSM, without changing the kernel command
> line or configuration.

Please reframe this as a bug fix for 79f7865d844c ("LSM: Introduce
"lsm=" for boottime LSM selection") and upstream it first, with
'integrity' as the last LSM.   The original bug fix commit 92063f3ca73a
("integrity: double check iint_cache was initialized") could then be
removed.

> 
> As for LSM_ORDER_FIRST, LSMs with LSM_ORDER_LAST are always enabled and put
> at the end of the LSM list in no particular order.

^Similar to LSM_ORDER_FIRST ...

And remove "in no particular order".

> 
> Signed-off-by: Roberto Sassu <roberto.sassu@huawei.com>
> ---
>  include/linux/lsm_hooks.h |  1 +
>  security/security.c       | 12 +++++++++---
>  2 files changed, 10 insertions(+), 3 deletions(-)
> 
> diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h
> index 21a8ce23108..05c4b831d99 100644
> --- a/include/linux/lsm_hooks.h
> +++ b/include/linux/lsm_hooks.h
> @@ -93,6 +93,7 @@ extern void security_add_hooks(struct security_hook_list *hooks, int count,
>  enum lsm_order {
>  	LSM_ORDER_FIRST = -1,	/* This is only for capabilities. */
>  	LSM_ORDER_MUTABLE = 0,
> +	LSM_ORDER_LAST = 1,
>  };
>  
>  struct lsm_info {
> diff --git a/security/security.c b/security/security.c
> index 322090a50cd..24f52ba3218 100644
> --- a/security/security.c
> +++ b/security/security.c
> @@ -284,9 +284,9 @@ static void __init ordered_lsm_parse(const char *order, const char *origin)
>  		bool found = false;
>  
>  		for (lsm = __start_lsm_info; lsm < __end_lsm_info; lsm++) {
> -			if (lsm->order == LSM_ORDER_MUTABLE &&
> -			    strcmp(lsm->name, name) == 0) {
> -				append_ordered_lsm(lsm, origin);
> +			if (strcmp(lsm->name, name) == 0) {
> +				if (lsm->order == LSM_ORDER_MUTABLE)
> +					append_ordered_lsm(lsm, origin);
>  				found = true;
>  			}
>  		}
> @@ -306,6 +306,12 @@ static void __init ordered_lsm_parse(const char *order, const char *origin)
>  		}
>  	}
>  
> +	/* LSM_ORDER_LAST is always last. */
> +	for (lsm = __start_lsm_info; lsm < __end_lsm_info; lsm++) {
> +		if (lsm->order == LSM_ORDER_LAST)
> +			append_ordered_lsm(lsm, "   last");
> +	}
> +
>  	/* Disable all LSMs not in the ordered list. */
>  	for (lsm = __start_lsm_info; lsm < __end_lsm_info; lsm++) {
>  		if (exists_ordered_lsm(lsm))

-- 
thanks,

Mimi


^ permalink raw reply	[flat|nested] 79+ messages in thread

* Re: [PATCH 23/28] security: Introduce LSM_ORDER_LAST
  2023-03-08 13:13   ` Mimi Zohar
@ 2023-03-08 13:26     ` Roberto Sassu
  2023-03-08 14:00       ` Mimi Zohar
  0 siblings, 1 reply; 79+ messages in thread
From: Roberto Sassu @ 2023-03-08 13:26 UTC (permalink / raw)
  To: Mimi Zohar, viro, chuck.lever, jlayton, dmitry.kasatkin, paul,
	jmorris, serge, dhowells, jarkko, stephen.smalley.work, eparis,
	casey, brauner
  Cc: linux-fsdevel, linux-nfs, linux-integrity, linux-security-module,
	keyrings, selinux, linux-kernel, stefanb, Roberto Sassu

On Wed, 2023-03-08 at 08:13 -0500, Mimi Zohar wrote:
> Hi Roberto,
> 
> On Fri, 2023-03-03 at 19:25 +0100, Roberto Sassu wrote:
> > From: Roberto Sassu <roberto.sassu@huawei.com>
> > 
> > Introduce LSM_ORDER_LAST, to satisfy the requirement of LSMs willing to be
> > the last, e.g. the 'integrity' LSM, without changing the kernel command
> > line or configuration.
> 
> Please reframe this as a bug fix for 79f7865d844c ("LSM: Introduce
> "lsm=" for boottime LSM selection") and upstream it first, with
> 'integrity' as the last LSM.   The original bug fix commit 92063f3ca73a
> ("integrity: double check iint_cache was initialized") could then be
> removed.

Ok, I should complete the patch by checking the cache initialization in
iint.c.

> > As for LSM_ORDER_FIRST, LSMs with LSM_ORDER_LAST are always enabled and put
> > at the end of the LSM list in no particular order.
> 
> ^Similar to LSM_ORDER_FIRST ...
> 
> And remove "in no particular order".

The reason for this is that I originally thought that the relative
order of LSMs specified in the kernel configuration or the command line
was respected (if more than one LSM specifies LSM_ORDER_LAST). In fact
not. To do this, we would have to parse the LSM string again, as it is
done for LSM_ORDER_MUTABLE LSMs.

Thanks

Roberto

> > Signed-off-by: Roberto Sassu <roberto.sassu@huawei.com>
> > ---
> >  include/linux/lsm_hooks.h |  1 +
> >  security/security.c       | 12 +++++++++---
> >  2 files changed, 10 insertions(+), 3 deletions(-)
> > 
> > diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h
> > index 21a8ce23108..05c4b831d99 100644
> > --- a/include/linux/lsm_hooks.h
> > +++ b/include/linux/lsm_hooks.h
> > @@ -93,6 +93,7 @@ extern void security_add_hooks(struct security_hook_list *hooks, int count,
> >  enum lsm_order {
> >  	LSM_ORDER_FIRST = -1,	/* This is only for capabilities. */
> >  	LSM_ORDER_MUTABLE = 0,
> > +	LSM_ORDER_LAST = 1,
> >  };
> >  
> >  struct lsm_info {
> > diff --git a/security/security.c b/security/security.c
> > index 322090a50cd..24f52ba3218 100644
> > --- a/security/security.c
> > +++ b/security/security.c
> > @@ -284,9 +284,9 @@ static void __init ordered_lsm_parse(const char *order, const char *origin)
> >  		bool found = false;
> >  
> >  		for (lsm = __start_lsm_info; lsm < __end_lsm_info; lsm++) {
> > -			if (lsm->order == LSM_ORDER_MUTABLE &&
> > -			    strcmp(lsm->name, name) == 0) {
> > -				append_ordered_lsm(lsm, origin);
> > +			if (strcmp(lsm->name, name) == 0) {
> > +				if (lsm->order == LSM_ORDER_MUTABLE)
> > +					append_ordered_lsm(lsm, origin);
> >  				found = true;
> >  			}
> >  		}
> > @@ -306,6 +306,12 @@ static void __init ordered_lsm_parse(const char *order, const char *origin)
> >  		}
> >  	}
> >  
> > +	/* LSM_ORDER_LAST is always last. */
> > +	for (lsm = __start_lsm_info; lsm < __end_lsm_info; lsm++) {
> > +		if (lsm->order == LSM_ORDER_LAST)
> > +			append_ordered_lsm(lsm, "   last");
> > +	}
> > +
> >  	/* Disable all LSMs not in the ordered list. */
> >  	for (lsm = __start_lsm_info; lsm < __end_lsm_info; lsm++) {
> >  		if (exists_ordered_lsm(lsm))


^ permalink raw reply	[flat|nested] 79+ messages in thread

* Re: [PATCH 23/28] security: Introduce LSM_ORDER_LAST
  2023-03-08 13:26     ` Roberto Sassu
@ 2023-03-08 14:00       ` Mimi Zohar
  2023-03-08 14:35         ` Roberto Sassu
  0 siblings, 1 reply; 79+ messages in thread
From: Mimi Zohar @ 2023-03-08 14:00 UTC (permalink / raw)
  To: Roberto Sassu, viro, chuck.lever, jlayton, dmitry.kasatkin, paul,
	jmorris, serge, dhowells, jarkko, stephen.smalley.work, eparis,
	casey, brauner
  Cc: linux-fsdevel, linux-nfs, linux-integrity, linux-security-module,
	keyrings, selinux, linux-kernel, stefanb, Roberto Sassu

On Wed, 2023-03-08 at 14:26 +0100, Roberto Sassu wrote:
> On Wed, 2023-03-08 at 08:13 -0500, Mimi Zohar wrote:
> > Hi Roberto,
> > 
> > On Fri, 2023-03-03 at 19:25 +0100, Roberto Sassu wrote:
> > > From: Roberto Sassu <roberto.sassu@huawei.com>
> > > 
> > > Introduce LSM_ORDER_LAST, to satisfy the requirement of LSMs willing to be
> > > the last, e.g. the 'integrity' LSM, without changing the kernel command
> > > line or configuration.
> > 
> > Please reframe this as a bug fix for 79f7865d844c ("LSM: Introduce
> > "lsm=" for boottime LSM selection") and upstream it first, with
> > 'integrity' as the last LSM.   The original bug fix commit 92063f3ca73a
> > ("integrity: double check iint_cache was initialized") could then be
> > removed.
> 
> Ok, I should complete the patch by checking the cache initialization in
> iint.c.
> 
> > > As for LSM_ORDER_FIRST, LSMs with LSM_ORDER_LAST are always enabled and put
> > > at the end of the LSM list in no particular order.
> > 
> > ^Similar to LSM_ORDER_FIRST ...
> > 
> > And remove "in no particular order".
> 
> The reason for this is that I originally thought that the relative
> order of LSMs specified in the kernel configuration or the command line
> was respected (if more than one LSM specifies LSM_ORDER_LAST). In fact
> not. To do this, we would have to parse the LSM string again, as it is
> done for LSM_ORDER_MUTABLE LSMs.

IMA and EVM are only configurable if 'integrity' is enabled.  Similar
to how LSM_ORDER_FIRST is reserved for capabilities, LSM_ORDER_LAST
should be reserved for integrity (LSMs), if it is configured, for the
reason as described in the "[PATCH 24/28] ima: Move to LSM
infrastructure" patch description.

> 
> Thanks
> 
> Roberto
> 
> > > Signed-off-by: Roberto Sassu <roberto.sassu@huawei.com>
> > > ---
> > >  include/linux/lsm_hooks.h |  1 +
> > >  security/security.c       | 12 +++++++++---
> > >  2 files changed, 10 insertions(+), 3 deletions(-)
> > > 
> > > diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h
> > > index 21a8ce23108..05c4b831d99 100644
> > > --- a/include/linux/lsm_hooks.h
> > > +++ b/include/linux/lsm_hooks.h
> > > @@ -93,6 +93,7 @@ extern void security_add_hooks(struct security_hook_list *hooks, int count,
> > >  enum lsm_order {
> > >  	LSM_ORDER_FIRST = -1,	/* This is only for capabilities. */
> > >  	LSM_ORDER_MUTABLE = 0,
> > > +	LSM_ORDER_LAST = 1,
> > >  };
> > >  
> > >  struct lsm_info {
> > > diff --git a/security/security.c b/security/security.c
> > > index 322090a50cd..24f52ba3218 100644
> > > --- a/security/security.c
> > > +++ b/security/security.c
> > > @@ -284,9 +284,9 @@ static void __init ordered_lsm_parse(const char *order, const char *origin)
> > >  		bool found = false;
> > >  
> > >  		for (lsm = __start_lsm_info; lsm < __end_lsm_info; lsm++) {
> > > -			if (lsm->order == LSM_ORDER_MUTABLE &&
> > > -			    strcmp(lsm->name, name) == 0) {
> > > -				append_ordered_lsm(lsm, origin);
> > > +			if (strcmp(lsm->name, name) == 0) {
> > > +				if (lsm->order == LSM_ORDER_MUTABLE)
> > > +					append_ordered_lsm(lsm, origin);
> > >  				found = true;
> > >  			}
> > >  		}
> > > @@ -306,6 +306,12 @@ static void __init ordered_lsm_parse(const char *order, const char *origin)
> > >  		}
> > >  	}
> > >  
> > > +	/* LSM_ORDER_LAST is always last. */
> > > +	for (lsm = __start_lsm_info; lsm < __end_lsm_info; lsm++) {
> > > +		if (lsm->order == LSM_ORDER_LAST)
> > > +			append_ordered_lsm(lsm, "   last");
> > > +	}
> > > +
> > >  	/* Disable all LSMs not in the ordered list. */
> > >  	for (lsm = __start_lsm_info; lsm < __end_lsm_info; lsm++) {
> > >  		if (exists_ordered_lsm(lsm))
> 



^ permalink raw reply	[flat|nested] 79+ messages in thread

* Re: [PATCH 23/28] security: Introduce LSM_ORDER_LAST
  2023-03-08 14:00       ` Mimi Zohar
@ 2023-03-08 14:35         ` Roberto Sassu
  2023-03-08 15:52           ` Mimi Zohar
  0 siblings, 1 reply; 79+ messages in thread
From: Roberto Sassu @ 2023-03-08 14:35 UTC (permalink / raw)
  To: Mimi Zohar, viro, chuck.lever, jlayton, dmitry.kasatkin, paul,
	jmorris, serge, dhowells, jarkko, stephen.smalley.work, eparis,
	casey, brauner
  Cc: linux-fsdevel, linux-nfs, linux-integrity, linux-security-module,
	keyrings, selinux, linux-kernel, stefanb, Roberto Sassu

On Wed, 2023-03-08 at 09:00 -0500, Mimi Zohar wrote:
> On Wed, 2023-03-08 at 14:26 +0100, Roberto Sassu wrote:
> > On Wed, 2023-03-08 at 08:13 -0500, Mimi Zohar wrote:
> > > Hi Roberto,
> > > 
> > > On Fri, 2023-03-03 at 19:25 +0100, Roberto Sassu wrote:
> > > > From: Roberto Sassu <roberto.sassu@huawei.com>
> > > > 
> > > > Introduce LSM_ORDER_LAST, to satisfy the requirement of LSMs willing to be
> > > > the last, e.g. the 'integrity' LSM, without changing the kernel command
> > > > line or configuration.
> > > 
> > > Please reframe this as a bug fix for 79f7865d844c ("LSM: Introduce
> > > "lsm=" for boottime LSM selection") and upstream it first, with
> > > 'integrity' as the last LSM.   The original bug fix commit 92063f3ca73a
> > > ("integrity: double check iint_cache was initialized") could then be
> > > removed.
> > 
> > Ok, I should complete the patch by checking the cache initialization in
> > iint.c.
> > 
> > > > As for LSM_ORDER_FIRST, LSMs with LSM_ORDER_LAST are always enabled and put
> > > > at the end of the LSM list in no particular order.
> > > 
> > > ^Similar to LSM_ORDER_FIRST ...
> > > 
> > > And remove "in no particular order".
> > 
> > The reason for this is that I originally thought that the relative
> > order of LSMs specified in the kernel configuration or the command line
> > was respected (if more than one LSM specifies LSM_ORDER_LAST). In fact
> > not. To do this, we would have to parse the LSM string again, as it is
> > done for LSM_ORDER_MUTABLE LSMs.
> 
> IMA and EVM are only configurable if 'integrity' is enabled.  Similar
> to how LSM_ORDER_FIRST is reserved for capabilities, LSM_ORDER_LAST
> should be reserved for integrity (LSMs), if it is configured, for the
> reason as described in the "[PATCH 24/28] ima: Move to LSM
> infrastructure" patch description.

Yes, it is just that nothing prevents to have multiple LSMs with order
LSM_ORDER_LAST. I guess we will enforce that it is only one by
reviewing the code.

Thanks

Roberto

> > Thanks
> > 
> > Roberto
> > 
> > > > Signed-off-by: Roberto Sassu <roberto.sassu@huawei.com>
> > > > ---
> > > >  include/linux/lsm_hooks.h |  1 +
> > > >  security/security.c       | 12 +++++++++---
> > > >  2 files changed, 10 insertions(+), 3 deletions(-)
> > > > 
> > > > diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h
> > > > index 21a8ce23108..05c4b831d99 100644
> > > > --- a/include/linux/lsm_hooks.h
> > > > +++ b/include/linux/lsm_hooks.h
> > > > @@ -93,6 +93,7 @@ extern void security_add_hooks(struct security_hook_list *hooks, int count,
> > > >  enum lsm_order {
> > > >  	LSM_ORDER_FIRST = -1,	/* This is only for capabilities. */
> > > >  	LSM_ORDER_MUTABLE = 0,
> > > > +	LSM_ORDER_LAST = 1,
> > > >  };
> > > >  
> > > >  struct lsm_info {
> > > > diff --git a/security/security.c b/security/security.c
> > > > index 322090a50cd..24f52ba3218 100644
> > > > --- a/security/security.c
> > > > +++ b/security/security.c
> > > > @@ -284,9 +284,9 @@ static void __init ordered_lsm_parse(const char *order, const char *origin)
> > > >  		bool found = false;
> > > >  
> > > >  		for (lsm = __start_lsm_info; lsm < __end_lsm_info; lsm++) {
> > > > -			if (lsm->order == LSM_ORDER_MUTABLE &&
> > > > -			    strcmp(lsm->name, name) == 0) {
> > > > -				append_ordered_lsm(lsm, origin);
> > > > +			if (strcmp(lsm->name, name) == 0) {
> > > > +				if (lsm->order == LSM_ORDER_MUTABLE)
> > > > +					append_ordered_lsm(lsm, origin);
> > > >  				found = true;
> > > >  			}
> > > >  		}
> > > > @@ -306,6 +306,12 @@ static void __init ordered_lsm_parse(const char *order, const char *origin)
> > > >  		}
> > > >  	}
> > > >  
> > > > +	/* LSM_ORDER_LAST is always last. */
> > > > +	for (lsm = __start_lsm_info; lsm < __end_lsm_info; lsm++) {
> > > > +		if (lsm->order == LSM_ORDER_LAST)
> > > > +			append_ordered_lsm(lsm, "   last");
> > > > +	}
> > > > +
> > > >  	/* Disable all LSMs not in the ordered list. */
> > > >  	for (lsm = __start_lsm_info; lsm < __end_lsm_info; lsm++) {
> > > >  		if (exists_ordered_lsm(lsm))


^ permalink raw reply	[flat|nested] 79+ messages in thread

* Re: [PATCH 00/28] security: Move IMA and EVM to the LSM infrastructure
  2023-03-03 18:18 [PATCH 00/28] security: Move IMA and EVM to the LSM infrastructure Roberto Sassu
                   ` (27 preceding siblings ...)
  2023-03-03 18:26 ` [PATCH 28/28] integrity: Switch from rbtree to LSM-managed blob for integrity_iint_cache Roberto Sassu
@ 2023-03-08 15:14 ` Mimi Zohar
  2023-03-08 16:23   ` Roberto Sassu
  28 siblings, 1 reply; 79+ messages in thread
From: Mimi Zohar @ 2023-03-08 15:14 UTC (permalink / raw)
  To: Roberto Sassu, viro, chuck.lever, jlayton, dmitry.kasatkin, paul,
	jmorris, serge, dhowells, jarkko, stephen.smalley.work, eparis,
	casey, brauner
  Cc: linux-fsdevel, linux-nfs, linux-integrity, linux-security-module,
	keyrings, selinux, linux-kernel, stefanb, Roberto Sassu

Hi Roberto,

On Fri, 2023-03-03 at 19:18 +0100, Roberto Sassu wrote:
> From: Roberto Sassu <roberto.sassu@huawei.com>
> 
> This patch set depends on:
> - https://lore.kernel.org/linux-integrity/20221201104125.919483-1-roberto.sassu@huaweicloud.com/ (there will be a v8 shortly)
> - https://lore.kernel.org/linux-security-module/20230217032625.678457-1-paul@paul-moore.com/
> 
> IMA and EVM are not effectively LSMs, especially due the fact that in the
> past they could not provide a security blob while there is another LSM
> active.
> 
> That changed in the recent years, the LSM stacking feature now makes it
> possible to stack together multiple LSMs, and allows them to provide a
> security blob for most kernel objects. While the LSM stacking feature has
> some limitations being worked out, it is already suitable to make IMA and
> EVM as LSMs.
> 
> In short, while this patch set is big, it does not make any functional
> change to IMA and EVM. IMA and EVM functions are called by the LSM
> infrastructure in the same places as before (except ima_post_path_mknod()),
> rather being hardcoded calls, and the inode metadata pointer is directly
> stored in the inode security blob rather than in a separate rbtree.
> 
> More specifically, patches 1-13 make IMA and EVM functions suitable to
> be registered to the LSM infrastructure, by aligning function parameters.
> 
> Patches 14-22 add new LSM hooks in the same places where IMA and EVM
> functions are called, if there is no LSM hook already.
> 
> Patch 23 adds the 'last' ordering strategy for LSMs, so that IMA and EVM
> functions are called in the same order as of today. Also, like with the
> 'first' strategy, LSMs using it are always enabled, so IMA and EVM
> functions will be always called (if IMA and EVM are compiled built-in).
> 
> Patches 24-27 do the bulk of the work, remove hardcoded calls to IMA and
> EVM functions, register those functions in the LSM infrastructure, and let
> the latter call them. In addition, they also reserve one slot for EVM to 
> supply an xattr to the inode_init_security hook.
> 
> Finally, patch 28 removes the rbtree used to bind metadata to the inodes,
> and instead reserve a space in the inode security blob to store the pointer
> to metadata. This also brings performance improvements due to retrieving
> metadata in constant time, as opposed to logarithmic.

Prior to IMA being upstreamed, it went through a number of iterations,
first on the security hooks, then as a separate parallel set of
integrity hooks, and, finally, co-located with the security hooks,
where they exist.  With this patch set we've come full circle.

With the LSM stacking support, multiple LSMs can now use the
'i_security' field removing the need for the rbtree indirection for
accessing integrity state info.

Roberto, thank you for making this change.  Mostly it looks good.  
Reviewing the patch set will be easier once the prereq's and this patch
set can be properly applied.

-- 
thanks,

Mimi


^ permalink raw reply	[flat|nested] 79+ messages in thread

* Re: [PATCH 03/28] ima: Align ima_post_create_tmpfile() definition with LSM infrastructure
  2023-03-03 18:18 ` [PATCH 03/28] ima: Align ima_post_create_tmpfile() " Roberto Sassu
  2023-03-06 16:53   ` Stefan Berger
@ 2023-03-08 15:15   ` Mimi Zohar
  2023-03-09  9:11     ` Roberto Sassu
  1 sibling, 1 reply; 79+ messages in thread
From: Mimi Zohar @ 2023-03-08 15:15 UTC (permalink / raw)
  To: Roberto Sassu, viro, chuck.lever, jlayton, dmitry.kasatkin, paul,
	jmorris, serge, dhowells, jarkko, stephen.smalley.work, eparis,
	casey, brauner
  Cc: linux-fsdevel, linux-nfs, linux-integrity, linux-security-module,
	keyrings, selinux, linux-kernel, stefanb, Roberto Sassu

Hi Roberto,

On Fri, 2023-03-03 at 19:18 +0100, Roberto Sassu wrote:
> From: Roberto Sassu <roberto.sassu@huawei.com>
> 
> Change ima_post_create_tmpfile() definition, so that it can be registered
> as implementation of the post_create_tmpfile hook.

Since neither security_create_tmpfile() nor
security_post_create_tmpfile() already exist, why not pass a pointer to
the file to conform to the other file related security hooks?

Mimi

> 
> Signed-off-by: Roberto Sassu <roberto.sassu@huawei.com>
> ---
>  fs/namei.c                        | 2 +-
>  include/linux/ima.h               | 7 +++++--
>  security/integrity/ima/ima_main.c | 8 ++++++--
>  3 files changed, 12 insertions(+), 5 deletions(-)
> 
> diff --git a/fs/namei.c b/fs/namei.c
> index b5a1ec29193..57727a1ae38 100644
> --- a/fs/namei.c
> +++ b/fs/namei.c
> @@ -3622,7 +3622,7 @@ static int vfs_tmpfile(struct mnt_idmap *idmap,
>  		inode->i_state |= I_LINKABLE;
>  		spin_unlock(&inode->i_lock);
>  	}
> -	ima_post_create_tmpfile(idmap, inode);
> +	ima_post_create_tmpfile(idmap, dir, file_dentry(file), mode);
>  	return 0;
>  }
>  
> diff --git a/include/linux/ima.h b/include/linux/ima.h
> index 179ce52013b..7535686a403 100644
> --- a/include/linux/ima.h
> +++ b/include/linux/ima.h
> @@ -19,7 +19,8 @@ extern enum hash_algo ima_get_current_hash_algo(void);
>  extern int ima_bprm_check(struct linux_binprm *bprm);
>  extern int ima_file_check(struct file *file, int mask);
>  extern void ima_post_create_tmpfile(struct mnt_idmap *idmap,
> -				    struct inode *inode);
> +				    struct inode *dir, struct dentry *dentry,
> +				    umode_t mode);
>  extern void ima_file_free(struct file *file);
>  extern int ima_file_mmap(struct file *file, unsigned long reqprot,
>  			 unsigned long prot, unsigned long flags);
> @@ -69,7 +70,9 @@ static inline int ima_file_check(struct file *file, int mask)
>  }
>  
>  static inline void ima_post_create_tmpfile(struct mnt_idmap *idmap,
> -					   struct inode *inode)
> +					   struct inode *dir,
> +					   struct dentry *dentry,
> +					   umode_t mode)
>  {
>  }
>  
> diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c
> index 8941305376b..4a3d0c8bcba 100644
> --- a/security/integrity/ima/ima_main.c
> +++ b/security/integrity/ima/ima_main.c
> @@ -659,16 +659,20 @@ EXPORT_SYMBOL_GPL(ima_inode_hash);
>  /**
>   * ima_post_create_tmpfile - mark newly created tmpfile as new
>   * @idmap: idmap of the mount the inode was found from
> - * @inode: inode of the newly created tmpfile
> + * @dir: inode structure of the parent of the new file
> + * @dentry: dentry structure of the new file
> + * @mode: mode of the new file
>   *
>   * No measuring, appraising or auditing of newly created tmpfiles is needed.
>   * Skip calling process_measurement(), but indicate which newly, created
>   * tmpfiles are in policy.
>   */
>  void ima_post_create_tmpfile(struct mnt_idmap *idmap,
> -			     struct inode *inode)
> +			     struct inode *dir, struct dentry *dentry,
> +			     umode_t mode)
>  {
>  	struct integrity_iint_cache *iint;
> +	struct inode *inode = dentry->d_inode;
>  	int must_appraise;
>  
>  	if (!ima_policy_flag || !S_ISREG(inode->i_mode))



^ permalink raw reply	[flat|nested] 79+ messages in thread

* Re: [PATCH 14/28] security: Introduce inode_post_setattr hook
  2023-03-03 18:18 ` [PATCH 14/28] security: Introduce inode_post_setattr hook Roberto Sassu
  2023-03-06 17:08   ` Stefan Berger
@ 2023-03-08 15:19   ` Mimi Zohar
  1 sibling, 0 replies; 79+ messages in thread
From: Mimi Zohar @ 2023-03-08 15:19 UTC (permalink / raw)
  To: Roberto Sassu, viro, chuck.lever, jlayton, dmitry.kasatkin, paul,
	jmorris, serge, dhowells, jarkko, stephen.smalley.work, eparis,
	casey, brauner
  Cc: linux-fsdevel, linux-nfs, linux-integrity, linux-security-module,
	keyrings, selinux, linux-kernel, stefanb, Roberto Sassu

Hi Roberto,

On Fri, 2023-03-03 at 19:18 +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_setattr hook.
> 
> Signed-off-by: Roberto Sassu <roberto.sassu@huawei.com>

Other than the one minor comment below,

Reviewed-by: Mimi Zohar <zohar@linux.ibm.com>
> ---
>  fs/attr.c                     |  1 +
>  include/linux/lsm_hook_defs.h |  2 ++
>  include/linux/security.h      |  7 +++++++
>  security/security.c           | 16 ++++++++++++++++
>  4 files changed, 26 insertions(+)
> 
> diff --git a/fs/attr.c b/fs/attr.c
> index da45cf01be6..343d6d62435 100644
> --- a/fs/attr.c
> +++ b/fs/attr.c
> @@ -485,6 +485,7 @@ int notify_change(struct mnt_idmap *idmap, struct dentry *dentry,
>  
>  	if (!error) {
>  		fsnotify_change(dentry, ia_valid);
> +		security_inode_post_setattr(idmap, dentry, ia_valid);
>  		ima_inode_post_setattr(idmap, dentry, ia_valid);
>  		evm_inode_post_setattr(idmap, dentry, ia_valid);
>  	}
> diff --git a/include/linux/lsm_hook_defs.h b/include/linux/lsm_hook_defs.h
> index 4372a6b2632..eedefbcdde3 100644
> --- a/include/linux/lsm_hook_defs.h
> +++ b/include/linux/lsm_hook_defs.h
> @@ -135,6 +135,8 @@ LSM_HOOK(int, 0, inode_follow_link, struct dentry *dentry, struct inode *inode,
>  LSM_HOOK(int, 0, inode_permission, struct inode *inode, int mask)
>  LSM_HOOK(int, 0, inode_setattr, struct mnt_idmap *idmap, struct dentry *dentry,
>  	 struct iattr *attr)
> +LSM_HOOK(void, LSM_RET_VOID, inode_post_setattr, struct mnt_idmap *idmap,
> +	 struct dentry *dentry, int ia_valid)
>  LSM_HOOK(int, 0, inode_getattr, const struct path *path)
>  LSM_HOOK(int, 0, inode_setxattr, struct mnt_idmap *idmap,
>  	 struct dentry *dentry, const char *name, const void *value,
> diff --git a/include/linux/security.h b/include/linux/security.h
> index cd23221ce9e..64224216f6c 100644
> --- a/include/linux/security.h
> +++ b/include/linux/security.h
> @@ -354,6 +354,8 @@ int security_inode_follow_link(struct dentry *dentry, struct inode *inode,
>  int security_inode_permission(struct inode *inode, int mask);
>  int security_inode_setattr(struct mnt_idmap *idmap,
>  			   struct dentry *dentry, struct iattr *attr);
> +void security_inode_post_setattr(struct mnt_idmap *idmap, struct dentry *dentry,
> +				 int ia_valid);
>  int security_inode_getattr(const struct path *path);
>  int security_inode_setxattr(struct mnt_idmap *idmap,
>  			    struct dentry *dentry, const char *name,
> @@ -855,6 +857,11 @@ static inline int security_inode_setattr(struct mnt_idmap *idmap,
>  	return 0;
>  }
>  
> +static inline void
> +security_inode_post_setattr(struct mnt_idmap *idmap, struct dentry *dentry,
> +			    int ia_valid)
> +{ }
> +
>  static inline int security_inode_getattr(const struct path *path)
>  {
>  	return 0;
> diff --git a/security/security.c b/security/security.c
> index f7fe252e9d3..2dbf225f5d8 100644
> --- a/security/security.c
> +++ b/security/security.c
> @@ -2190,6 +2190,22 @@ int security_inode_getattr(const struct path *path)
>  	return call_int_hook(inode_getattr, 0, path);
>  }
>  

Like the definitions, move the security_inode_post_setattr() to after
security_inode_setattr().

> +/**
> + * security_inode_post_setattr() - Update the inode after a setattr operation
> + * @idmap: idmap of the mount
> + * @dentry: file
> + * @ia_valid: file attributes set
> + *
> + * Update inode security field after successful setting file attributes.
> + */
> +void security_inode_post_setattr(struct mnt_idmap *idmap, struct dentry *entry,
> +				 int ia_valid)
> +{
> +	if (unlikely(IS_PRIVATE(d_backing_inode(dentry))))
> +		return;
> +	call_void_hook(inode_post_setattr, idmap, dentry, ia_valid);
> +}
> +
>  /**
>   * security_inode_setxattr() - Check if setting file xattrs is allowed
>   * @idmap: idmap of the mounth

-- 
thanks,

Mimi


^ permalink raw reply	[flat|nested] 79+ messages in thread

* Re: [PATCH 15/28] security: Introduce inode_post_removexattr hook
  2023-03-03 18:18 ` [PATCH 15/28] security: Introduce inode_post_removexattr hook Roberto Sassu
  2023-03-06 19:17   ` Stefan Berger
@ 2023-03-08 15:43   ` Mimi Zohar
  2023-03-09 13:07     ` Roberto Sassu
  2023-08-30  9:31     ` Roberto Sassu
  1 sibling, 2 replies; 79+ messages in thread
From: Mimi Zohar @ 2023-03-08 15:43 UTC (permalink / raw)
  To: Roberto Sassu, viro, chuck.lever, jlayton, dmitry.kasatkin, paul,
	jmorris, serge, dhowells, jarkko, stephen.smalley.work, eparis,
	casey, brauner
  Cc: linux-fsdevel, linux-nfs, linux-integrity, linux-security-module,
	keyrings, selinux, linux-kernel, stefanb, Roberto Sassu

Hi Roberto,

On Fri, 2023-03-03 at 19:18 +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_removexattr hook.
> 
> Signed-off-by: Roberto Sassu <roberto.sassu@huawei.com>
> ---
>  fs/xattr.c                    |  1 +
>  include/linux/lsm_hook_defs.h |  2 ++
>  include/linux/security.h      |  5 +++++
>  security/security.c           | 14 ++++++++++++++
>  4 files changed, 22 insertions(+)
> 
> diff --git a/fs/xattr.c b/fs/xattr.c
> index 14a7eb3c8fa..10c959d9fc6 100644
> --- a/fs/xattr.c
> +++ b/fs/xattr.c
> @@ -534,6 +534,7 @@ __vfs_removexattr_locked(struct mnt_idmap *idmap,
>  
>  	if (!error) {
>  		fsnotify_xattr(dentry);
> +		security_inode_post_removexattr(dentry, name);
>  		evm_inode_post_removexattr(dentry, name);
>  	}

Nothing wrong with this, but other places in this function test "if
(error) goto ...".   Perhaps it is time to clean this up.

>  
> diff --git a/include/linux/lsm_hook_defs.h b/include/linux/lsm_hook_defs.h
> index eedefbcdde3..2ae5224d967 100644
> --- a/include/linux/lsm_hook_defs.h
> +++ b/include/linux/lsm_hook_defs.h
> @@ -147,6 +147,8 @@ LSM_HOOK(int, 0, inode_getxattr, struct dentry *dentry, const char *name)
>  LSM_HOOK(int, 0, inode_listxattr, struct dentry *dentry)
>  LSM_HOOK(int, 0, inode_removexattr, struct mnt_idmap *idmap,
>  	 struct dentry *dentry, const char *name)
> +LSM_HOOK(void, LSM_RET_VOID, inode_post_removexattr, struct dentry *dentry,
> +	 const char *name)

@Christian should the security_inode_removexattr() and
security_inode_post_removexattr() arguments be the same?

>  LSM_HOOK(int, 0, inode_set_acl, struct mnt_idmap *idmap,
>  	 struct dentry *dentry, const char *acl_name, struct posix_acl *kacl)
>  LSM_HOOK(int, 0, inode_get_acl, struct mnt_idmap *idmap,

-- 
thanks,

Mimi


^ permalink raw reply	[flat|nested] 79+ messages in thread

* Re: [PATCH 18/28] security: Introduce path_post_mknod hook
  2023-03-03 18:18 ` [PATCH 18/28] security: Introduce path_post_mknod hook Roberto Sassu
  2023-03-06 19:29   ` Stefan Berger
@ 2023-03-08 15:47   ` Mimi Zohar
  1 sibling, 0 replies; 79+ messages in thread
From: Mimi Zohar @ 2023-03-08 15:47 UTC (permalink / raw)
  To: Roberto Sassu, viro, chuck.lever, jlayton, dmitry.kasatkin, paul,
	jmorris, serge, dhowells, jarkko, stephen.smalley.work, eparis,
	casey, brauner
  Cc: linux-fsdevel, linux-nfs, linux-integrity, linux-security-module,
	keyrings, selinux, linux-kernel, stefanb, Roberto Sassu

Hi Roberto,

On Fri, 2023-03-03 at 19:18 +0100, Roberto Sassu wrote:
> From: Roberto Sassu <roberto.sassu@huawei.com>
> 
> In preparation for moving IMA and EVM to the LSM infrastructure, introduce
> the path_post_mknod hook.
> 
> Signed-off-by: Roberto Sassu <roberto.sassu@huawei.com>
> ---
>  fs/namei.c                    |  2 ++
>  include/linux/lsm_hook_defs.h |  3 +++
>  include/linux/security.h      |  9 +++++++++
>  security/security.c           | 19 +++++++++++++++++++
>  4 files changed, 33 insertions(+)
> 
> diff --git a/fs/namei.c b/fs/namei.c
> index 41f7fdf4657..3f2747521d3 100644
> --- a/fs/namei.c
> +++ b/fs/namei.c
> @@ -3980,6 +3980,8 @@ static int do_mknodat(int dfd, struct filename *name, umode_t mode,
>  					  dentry, mode, 0);
>  			break;
>  	}
> +	if (!error)
> +		security_path_post_mknod(idmap, &path, dentry, mode, dev);

Even though the original code uses "if (!error) ...",  consider using
"if (error) goto ..." here.

-- 
thanks,

Mimi



^ permalink raw reply	[flat|nested] 79+ messages in thread

* Re: [PATCH 22/28] security: Introduce key_post_create_or_update hook
  2023-03-03 18:18 ` [PATCH 22/28] security: Introduce key_post_create_or_update hook Roberto Sassu
  2023-03-07 17:48   ` Stefan Berger
@ 2023-03-08 15:49   ` Mimi Zohar
  1 sibling, 0 replies; 79+ messages in thread
From: Mimi Zohar @ 2023-03-08 15:49 UTC (permalink / raw)
  To: Roberto Sassu, viro, chuck.lever, jlayton, dmitry.kasatkin, paul,
	jmorris, serge, dhowells, jarkko, stephen.smalley.work, eparis,
	casey, brauner
  Cc: linux-fsdevel, linux-nfs, linux-integrity, linux-security-module,
	keyrings, selinux, linux-kernel, stefanb, Roberto Sassu

On Fri, 2023-03-03 at 19:18 +0100, Roberto Sassu wrote:

> diff --git a/security/security.c b/security/security.c
> index b3a9c317f75..322090a50cd 100644
> --- a/security/security.c
> +++ b/security/security.c
> @@ -5195,6 +5195,25 @@ int security_key_getsecurity(struct key *key, char **_buffer)
>  	*_buffer = NULL;
>  	return call_int_hook(key_getsecurity, 0, key, _buffer);
>  }
> +
> +/**
> + * security_key_post_create_or_update() - Tell caller of key creation or update

^Notification of key create or update

-- 
thanks,

Mimi


^ permalink raw reply	[flat|nested] 79+ messages in thread

* Re: [PATCH 23/28] security: Introduce LSM_ORDER_LAST
  2023-03-08 14:35         ` Roberto Sassu
@ 2023-03-08 15:52           ` Mimi Zohar
  0 siblings, 0 replies; 79+ messages in thread
From: Mimi Zohar @ 2023-03-08 15:52 UTC (permalink / raw)
  To: Roberto Sassu, viro, chuck.lever, jlayton, dmitry.kasatkin, paul,
	jmorris, serge, dhowells, jarkko, stephen.smalley.work, eparis,
	casey, brauner
  Cc: linux-fsdevel, linux-nfs, linux-integrity, linux-security-module,
	keyrings, selinux, linux-kernel, stefanb, Roberto Sassu

On Wed, 2023-03-08 at 15:35 +0100, Roberto Sassu wrote:
> On Wed, 2023-03-08 at 09:00 -0500, Mimi Zohar wrote:
> > On Wed, 2023-03-08 at 14:26 +0100, Roberto Sassu wrote:
> > > On Wed, 2023-03-08 at 08:13 -0500, Mimi Zohar wrote:
> > > > Hi Roberto,
> > > > 
> > > > On Fri, 2023-03-03 at 19:25 +0100, Roberto Sassu wrote:
> > > > > From: Roberto Sassu <roberto.sassu@huawei.com>
> > > > > 
> > > > > Introduce LSM_ORDER_LAST, to satisfy the requirement of LSMs willing to be
> > > > > the last, e.g. the 'integrity' LSM, without changing the kernel command
> > > > > line or configuration.
> > > > 
> > > > Please reframe this as a bug fix for 79f7865d844c ("LSM: Introduce
> > > > "lsm=" for boottime LSM selection") and upstream it first, with
> > > > 'integrity' as the last LSM.   The original bug fix commit 92063f3ca73a
> > > > ("integrity: double check iint_cache was initialized") could then be
> > > > removed.
> > > 
> > > Ok, I should complete the patch by checking the cache initialization in
> > > iint.c.
> > > 
> > > > > As for LSM_ORDER_FIRST, LSMs with LSM_ORDER_LAST are always enabled and put
> > > > > at the end of the LSM list in no particular order.
> > > > 
> > > > ^Similar to LSM_ORDER_FIRST ...
> > > > 
> > > > And remove "in no particular order".
> > > 
> > > The reason for this is that I originally thought that the relative
> > > order of LSMs specified in the kernel configuration or the command line
> > > was respected (if more than one LSM specifies LSM_ORDER_LAST). In fact
> > > not. To do this, we would have to parse the LSM string again, as it is
> > > done for LSM_ORDER_MUTABLE LSMs.
> > 
> > IMA and EVM are only configurable if 'integrity' is enabled.  Similar
> > to how LSM_ORDER_FIRST is reserved for capabilities, LSM_ORDER_LAST
> > should be reserved for integrity (LSMs), if it is configured, for the
> > reason as described in the "[PATCH 24/28] ima: Move to LSM
> > infrastructure" patch description.
> 
> Yes, it is just that nothing prevents to have multiple LSMs with order
> LSM_ORDER_LAST. I guess we will enforce that it is only one by
> reviewing the code.

At least add a comment, like the existing one for LSM_ORDER_FIRST.

> > > >  enum lsm_order {
> > > > >  	LSM_ORDER_FIRST = -1,	/* This is only for capabilities. */
> > > > >  	LSM_ORDER_MUTABLE = 0,
> > > > > +	LSM_ORDER_LAST = 1,
> > > > >  };

-- 
thanks,

Mimi


^ permalink raw reply	[flat|nested] 79+ messages in thread

* Re: [PATCH 00/28] security: Move IMA and EVM to the LSM infrastructure
  2023-03-08 15:14 ` [PATCH 00/28] security: Move IMA and EVM to the LSM infrastructure Mimi Zohar
@ 2023-03-08 16:23   ` Roberto Sassu
  0 siblings, 0 replies; 79+ messages in thread
From: Roberto Sassu @ 2023-03-08 16:23 UTC (permalink / raw)
  To: Mimi Zohar, viro, chuck.lever, jlayton, dmitry.kasatkin, paul,
	jmorris, serge, dhowells, jarkko, stephen.smalley.work, eparis,
	casey, brauner
  Cc: linux-fsdevel, linux-nfs, linux-integrity, linux-security-module,
	keyrings, selinux, linux-kernel, stefanb, Roberto Sassu

On Wed, 2023-03-08 at 10:14 -0500, Mimi Zohar wrote:
> Hi Roberto,
> 
> On Fri, 2023-03-03 at 19:18 +0100, Roberto Sassu wrote:
> > From: Roberto Sassu <roberto.sassu@huawei.com>
> > 
> > This patch set depends on:
> > - https://lore.kernel.org/linux-integrity/20221201104125.919483-1-roberto.sassu@huaweicloud.com/ (there will be a v8 shortly)
> > - https://lore.kernel.org/linux-security-module/20230217032625.678457-1-paul@paul-moore.com/
> > 
> > IMA and EVM are not effectively LSMs, especially due the fact that in the
> > past they could not provide a security blob while there is another LSM
> > active.
> > 
> > That changed in the recent years, the LSM stacking feature now makes it
> > possible to stack together multiple LSMs, and allows them to provide a
> > security blob for most kernel objects. While the LSM stacking feature has
> > some limitations being worked out, it is already suitable to make IMA and
> > EVM as LSMs.
> > 
> > In short, while this patch set is big, it does not make any functional
> > change to IMA and EVM. IMA and EVM functions are called by the LSM
> > infrastructure in the same places as before (except ima_post_path_mknod()),
> > rather being hardcoded calls, and the inode metadata pointer is directly
> > stored in the inode security blob rather than in a separate rbtree.
> > 
> > More specifically, patches 1-13 make IMA and EVM functions suitable to
> > be registered to the LSM infrastructure, by aligning function parameters.
> > 
> > Patches 14-22 add new LSM hooks in the same places where IMA and EVM
> > functions are called, if there is no LSM hook already.
> > 
> > Patch 23 adds the 'last' ordering strategy for LSMs, so that IMA and EVM
> > functions are called in the same order as of today. Also, like with the
> > 'first' strategy, LSMs using it are always enabled, so IMA and EVM
> > functions will be always called (if IMA and EVM are compiled built-in).
> > 
> > Patches 24-27 do the bulk of the work, remove hardcoded calls to IMA and
> > EVM functions, register those functions in the LSM infrastructure, and let
> > the latter call them. In addition, they also reserve one slot for EVM to 
> > supply an xattr to the inode_init_security hook.
> > 
> > Finally, patch 28 removes the rbtree used to bind metadata to the inodes,
> > and instead reserve a space in the inode security blob to store the pointer
> > to metadata. This also brings performance improvements due to retrieving
> > metadata in constant time, as opposed to logarithmic.
> 
> Prior to IMA being upstreamed, it went through a number of iterations,
> first on the security hooks, then as a separate parallel set of
> integrity hooks, and, finally, co-located with the security hooks,
> where they exist.  With this patch set we've come full circle.
> 
> With the LSM stacking support, multiple LSMs can now use the
> 'i_security' field removing the need for the rbtree indirection for
> accessing integrity state info.
> 
> Roberto, thank you for making this change.  Mostly it looks good.  
> Reviewing the patch set will be easier once the prereq's and this patch
> set can be properly applied.

Welcome. Yes, once Paul reviews the other patch set, we can
progressively apply the patches.

Thanks

Roberto


^ permalink raw reply	[flat|nested] 79+ messages in thread

* Re: [PATCH 03/28] ima: Align ima_post_create_tmpfile() definition with LSM infrastructure
  2023-03-08 15:15   ` Mimi Zohar
@ 2023-03-09  9:11     ` Roberto Sassu
  0 siblings, 0 replies; 79+ messages in thread
From: Roberto Sassu @ 2023-03-09  9:11 UTC (permalink / raw)
  To: Mimi Zohar, viro, chuck.lever, jlayton, dmitry.kasatkin, paul,
	jmorris, serge, dhowells, jarkko, stephen.smalley.work, eparis,
	casey, brauner
  Cc: linux-fsdevel, linux-nfs, linux-integrity, linux-security-module,
	keyrings, selinux, linux-kernel, stefanb, Roberto Sassu

On Wed, 2023-03-08 at 10:15 -0500, Mimi Zohar wrote:
> Hi Roberto,
> 
> On Fri, 2023-03-03 at 19:18 +0100, Roberto Sassu wrote:
> > From: Roberto Sassu <roberto.sassu@huawei.com>
> > 
> > Change ima_post_create_tmpfile() definition, so that it can be registered
> > as implementation of the post_create_tmpfile hook.
> 
> Since neither security_create_tmpfile() nor
> security_post_create_tmpfile() already exist, why not pass a pointer to
> the file to conform to the other file related security hooks?

Ok, will change the parameter.

Thanks

Roberto

> Mimi
> 
> > Signed-off-by: Roberto Sassu <roberto.sassu@huawei.com>
> > ---
> >  fs/namei.c                        | 2 +-
> >  include/linux/ima.h               | 7 +++++--
> >  security/integrity/ima/ima_main.c | 8 ++++++--
> >  3 files changed, 12 insertions(+), 5 deletions(-)
> > 
> > diff --git a/fs/namei.c b/fs/namei.c
> > index b5a1ec29193..57727a1ae38 100644
> > --- a/fs/namei.c
> > +++ b/fs/namei.c
> > @@ -3622,7 +3622,7 @@ static int vfs_tmpfile(struct mnt_idmap *idmap,
> >  		inode->i_state |= I_LINKABLE;
> >  		spin_unlock(&inode->i_lock);
> >  	}
> > -	ima_post_create_tmpfile(idmap, inode);
> > +	ima_post_create_tmpfile(idmap, dir, file_dentry(file), mode);
> >  	return 0;
> >  }
> >  
> > diff --git a/include/linux/ima.h b/include/linux/ima.h
> > index 179ce52013b..7535686a403 100644
> > --- a/include/linux/ima.h
> > +++ b/include/linux/ima.h
> > @@ -19,7 +19,8 @@ extern enum hash_algo ima_get_current_hash_algo(void);
> >  extern int ima_bprm_check(struct linux_binprm *bprm);
> >  extern int ima_file_check(struct file *file, int mask);
> >  extern void ima_post_create_tmpfile(struct mnt_idmap *idmap,
> > -				    struct inode *inode);
> > +				    struct inode *dir, struct dentry *dentry,
> > +				    umode_t mode);
> >  extern void ima_file_free(struct file *file);
> >  extern int ima_file_mmap(struct file *file, unsigned long reqprot,
> >  			 unsigned long prot, unsigned long flags);
> > @@ -69,7 +70,9 @@ static inline int ima_file_check(struct file *file, int mask)
> >  }
> >  
> >  static inline void ima_post_create_tmpfile(struct mnt_idmap *idmap,
> > -					   struct inode *inode)
> > +					   struct inode *dir,
> > +					   struct dentry *dentry,
> > +					   umode_t mode)
> >  {
> >  }
> >  
> > diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c
> > index 8941305376b..4a3d0c8bcba 100644
> > --- a/security/integrity/ima/ima_main.c
> > +++ b/security/integrity/ima/ima_main.c
> > @@ -659,16 +659,20 @@ EXPORT_SYMBOL_GPL(ima_inode_hash);
> >  /**
> >   * ima_post_create_tmpfile - mark newly created tmpfile as new
> >   * @idmap: idmap of the mount the inode was found from
> > - * @inode: inode of the newly created tmpfile
> > + * @dir: inode structure of the parent of the new file
> > + * @dentry: dentry structure of the new file
> > + * @mode: mode of the new file
> >   *
> >   * No measuring, appraising or auditing of newly created tmpfiles is needed.
> >   * Skip calling process_measurement(), but indicate which newly, created
> >   * tmpfiles are in policy.
> >   */
> >  void ima_post_create_tmpfile(struct mnt_idmap *idmap,
> > -			     struct inode *inode)
> > +			     struct inode *dir, struct dentry *dentry,
> > +			     umode_t mode)
> >  {
> >  	struct integrity_iint_cache *iint;
> > +	struct inode *inode = dentry->d_inode;
> >  	int must_appraise;
> >  
> >  	if (!ima_policy_flag || !S_ISREG(inode->i_mode))


^ permalink raw reply	[flat|nested] 79+ messages in thread

* Re: [PATCH 15/28] security: Introduce inode_post_removexattr hook
  2023-03-08 15:43   ` Mimi Zohar
@ 2023-03-09 13:07     ` Roberto Sassu
  2023-08-30  9:31     ` Roberto Sassu
  1 sibling, 0 replies; 79+ messages in thread
From: Roberto Sassu @ 2023-03-09 13:07 UTC (permalink / raw)
  To: Mimi Zohar, viro, chuck.lever, jlayton, dmitry.kasatkin, paul,
	jmorris, serge, dhowells, jarkko, stephen.smalley.work, eparis,
	casey, brauner
  Cc: linux-fsdevel, linux-nfs, linux-integrity, linux-security-module,
	keyrings, selinux, linux-kernel, stefanb, Roberto Sassu

On Wed, 2023-03-08 at 10:43 -0500, Mimi Zohar wrote:
> Hi Roberto,
> 
> On Fri, 2023-03-03 at 19:18 +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_removexattr hook.
> > 
> > Signed-off-by: Roberto Sassu <roberto.sassu@huawei.com>
> > ---
> >  fs/xattr.c                    |  1 +
> >  include/linux/lsm_hook_defs.h |  2 ++
> >  include/linux/security.h      |  5 +++++
> >  security/security.c           | 14 ++++++++++++++
> >  4 files changed, 22 insertions(+)
> > 
> > diff --git a/fs/xattr.c b/fs/xattr.c
> > index 14a7eb3c8fa..10c959d9fc6 100644
> > --- a/fs/xattr.c
> > +++ b/fs/xattr.c
> > @@ -534,6 +534,7 @@ __vfs_removexattr_locked(struct mnt_idmap *idmap,
> >  
> >  	if (!error) {
> >  		fsnotify_xattr(dentry);
> > +		security_inode_post_removexattr(dentry, name);
> >  		evm_inode_post_removexattr(dentry, name);
> >  	}
> 
> Nothing wrong with this, but other places in this function test "if
> (error) goto ...".   Perhaps it is time to clean this up.

Theoretically, all 'goto out' can be replaced with 'return error'.

I would be more in favor of minimizing the changes as much as possible
to reach the main goal. But it is ok also to change the last part.

Thanks

Roberto

> >  
> > diff --git a/include/linux/lsm_hook_defs.h b/include/linux/lsm_hook_defs.h
> > index eedefbcdde3..2ae5224d967 100644
> > --- a/include/linux/lsm_hook_defs.h
> > +++ b/include/linux/lsm_hook_defs.h
> > @@ -147,6 +147,8 @@ LSM_HOOK(int, 0, inode_getxattr, struct dentry *dentry, const char *name)
> >  LSM_HOOK(int, 0, inode_listxattr, struct dentry *dentry)
> >  LSM_HOOK(int, 0, inode_removexattr, struct mnt_idmap *idmap,
> >  	 struct dentry *dentry, const char *name)
> > +LSM_HOOK(void, LSM_RET_VOID, inode_post_removexattr, struct dentry *dentry,
> > +	 const char *name)
> 
> @Christian should the security_inode_removexattr() and
> security_inode_post_removexattr() arguments be the same?
> 
> >  LSM_HOOK(int, 0, inode_set_acl, struct mnt_idmap *idmap,
> >  	 struct dentry *dentry, const char *acl_name, struct posix_acl *kacl)
> >  LSM_HOOK(int, 0, inode_get_acl, struct mnt_idmap *idmap,


^ permalink raw reply	[flat|nested] 79+ messages in thread

* Re: [PATCH 15/28] security: Introduce inode_post_removexattr hook
  2023-03-08 15:43   ` Mimi Zohar
  2023-03-09 13:07     ` Roberto Sassu
@ 2023-08-30  9:31     ` Roberto Sassu
  2023-08-30  9:53       ` Christian Brauner
  1 sibling, 1 reply; 79+ messages in thread
From: Roberto Sassu @ 2023-08-30  9:31 UTC (permalink / raw)
  To: brauner
  Cc: Mimi Zohar, viro, chuck.lever, jlayton, dmitry.kasatkin, paul,
	jmorris, serge, dhowells, jarkko, stephen.smalley.work, eparis,
	casey, linux-fsdevel, linux-nfs, linux-integrity,
	linux-security-module, keyrings, selinux, linux-kernel, stefanb,
	Roberto Sassu

On Wed, 2023-03-08 at 10:43 -0500, Mimi Zohar wrote:
> Hi Roberto,
> 
> On Fri, 2023-03-03 at 19:18 +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_removexattr hook.
> > 
> > Signed-off-by: Roberto Sassu <roberto.sassu@huawei.com>
> > ---
> >  fs/xattr.c                    |  1 +
> >  include/linux/lsm_hook_defs.h |  2 ++
> >  include/linux/security.h      |  5 +++++
> >  security/security.c           | 14 ++++++++++++++
> >  4 files changed, 22 insertions(+)
> > 
> > diff --git a/fs/xattr.c b/fs/xattr.c
> > index 14a7eb3c8fa..10c959d9fc6 100644
> > --- a/fs/xattr.c
> > +++ b/fs/xattr.c
> > @@ -534,6 +534,7 @@ __vfs_removexattr_locked(struct mnt_idmap *idmap,
> >  
> >  	if (!error) {
> >  		fsnotify_xattr(dentry);
> > +		security_inode_post_removexattr(dentry, name);
> >  		evm_inode_post_removexattr(dentry, name);
> >  	}
> 
> Nothing wrong with this, but other places in this function test "if
> (error) goto ...".   Perhaps it is time to clean this up.
> 
> >  
> > diff --git a/include/linux/lsm_hook_defs.h b/include/linux/lsm_hook_defs.h
> > index eedefbcdde3..2ae5224d967 100644
> > --- a/include/linux/lsm_hook_defs.h
> > +++ b/include/linux/lsm_hook_defs.h
> > @@ -147,6 +147,8 @@ LSM_HOOK(int, 0, inode_getxattr, struct dentry *dentry, const char *name)
> >  LSM_HOOK(int, 0, inode_listxattr, struct dentry *dentry)
> >  LSM_HOOK(int, 0, inode_removexattr, struct mnt_idmap *idmap,
> >  	 struct dentry *dentry, const char *name)
> > +LSM_HOOK(void, LSM_RET_VOID, inode_post_removexattr, struct dentry *dentry,
> > +	 const char *name)
> 
> @Christian should the security_inode_removexattr() and
> security_inode_post_removexattr() arguments be the same?

Probably this got lost.

Christian, should security_inode_post_removexattr() have the idmap
parameter as well?

Thanks

Roberto

> >  LSM_HOOK(int, 0, inode_set_acl, struct mnt_idmap *idmap,
> >  	 struct dentry *dentry, const char *acl_name, struct posix_acl *kacl)
> >  LSM_HOOK(int, 0, inode_get_acl, struct mnt_idmap *idmap,
> 


^ permalink raw reply	[flat|nested] 79+ messages in thread

* Re: [PATCH 15/28] security: Introduce inode_post_removexattr hook
  2023-08-30  9:31     ` Roberto Sassu
@ 2023-08-30  9:53       ` Christian Brauner
  0 siblings, 0 replies; 79+ messages in thread
From: Christian Brauner @ 2023-08-30  9:53 UTC (permalink / raw)
  To: Roberto Sassu
  Cc: Mimi Zohar, viro, chuck.lever, jlayton, dmitry.kasatkin, paul,
	jmorris, serge, dhowells, jarkko, stephen.smalley.work, eparis,
	casey, linux-fsdevel, linux-nfs, linux-integrity,
	linux-security-module, keyrings, selinux, linux-kernel, stefanb,
	Roberto Sassu

On Wed, Aug 30, 2023 at 11:31:35AM +0200, Roberto Sassu wrote:
> On Wed, 2023-03-08 at 10:43 -0500, Mimi Zohar wrote:
> > Hi Roberto,
> > 
> > On Fri, 2023-03-03 at 19:18 +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_removexattr hook.
> > > 
> > > Signed-off-by: Roberto Sassu <roberto.sassu@huawei.com>
> > > ---
> > >  fs/xattr.c                    |  1 +
> > >  include/linux/lsm_hook_defs.h |  2 ++
> > >  include/linux/security.h      |  5 +++++
> > >  security/security.c           | 14 ++++++++++++++
> > >  4 files changed, 22 insertions(+)
> > > 
> > > diff --git a/fs/xattr.c b/fs/xattr.c
> > > index 14a7eb3c8fa..10c959d9fc6 100644
> > > --- a/fs/xattr.c
> > > +++ b/fs/xattr.c
> > > @@ -534,6 +534,7 @@ __vfs_removexattr_locked(struct mnt_idmap *idmap,
> > >  
> > >  	if (!error) {
> > >  		fsnotify_xattr(dentry);
> > > +		security_inode_post_removexattr(dentry, name);
> > >  		evm_inode_post_removexattr(dentry, name);
> > >  	}
> > 
> > Nothing wrong with this, but other places in this function test "if
> > (error) goto ...".   Perhaps it is time to clean this up.
> > 
> > >  
> > > diff --git a/include/linux/lsm_hook_defs.h b/include/linux/lsm_hook_defs.h
> > > index eedefbcdde3..2ae5224d967 100644
> > > --- a/include/linux/lsm_hook_defs.h
> > > +++ b/include/linux/lsm_hook_defs.h
> > > @@ -147,6 +147,8 @@ LSM_HOOK(int, 0, inode_getxattr, struct dentry *dentry, const char *name)
> > >  LSM_HOOK(int, 0, inode_listxattr, struct dentry *dentry)
> > >  LSM_HOOK(int, 0, inode_removexattr, struct mnt_idmap *idmap,
> > >  	 struct dentry *dentry, const char *name)
> > > +LSM_HOOK(void, LSM_RET_VOID, inode_post_removexattr, struct dentry *dentry,
> > > +	 const char *name)
> > 
> > @Christian should the security_inode_removexattr() and
> > security_inode_post_removexattr() arguments be the same?
> 
> Probably this got lost.
> 
> Christian, should security_inode_post_removexattr() have the idmap
> parameter as well?

Only if you call anything from any implementers of the hook that needs
access to the idmap.

^ permalink raw reply	[flat|nested] 79+ messages in thread

end of thread, other threads:[~2023-08-30 18:48 UTC | newest]

Thread overview: 79+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-03-03 18:18 [PATCH 00/28] security: Move IMA and EVM to the LSM infrastructure Roberto Sassu
2023-03-03 18:18 ` [PATCH 01/28] ima: Align ima_inode_post_setattr() definition with " Roberto Sassu
2023-03-06 16:46   ` Stefan Berger
2023-03-03 18:18 ` [PATCH 02/28] ima: Align ima_post_path_mknod() " Roberto Sassu
2023-03-06 16:52   ` Stefan Berger
2023-03-03 18:18 ` [PATCH 03/28] ima: Align ima_post_create_tmpfile() " Roberto Sassu
2023-03-06 16:53   ` Stefan Berger
2023-03-08 15:15   ` Mimi Zohar
2023-03-09  9:11     ` Roberto Sassu
2023-03-03 18:18 ` [PATCH 04/28] ima: Align ima_file_mprotect() " Roberto Sassu
2023-03-06 16:56   ` Stefan Berger
2023-03-03 18:18 ` [PATCH 05/28] ima: Align ima_inode_setxattr() " Roberto Sassu
2023-03-06 16:57   ` Stefan Berger
2023-03-03 18:18 ` [PATCH 06/28] ima: Align ima_inode_removexattr() " Roberto Sassu
2023-03-06 16:58   ` Stefan Berger
2023-03-03 18:18 ` [PATCH 07/28] ima: Align ima_post_read_file() " Roberto Sassu
2023-03-06 16:59   ` Stefan Berger
2023-03-03 18:18 ` [PATCH 08/28] evm: Align evm_inode_post_setattr() " Roberto Sassu
2023-03-06 17:00   ` Stefan Berger
2023-03-03 18:18 ` [PATCH 09/28] evm: Align evm_inode_setxattr() " Roberto Sassu
2023-03-06 17:01   ` Stefan Berger
2023-03-03 18:18 ` [PATCH 10/28] evm: Align evm_inode_post_setxattr() " Roberto Sassu
2023-03-06 17:02   ` Stefan Berger
2023-03-03 18:18 ` [PATCH 11/28] evm: Complete description of evm_inode_setattr() Roberto Sassu
2023-03-06 17:04   ` Stefan Berger
2023-03-07  8:58     ` Roberto Sassu
2023-03-03 18:18 ` [PATCH 12/28] fs: Fix description of vfs_tmpfile() Roberto Sassu
2023-03-06 10:28   ` Christian Brauner
2023-03-06 10:31     ` Roberto Sassu
2023-03-03 18:18 ` [PATCH 13/28] security: Align inode_setattr hook definition with EVM Roberto Sassu
2023-03-05  0:42   ` Casey Schaufler
2023-03-06 17:06   ` Stefan Berger
2023-03-03 18:18 ` [PATCH 14/28] security: Introduce inode_post_setattr hook Roberto Sassu
2023-03-06 17:08   ` Stefan Berger
2023-03-08 15:19   ` Mimi Zohar
2023-03-03 18:18 ` [PATCH 15/28] security: Introduce inode_post_removexattr hook Roberto Sassu
2023-03-06 19:17   ` Stefan Berger
2023-03-08 15:43   ` Mimi Zohar
2023-03-09 13:07     ` Roberto Sassu
2023-08-30  9:31     ` Roberto Sassu
2023-08-30  9:53       ` Christian Brauner
2023-03-03 18:18 ` [PATCH 16/28] security: Introduce file_post_open hook Roberto Sassu
2023-03-06 19:24   ` Stefan Berger
2023-03-03 18:18 ` [PATCH 17/28] security: Introduce file_pre_free_security hook Roberto Sassu
2023-03-06 19:26   ` Stefan Berger
2023-03-03 18:18 ` [PATCH 18/28] security: Introduce path_post_mknod hook Roberto Sassu
2023-03-06 19:29   ` Stefan Berger
2023-03-08 15:47   ` Mimi Zohar
2023-03-03 18:18 ` [PATCH 19/28] security: Introduce inode_post_create_tmpfile hook Roberto Sassu
2023-03-06 19:35   ` Stefan Berger
2023-03-03 18:18 ` [PATCH 20/28] security: Introduce inode_post_set_acl hook Roberto Sassu
2023-03-06 19:45   ` Stefan Berger
2023-03-03 18:18 ` [PATCH 21/28] security: Introduce inode_post_remove_acl hook Roberto Sassu
2023-03-06 15:22   ` Stefan Berger
2023-03-06 15:34     ` Roberto Sassu
2023-03-06 16:16       ` Stefan Berger
2023-03-06 16:50         ` Roberto Sassu
2023-03-03 18:18 ` [PATCH 22/28] security: Introduce key_post_create_or_update hook Roberto Sassu
2023-03-07 17:48   ` Stefan Berger
2023-03-08 15:49   ` Mimi Zohar
2023-03-03 18:25 ` [PATCH 23/28] security: Introduce LSM_ORDER_LAST Roberto Sassu
2023-03-07 18:04   ` Stefan Berger
2023-03-08  8:06     ` Roberto Sassu
2023-03-08 13:13   ` Mimi Zohar
2023-03-08 13:26     ` Roberto Sassu
2023-03-08 14:00       ` Mimi Zohar
2023-03-08 14:35         ` Roberto Sassu
2023-03-08 15:52           ` Mimi Zohar
2023-03-03 18:25 ` [PATCH 24/28] ima: Move to LSM infrastructure Roberto Sassu
2023-03-03 18:25 ` [PATCH 25/28] ima: Move IMA-Appraisal " Roberto Sassu
2023-03-03 18:26 ` [PATCH 26/28] evm: Move " Roberto Sassu
2023-03-04 21:36   ` Casey Schaufler
2023-03-06  9:21     ` Roberto Sassu
2023-03-07 16:54       ` Casey Schaufler
2023-03-07 16:57         ` Roberto Sassu
2023-03-03 18:26 ` [PATCH 27/28] integrity: Move integrity functions to the " Roberto Sassu
2023-03-03 18:26 ` [PATCH 28/28] integrity: Switch from rbtree to LSM-managed blob for integrity_iint_cache Roberto Sassu
2023-03-08 15:14 ` [PATCH 00/28] security: Move IMA and EVM to the LSM infrastructure Mimi Zohar
2023-03-08 16:23   ` Roberto Sassu

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).