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

From: Roberto Sassu <roberto.sassu@huawei.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-11 make IMA and EVM functions suitable to
be registered to the LSM infrastructure, by aligning function parameters.

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

Patches 21-24 do the bulk of the work, remove hardcoded calls to IMA, EVM
and integrity 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 25 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.

The patch set applies on top of lsm/next, commit 8e4672d6f902 ("lsm:
constify the 'file' parameter in security_binder_transfer_file()")

Changelog:

v1:
 - Drop 'evm: Complete description of evm_inode_setattr()', 'fs: Fix
   description of vfs_tmpfile()' and 'security: Introduce LSM_ORDER_LAST',
   they were sent separately (suggested by Christian Brauner)
 - Replace dentry with file descriptor parameter for
   security_inode_post_create_tmpfile()
 - Introduce mode_stripped and pass it as mode argument to
   security_path_mknod() and security_path_post_mknod()
 - Use goto in do_mknodat() and __vfs_removexattr_locked() (suggested by
   Mimi)
 - Replace __lsm_ro_after_init with __ro_after_init
 - Modify short description of security_inode_post_create_tmpfile() and
   security_inode_post_set_acl() (suggested by Stefan)
 - Move security_inode_post_setattr() just after security_inode_setattr()
   (suggested by Mimi)
 - Modify short description of security_key_post_create_or_update()
   (suggested by Mimi)
 - Add back exported functions ima_file_check() and
   evm_inode_init_security() respectively to ima.h and evm.h (reported by
   kernel robot)
 - Remove extern from prototype declarations and fix style issues
 - Remove unnecessary include of linux/lsm_hooks.h in ima_main.c and
   ima_appraise.c

Roberto Sassu (25):
  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
  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
  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                            |  18 +-
 fs/nfsd/vfs.c                         |   3 +-
 fs/open.c                             |   1 -
 fs/posix_acl.c                        |   5 +-
 fs/xattr.c                            |   9 +-
 include/linux/evm.h                   | 103 ----------
 include/linux/ima.h                   | 136 -------------
 include/linux/integrity.h             |  26 ---
 include/linux/lsm_hook_defs.h         |  21 +-
 include/linux/security.h              |  65 +++++++
 security/integrity/evm/evm_main.c     | 104 ++++++++--
 security/integrity/iint.c             |  92 +++------
 security/integrity/ima/ima.h          |  11 ++
 security/integrity/ima/ima_appraise.c |  37 +++-
 security/integrity/ima/ima_main.c     |  76 ++++++--
 security/integrity/integrity.h        |  44 ++++-
 security/keys/key.c                   |  10 +-
 security/security.c                   | 265 ++++++++++++++++----------
 security/selinux/hooks.c              |   3 +-
 security/smack/smack_lsm.c            |   4 +-
 22 files changed, 540 insertions(+), 501 deletions(-)

-- 
2.34.1


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

* [PATCH v2 01/25] ima: Align ima_inode_post_setattr() definition with LSM infrastructure
  2023-08-31 10:41 [PATCH v2 00/25] security: Move IMA and EVM to the LSM infrastructure Roberto Sassu
@ 2023-08-31 10:41 ` Roberto Sassu
  2023-08-31 10:41 ` [PATCH v2 02/25] ima: Align ima_post_path_mknod() " Roberto Sassu
                   ` (24 subsequent siblings)
  25 siblings, 0 replies; 48+ messages in thread
From: Roberto Sassu @ 2023-08-31 10:41 UTC (permalink / raw)
  To: viro, brauner, chuck.lever, jlayton, neilb, kolga, Dai.Ngo, tom,
	zohar, dmitry.kasatkin, paul, jmorris, serge, dhowells, jarkko,
	stephen.smalley.work, eparis, casey
  Cc: linux-fsdevel, linux-kernel, linux-nfs, linux-integrity,
	linux-security-module, keyrings, selinux, Roberto Sassu,
	Stefan Berger

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>
---
 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 d60dc1edb526..7d4553c1208d 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);
+		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 86b57757c7b1..910a2f11a906 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 491c1aca0b1c..6b032bce4fe7 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.34.1


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

* [PATCH v2 02/25] ima: Align ima_post_path_mknod() definition with LSM infrastructure
  2023-08-31 10:41 [PATCH v2 00/25] security: Move IMA and EVM to the LSM infrastructure Roberto Sassu
  2023-08-31 10:41 ` [PATCH v2 01/25] ima: Align ima_inode_post_setattr() definition with " Roberto Sassu
@ 2023-08-31 10:41 ` Roberto Sassu
  2023-08-31 10:41 ` [PATCH v2 03/25] ima: Align ima_post_create_tmpfile() " Roberto Sassu
                   ` (23 subsequent siblings)
  25 siblings, 0 replies; 48+ messages in thread
From: Roberto Sassu @ 2023-08-31 10:41 UTC (permalink / raw)
  To: viro, brauner, chuck.lever, jlayton, neilb, kolga, Dai.Ngo, tom,
	zohar, dmitry.kasatkin, paul, jmorris, serge, dhowells, jarkko,
	stephen.smalley.work, eparis, casey
  Cc: linux-fsdevel, linux-kernel, linux-nfs, linux-integrity,
	linux-security-module, keyrings, selinux, 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. Since LSMs see a umask-stripped
mode from security_path_mknod(), pass the same to ima_post_path_mknod() as
well.

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                        |  9 ++++++---
 include/linux/ima.h               |  7 +++++--
 security/integrity/ima/ima_main.c | 10 +++++++++-
 3 files changed, 20 insertions(+), 6 deletions(-)

diff --git a/fs/namei.c b/fs/namei.c
index e56ff39a79bc..c5e96f716f98 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -4024,6 +4024,7 @@ static int do_mknodat(int dfd, struct filename *name, umode_t mode,
 	struct path path;
 	int error;
 	unsigned int lookup_flags = 0;
+	umode_t mode_stripped;
 
 	error = may_mknod(mode);
 	if (error)
@@ -4034,8 +4035,9 @@ static int do_mknodat(int dfd, struct filename *name, umode_t mode,
 	if (IS_ERR(dentry))
 		goto out1;
 
-	error = security_path_mknod(&path, dentry,
-			mode_strip_umask(path.dentry->d_inode, mode), dev);
+	mode_stripped = mode_strip_umask(path.dentry->d_inode, mode);
+
+	error = security_path_mknod(&path, dentry, mode_stripped, dev);
 	if (error)
 		goto out2;
 
@@ -4045,7 +4047,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_stripped, 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 910a2f11a906..179ce52013b2 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 365db0e43d7c..76eba92d7f10 100644
--- a/security/integrity/ima/ima_main.c
+++ b/security/integrity/ima/ima_main.c
@@ -696,18 +696,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.34.1


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

* [PATCH v2 03/25] ima: Align ima_post_create_tmpfile() definition with LSM infrastructure
  2023-08-31 10:41 [PATCH v2 00/25] security: Move IMA and EVM to the LSM infrastructure Roberto Sassu
  2023-08-31 10:41 ` [PATCH v2 01/25] ima: Align ima_inode_post_setattr() definition with " Roberto Sassu
  2023-08-31 10:41 ` [PATCH v2 02/25] ima: Align ima_post_path_mknod() " Roberto Sassu
@ 2023-08-31 10:41 ` Roberto Sassu
  2023-08-31 10:41 ` [PATCH v2 04/25] ima: Align ima_file_mprotect() " Roberto Sassu
                   ` (22 subsequent siblings)
  25 siblings, 0 replies; 48+ messages in thread
From: Roberto Sassu @ 2023-08-31 10:41 UTC (permalink / raw)
  To: viro, brauner, chuck.lever, jlayton, neilb, kolga, Dai.Ngo, tom,
	zohar, dmitry.kasatkin, paul, jmorris, serge, dhowells, jarkko,
	stephen.smalley.work, eparis, casey
  Cc: linux-fsdevel, linux-kernel, linux-nfs, linux-integrity,
	linux-security-module, keyrings, selinux, 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 c5e96f716f98..1f5ec71360de 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -3698,7 +3698,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, mode);
 	return 0;
 }
 
diff --git a/include/linux/ima.h b/include/linux/ima.h
index 179ce52013b2..893c3b98b4d0 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 file *file,
+				    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 file *file,
+					   umode_t mode)
 {
 }
 
diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c
index 76eba92d7f10..52e742d32f4b 100644
--- a/security/integrity/ima/ima_main.c
+++ b/security/integrity/ima/ima_main.c
@@ -663,16 +663,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
+ * @file: file descriptor 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 file *file,
+			     umode_t mode)
 {
 	struct integrity_iint_cache *iint;
+	struct inode *inode = file_inode(file);
 	int must_appraise;
 
 	if (!ima_policy_flag || !S_ISREG(inode->i_mode))
-- 
2.34.1


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

* [PATCH v2 04/25] ima: Align ima_file_mprotect() definition with LSM infrastructure
  2023-08-31 10:41 [PATCH v2 00/25] security: Move IMA and EVM to the LSM infrastructure Roberto Sassu
                   ` (2 preceding siblings ...)
  2023-08-31 10:41 ` [PATCH v2 03/25] ima: Align ima_post_create_tmpfile() " Roberto Sassu
@ 2023-08-31 10:41 ` Roberto Sassu
  2023-08-31 10:41 ` [PATCH v2 05/25] ima: Align ima_inode_setxattr() " Roberto Sassu
                   ` (21 subsequent siblings)
  25 siblings, 0 replies; 48+ messages in thread
From: Roberto Sassu @ 2023-08-31 10:41 UTC (permalink / raw)
  To: viro, brauner, chuck.lever, jlayton, neilb, kolga, Dai.Ngo, tom,
	zohar, dmitry.kasatkin, paul, jmorris, serge, dhowells, jarkko,
	stephen.smalley.work, eparis, casey
  Cc: linux-fsdevel, linux-kernel, linux-nfs, linux-integrity,
	linux-security-module, keyrings, selinux, Roberto Sassu,
	Stefan Berger

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>
---
 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 893c3b98b4d0..56e72c0beb96 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);
+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 52e742d32f4b..e9e2a3ad25a1 100644
--- a/security/integrity/ima/ima_main.c
+++ b/security/integrity/ima/ima_main.c
@@ -441,7 +441,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
@@ -451,7 +452,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 96f2c68a1571..dffb67e6e119 100644
--- a/security/security.c
+++ b/security/security.c
@@ -2721,7 +2721,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.34.1


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

* [PATCH v2 05/25] ima: Align ima_inode_setxattr() definition with LSM infrastructure
  2023-08-31 10:41 [PATCH v2 00/25] security: Move IMA and EVM to the LSM infrastructure Roberto Sassu
                   ` (3 preceding siblings ...)
  2023-08-31 10:41 ` [PATCH v2 04/25] ima: Align ima_file_mprotect() " Roberto Sassu
@ 2023-08-31 10:41 ` Roberto Sassu
  2023-08-31 10:41 ` [PATCH v2 06/25] ima: Align ima_inode_removexattr() " Roberto Sassu
                   ` (20 subsequent siblings)
  25 siblings, 0 replies; 48+ messages in thread
From: Roberto Sassu @ 2023-08-31 10:41 UTC (permalink / raw)
  To: viro, brauner, chuck.lever, jlayton, neilb, kolga, Dai.Ngo, tom,
	zohar, dmitry.kasatkin, paul, jmorris, serge, dhowells, jarkko,
	stephen.smalley.work, eparis, casey
  Cc: linux-fsdevel, linux-kernel, linux-nfs, linux-integrity,
	linux-security-module, keyrings, selinux, Roberto Sassu,
	Stefan Berger

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>
---
 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 56e72c0beb96..3dedff8659d2 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);
+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 6b032bce4fe7..88c5a0b2992f 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 dffb67e6e119..00826269481e 100644
--- a/security/security.c
+++ b/security/security.c
@@ -2171,7 +2171,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.34.1


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

* [PATCH v2 06/25] ima: Align ima_inode_removexattr() definition with LSM infrastructure
  2023-08-31 10:41 [PATCH v2 00/25] security: Move IMA and EVM to the LSM infrastructure Roberto Sassu
                   ` (4 preceding siblings ...)
  2023-08-31 10:41 ` [PATCH v2 05/25] ima: Align ima_inode_setxattr() " Roberto Sassu
@ 2023-08-31 10:41 ` Roberto Sassu
  2023-08-31 10:41 ` [PATCH v2 07/25] ima: Align ima_post_read_file() " Roberto Sassu
                   ` (19 subsequent siblings)
  25 siblings, 0 replies; 48+ messages in thread
From: Roberto Sassu @ 2023-08-31 10:41 UTC (permalink / raw)
  To: viro, brauner, chuck.lever, jlayton, neilb, kolga, Dai.Ngo, tom,
	zohar, dmitry.kasatkin, paul, jmorris, serge, dhowells, jarkko,
	stephen.smalley.work, eparis, casey
  Cc: linux-fsdevel, linux-kernel, linux-nfs, linux-integrity,
	linux-security-module, keyrings, selinux, Roberto Sassu,
	Stefan Berger

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>
---
 include/linux/ima.h                   | 7 +++++--
 security/integrity/ima/ima_appraise.c | 3 ++-
 security/security.c                   | 2 +-
 3 files changed, 8 insertions(+), 4 deletions(-)

diff --git a/include/linux/ima.h b/include/linux/ima.h
index 3dedff8659d2..93e3c6cdf1f8 100644
--- a/include/linux/ima.h
+++ b/include/linux/ima.h
@@ -206,7 +206,9 @@ 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);
+
+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 +239,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 88c5a0b2992f..c35e3537eb87 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 00826269481e..2746e889db6d 100644
--- a/security/security.c
+++ b/security/security.c
@@ -2332,7 +2332,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.34.1


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

* [PATCH v2 07/25] ima: Align ima_post_read_file() definition with LSM infrastructure
  2023-08-31 10:41 [PATCH v2 00/25] security: Move IMA and EVM to the LSM infrastructure Roberto Sassu
                   ` (5 preceding siblings ...)
  2023-08-31 10:41 ` [PATCH v2 06/25] ima: Align ima_inode_removexattr() " Roberto Sassu
@ 2023-08-31 10:41 ` Roberto Sassu
  2023-08-31 10:41 ` [PATCH v2 08/25] evm: Align evm_inode_post_setattr() " Roberto Sassu
                   ` (18 subsequent siblings)
  25 siblings, 0 replies; 48+ messages in thread
From: Roberto Sassu @ 2023-08-31 10:41 UTC (permalink / raw)
  To: viro, brauner, chuck.lever, jlayton, neilb, kolga, Dai.Ngo, tom,
	zohar, dmitry.kasatkin, paul, jmorris, serge, dhowells, jarkko,
	stephen.smalley.work, eparis, casey
  Cc: linux-fsdevel, linux-kernel, linux-nfs, linux-integrity,
	linux-security-module, keyrings, selinux, Roberto Sassu,
	Stefan Berger

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>
---
 include/linux/ima.h               | 6 +++---
 security/integrity/ima/ima_main.c | 2 +-
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/include/linux/ima.h b/include/linux/ima.h
index 93e3c6cdf1f8..6e4d060ff378 100644
--- a/include/linux/ima.h
+++ b/include/linux/ima.h
@@ -31,8 +31,8 @@ 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,
-			      enum kernel_read_file_id id);
+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);
@@ -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 e9e2a3ad25a1..f8581032e62c 100644
--- a/security/integrity/ima/ima_main.c
+++ b/security/integrity/ima/ima_main.c
@@ -801,7 +801,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.34.1


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

* [PATCH v2 08/25] evm: Align evm_inode_post_setattr() definition with LSM infrastructure
  2023-08-31 10:41 [PATCH v2 00/25] security: Move IMA and EVM to the LSM infrastructure Roberto Sassu
                   ` (6 preceding siblings ...)
  2023-08-31 10:41 ` [PATCH v2 07/25] ima: Align ima_post_read_file() " Roberto Sassu
@ 2023-08-31 10:41 ` Roberto Sassu
  2023-08-31 10:41 ` [PATCH v2 09/25] evm: Align evm_inode_setxattr() " Roberto Sassu
                   ` (17 subsequent siblings)
  25 siblings, 0 replies; 48+ messages in thread
From: Roberto Sassu @ 2023-08-31 10:41 UTC (permalink / raw)
  To: viro, brauner, chuck.lever, jlayton, neilb, kolga, Dai.Ngo, tom,
	zohar, dmitry.kasatkin, paul, jmorris, serge, dhowells, jarkko,
	stephen.smalley.work, eparis, casey
  Cc: linux-fsdevel, linux-kernel, linux-nfs, linux-integrity,
	linux-security-module, keyrings, selinux, Roberto Sassu,
	Stefan Berger

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>
---
 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 7d4553c1208d..431f667726c7 100644
--- a/fs/attr.c
+++ b/fs/attr.c
@@ -487,7 +487,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 01fc495a83e2..aebaae181fd9 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);
+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);
@@ -97,7 +98,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 ff9a939dad8e..d2f986a55d38 100644
--- a/security/integrity/evm/evm_main.c
+++ b/security/integrity/evm/evm_main.c
@@ -841,6 +841,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
  *
@@ -850,7 +851,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.34.1


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

* [PATCH v2 09/25] evm: Align evm_inode_setxattr() definition with LSM infrastructure
  2023-08-31 10:41 [PATCH v2 00/25] security: Move IMA and EVM to the LSM infrastructure Roberto Sassu
                   ` (7 preceding siblings ...)
  2023-08-31 10:41 ` [PATCH v2 08/25] evm: Align evm_inode_post_setattr() " Roberto Sassu
@ 2023-08-31 10:41 ` Roberto Sassu
  2023-08-31 10:41 ` [PATCH v2 10/25] evm: Align evm_inode_post_setxattr() " Roberto Sassu
                   ` (16 subsequent siblings)
  25 siblings, 0 replies; 48+ messages in thread
From: Roberto Sassu @ 2023-08-31 10:41 UTC (permalink / raw)
  To: viro, brauner, chuck.lever, jlayton, neilb, kolga, Dai.Ngo, tom,
	zohar, dmitry.kasatkin, paul, jmorris, serge, dhowells, jarkko,
	stephen.smalley.work, eparis, casey
  Cc: linux-fsdevel, linux-kernel, linux-nfs, linux-integrity,
	linux-security-module, keyrings, selinux, Roberto Sassu,
	Stefan Berger

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>
Reviewed-by: Stefan Berger <stefanb@linux.ibm.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 aebaae181fd9..bed63ed7bde9 100644
--- a/include/linux/evm.h
+++ b/include/linux/evm.h
@@ -27,7 +27,7 @@ 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,
@@ -106,7 +106,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 d2f986a55d38..779ec35fb39f 100644
--- a/security/integrity/evm/evm_main.c
+++ b/security/integrity/evm/evm_main.c
@@ -559,6 +559,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
@@ -568,7 +569,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 2746e889db6d..743fd0f58698 100644
--- a/security/security.c
+++ b/security/security.c
@@ -2174,7 +2174,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.34.1


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

* [PATCH v2 10/25] evm: Align evm_inode_post_setxattr() definition with LSM infrastructure
  2023-08-31 10:41 [PATCH v2 00/25] security: Move IMA and EVM to the LSM infrastructure Roberto Sassu
                   ` (8 preceding siblings ...)
  2023-08-31 10:41 ` [PATCH v2 09/25] evm: Align evm_inode_setxattr() " Roberto Sassu
@ 2023-08-31 10:41 ` Roberto Sassu
  2023-08-31 10:41 ` [PATCH v2 11/25] security: Align inode_setattr hook definition with EVM Roberto Sassu
                   ` (15 subsequent siblings)
  25 siblings, 0 replies; 48+ messages in thread
From: Roberto Sassu @ 2023-08-31 10:41 UTC (permalink / raw)
  To: viro, brauner, chuck.lever, jlayton, neilb, kolga, Dai.Ngo, tom,
	zohar, dmitry.kasatkin, paul, jmorris, serge, dhowells, jarkko,
	stephen.smalley.work, eparis, casey
  Cc: linux-fsdevel, linux-kernel, linux-nfs, linux-integrity,
	linux-security-module, keyrings, selinux, Roberto Sassu,
	Stefan Berger

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>
---
 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 bed63ed7bde9..642e52483adc 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);
 }
 
 int evm_inode_init_security(struct inode *inode, struct inode *dir,
@@ -114,7 +115,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 779ec35fb39f..2e8f6d1c9984 100644
--- a/security/integrity/evm/evm_main.c
+++ b/security/integrity/evm/evm_main.c
@@ -731,6 +731,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.
  *
@@ -739,7 +740,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 743fd0f58698..cb6242feb968 100644
--- a/security/security.c
+++ b/security/security.c
@@ -2269,7 +2269,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.34.1


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

* [PATCH v2 11/25] security: Align inode_setattr hook definition with EVM
  2023-08-31 10:41 [PATCH v2 00/25] security: Move IMA and EVM to the LSM infrastructure Roberto Sassu
                   ` (9 preceding siblings ...)
  2023-08-31 10:41 ` [PATCH v2 10/25] evm: Align evm_inode_post_setxattr() " Roberto Sassu
@ 2023-08-31 10:41 ` Roberto Sassu
  2023-09-04 21:08   ` Jarkko Sakkinen
  2023-08-31 10:41 ` [PATCH v2 12/25] security: Introduce inode_post_setattr hook Roberto Sassu
                   ` (14 subsequent siblings)
  25 siblings, 1 reply; 48+ messages in thread
From: Roberto Sassu @ 2023-08-31 10:41 UTC (permalink / raw)
  To: viro, brauner, chuck.lever, jlayton, neilb, kolga, Dai.Ngo, tom,
	zohar, dmitry.kasatkin, paul, jmorris, serge, dhowells, jarkko,
	stephen.smalley.work, eparis, casey
  Cc: linux-fsdevel, linux-kernel, linux-nfs, linux-integrity,
	linux-security-module, keyrings, selinux, Roberto Sassu,
	Stefan Berger

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>
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 4bdddb52a8fe..fdf075a6b1bb 100644
--- a/include/linux/lsm_hook_defs.h
+++ b/include/linux/lsm_hook_defs.h
@@ -134,7 +134,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 cb6242feb968..2b24d01cf181 100644
--- a/security/security.c
+++ b/security/security.c
@@ -2117,7 +2117,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 ee7c49c2cfd3..bfcc4d9aa5ab 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -3075,7 +3075,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 679156601a10..89f2669d50a9 100644
--- a/security/smack/smack_lsm.c
+++ b/security/smack/smack_lsm.c
@@ -1181,12 +1181,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.34.1


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

* [PATCH v2 12/25] security: Introduce inode_post_setattr hook
  2023-08-31 10:41 [PATCH v2 00/25] security: Move IMA and EVM to the LSM infrastructure Roberto Sassu
                   ` (10 preceding siblings ...)
  2023-08-31 10:41 ` [PATCH v2 11/25] security: Align inode_setattr hook definition with EVM Roberto Sassu
@ 2023-08-31 10:41 ` Roberto Sassu
  2023-08-31 22:28   ` Casey Schaufler
  2023-09-04 21:09   ` Jarkko Sakkinen
  2023-08-31 10:41 ` [PATCH v2 13/25] security: Introduce inode_post_removexattr hook Roberto Sassu
                   ` (13 subsequent siblings)
  25 siblings, 2 replies; 48+ messages in thread
From: Roberto Sassu @ 2023-08-31 10:41 UTC (permalink / raw)
  To: viro, brauner, chuck.lever, jlayton, neilb, kolga, Dai.Ngo, tom,
	zohar, dmitry.kasatkin, paul, jmorris, serge, dhowells, jarkko,
	stephen.smalley.work, eparis, casey
  Cc: linux-fsdevel, linux-kernel, linux-nfs, linux-integrity,
	linux-security-module, keyrings, selinux, Roberto Sassu,
	Stefan Berger

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>
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 431f667726c7..3c309eb456c6 100644
--- a/fs/attr.c
+++ b/fs/attr.c
@@ -486,6 +486,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 fdf075a6b1bb..995d30336cfa 100644
--- a/include/linux/lsm_hook_defs.h
+++ b/include/linux/lsm_hook_defs.h
@@ -136,6 +136,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 dcb3604ffab8..820899db5276 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -355,6 +355,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,
@@ -856,6 +858,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 2b24d01cf181..764a6f28b3b9 100644
--- a/security/security.c
+++ b/security/security.c
@@ -2124,6 +2124,22 @@ int security_inode_setattr(struct mnt_idmap *idmap,
 }
 EXPORT_SYMBOL_GPL(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 *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_getattr() - Check if getting file attributes is allowed
  * @path: file
-- 
2.34.1


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

* [PATCH v2 13/25] security: Introduce inode_post_removexattr hook
  2023-08-31 10:41 [PATCH v2 00/25] security: Move IMA and EVM to the LSM infrastructure Roberto Sassu
                   ` (11 preceding siblings ...)
  2023-08-31 10:41 ` [PATCH v2 12/25] security: Introduce inode_post_setattr hook Roberto Sassu
@ 2023-08-31 10:41 ` Roberto Sassu
  2023-08-31 22:30   ` Casey Schaufler
  2023-09-04 21:11   ` Jarkko Sakkinen
  2023-08-31 10:41 ` [PATCH v2 14/25] security: Introduce file_post_open hook Roberto Sassu
                   ` (12 subsequent siblings)
  25 siblings, 2 replies; 48+ messages in thread
From: Roberto Sassu @ 2023-08-31 10:41 UTC (permalink / raw)
  To: viro, brauner, chuck.lever, jlayton, neilb, kolga, Dai.Ngo, tom,
	zohar, dmitry.kasatkin, paul, jmorris, serge, dhowells, jarkko,
	stephen.smalley.work, eparis, casey
  Cc: linux-fsdevel, linux-kernel, linux-nfs, linux-integrity,
	linux-security-module, keyrings, selinux, Roberto Sassu,
	Stefan Berger

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>
---
 fs/xattr.c                    |  9 +++++----
 include/linux/lsm_hook_defs.h |  2 ++
 include/linux/security.h      |  5 +++++
 security/security.c           | 14 ++++++++++++++
 4 files changed, 26 insertions(+), 4 deletions(-)

diff --git a/fs/xattr.c b/fs/xattr.c
index e7bbb7f57557..4a0280295686 100644
--- a/fs/xattr.c
+++ b/fs/xattr.c
@@ -552,11 +552,12 @@ __vfs_removexattr_locked(struct mnt_idmap *idmap,
 		goto out;
 
 	error = __vfs_removexattr(idmap, dentry, name);
+	if (error)
+		goto out;
 
-	if (!error) {
-		fsnotify_xattr(dentry);
-		evm_inode_post_removexattr(dentry, name);
-	}
+	fsnotify_xattr(dentry);
+	security_inode_post_removexattr(dentry, name);
+	evm_inode_post_removexattr(dentry, name);
 
 out:
 	return error;
diff --git a/include/linux/lsm_hook_defs.h b/include/linux/lsm_hook_defs.h
index 995d30336cfa..1153e7163b8b 100644
--- a/include/linux/lsm_hook_defs.h
+++ b/include/linux/lsm_hook_defs.h
@@ -148,6 +148,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 820899db5276..665bba3e0081 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -374,6 +374,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,
@@ -919,6 +920,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 764a6f28b3b9..3947159ba5e9 100644
--- a/security/security.c
+++ b/security/security.c
@@ -2354,6 +2354,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.34.1


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

* [PATCH v2 14/25] security: Introduce file_post_open hook
  2023-08-31 10:41 [PATCH v2 00/25] security: Move IMA and EVM to the LSM infrastructure Roberto Sassu
                   ` (12 preceding siblings ...)
  2023-08-31 10:41 ` [PATCH v2 13/25] security: Introduce inode_post_removexattr hook Roberto Sassu
@ 2023-08-31 10:41 ` Roberto Sassu
  2023-08-31 22:33   ` Casey Schaufler
  2023-08-31 10:41 ` [PATCH v2 15/25] security: Introduce file_pre_free_security hook Roberto Sassu
                   ` (11 subsequent siblings)
  25 siblings, 1 reply; 48+ messages in thread
From: Roberto Sassu @ 2023-08-31 10:41 UTC (permalink / raw)
  To: viro, brauner, chuck.lever, jlayton, neilb, kolga, Dai.Ngo, tom,
	zohar, dmitry.kasatkin, paul, jmorris, serge, dhowells, jarkko,
	stephen.smalley.work, eparis, casey
  Cc: linux-fsdevel, linux-kernel, linux-nfs, linux-integrity,
	linux-security-module, keyrings, selinux, Roberto Sassu,
	Stefan Berger

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>
Reviewed-by: Stefan Berger <stefanb@linux.ibm.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 1f5ec71360de..7dc4626859f0 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -3634,6 +3634,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 8a2321d19194..3450bb1c8a18 100644
--- a/fs/nfsd/vfs.c
+++ b/fs/nfsd/vfs.c
@@ -862,6 +862,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 1153e7163b8b..60ed33f0c80d 100644
--- a/include/linux/lsm_hook_defs.h
+++ b/include/linux/lsm_hook_defs.h
@@ -188,6 +188,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 665bba3e0081..a0f16511c059 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -403,6 +403,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);
@@ -1044,6 +1045,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 3947159ba5e9..3e0078b51e46 100644
--- a/security/security.c
+++ b/security/security.c
@@ -2856,6 +2856,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.34.1


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

* [PATCH v2 15/25] security: Introduce file_pre_free_security hook
  2023-08-31 10:41 [PATCH v2 00/25] security: Move IMA and EVM to the LSM infrastructure Roberto Sassu
                   ` (13 preceding siblings ...)
  2023-08-31 10:41 ` [PATCH v2 14/25] security: Introduce file_post_open hook Roberto Sassu
@ 2023-08-31 10:41 ` Roberto Sassu
  2023-08-31 22:34   ` Casey Schaufler
  2023-08-31 10:41 ` [PATCH v2 16/25] security: Introduce path_post_mknod hook Roberto Sassu
                   ` (10 subsequent siblings)
  25 siblings, 1 reply; 48+ messages in thread
From: Roberto Sassu @ 2023-08-31 10:41 UTC (permalink / raw)
  To: viro, brauner, chuck.lever, jlayton, neilb, kolga, Dai.Ngo, tom,
	zohar, dmitry.kasatkin, paul, jmorris, serge, dhowells, jarkko,
	stephen.smalley.work, eparis, casey
  Cc: linux-fsdevel, linux-kernel, linux-nfs, linux-integrity,
	linux-security-module, keyrings, selinux, Roberto Sassu,
	Stefan Berger

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>
---
 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 fc7d677ff5ad..964e24120684 100644
--- a/fs/file_table.c
+++ b/fs/file_table.c
@@ -375,6 +375,7 @@ static void __fput(struct file *file)
 	eventpoll_release(file);
 	locks_remove_file(file);
 
+	security_file_pre_free(file);
 	ima_file_free(file);
 	if (unlikely(file->f_flags & FASYNC)) {
 		if (file->f_op->fasync)
diff --git a/include/linux/lsm_hook_defs.h b/include/linux/lsm_hook_defs.h
index 60ed33f0c80d..797f51da3f7d 100644
--- a/include/linux/lsm_hook_defs.h
+++ b/include/linux/lsm_hook_defs.h
@@ -172,6 +172,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 a0f16511c059..7871009d59ae 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -389,6 +389,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,
@@ -985,6 +986,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 3e0078b51e46..3e648aa9292c 100644
--- a/security/security.c
+++ b/security/security.c
@@ -2626,6 +2626,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.34.1


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

* [PATCH v2 16/25] security: Introduce path_post_mknod hook
  2023-08-31 10:41 [PATCH v2 00/25] security: Move IMA and EVM to the LSM infrastructure Roberto Sassu
                   ` (14 preceding siblings ...)
  2023-08-31 10:41 ` [PATCH v2 15/25] security: Introduce file_pre_free_security hook Roberto Sassu
@ 2023-08-31 10:41 ` Roberto Sassu
  2023-08-31 22:34   ` Casey Schaufler
  2023-08-31 10:41 ` [PATCH v2 17/25] security: Introduce inode_post_create_tmpfile hook Roberto Sassu
                   ` (9 subsequent siblings)
  25 siblings, 1 reply; 48+ messages in thread
From: Roberto Sassu @ 2023-08-31 10:41 UTC (permalink / raw)
  To: viro, brauner, chuck.lever, jlayton, neilb, kolga, Dai.Ngo, tom,
	zohar, dmitry.kasatkin, paul, jmorris, serge, dhowells, jarkko,
	stephen.smalley.work, eparis, casey
  Cc: linux-fsdevel, linux-kernel, linux-nfs, linux-integrity,
	linux-security-module, keyrings, selinux, 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                    |  5 +++++
 include/linux/lsm_hook_defs.h |  3 +++
 include/linux/security.h      |  9 +++++++++
 security/security.c           | 19 +++++++++++++++++++
 4 files changed, 36 insertions(+)

diff --git a/fs/namei.c b/fs/namei.c
index 7dc4626859f0..c8c4ab26b52a 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -4061,6 +4061,11 @@ static int do_mknodat(int dfd, struct filename *name, umode_t mode,
 					  dentry, mode, 0);
 			break;
 	}
+
+	if (error)
+		goto out2;
+
+	security_path_post_mknod(idmap, &path, dentry, mode_stripped, 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 797f51da3f7d..b1634b5de98c 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 7871009d59ae..f210bd66e939 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -1842,6 +1842,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);
@@ -1876,6 +1879,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 3e648aa9292c..56c1c1e66fd1 100644
--- a/security/security.c
+++ b/security/security.c
@@ -1702,6 +1702,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.34.1


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

* [PATCH v2 17/25] security: Introduce inode_post_create_tmpfile hook
  2023-08-31 10:41 [PATCH v2 00/25] security: Move IMA and EVM to the LSM infrastructure Roberto Sassu
                   ` (15 preceding siblings ...)
  2023-08-31 10:41 ` [PATCH v2 16/25] security: Introduce path_post_mknod hook Roberto Sassu
@ 2023-08-31 10:41 ` Roberto Sassu
  2023-08-31 22:35   ` Casey Schaufler
  2023-08-31 10:41 ` [PATCH v2 18/25] security: Introduce inode_post_set_acl hook Roberto Sassu
                   ` (8 subsequent siblings)
  25 siblings, 1 reply; 48+ messages in thread
From: Roberto Sassu @ 2023-08-31 10:41 UTC (permalink / raw)
  To: viro, brauner, chuck.lever, jlayton, neilb, kolga, Dai.Ngo, tom,
	zohar, dmitry.kasatkin, paul, jmorris, serge, dhowells, jarkko,
	stephen.smalley.work, eparis, casey
  Cc: linux-fsdevel, linux-kernel, linux-nfs, linux-integrity,
	linux-security-module, keyrings, selinux, Roberto Sassu,
	Stefan Berger

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>
Reviewed-by: Stefan Berger <stefanb@linux.ibm.com>
---
 fs/namei.c                    |  1 +
 include/linux/lsm_hook_defs.h |  2 ++
 include/linux/security.h      |  8 ++++++++
 security/security.c           | 18 ++++++++++++++++++
 4 files changed, 29 insertions(+)

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


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

* [PATCH v2 18/25] security: Introduce inode_post_set_acl hook
  2023-08-31 10:41 [PATCH v2 00/25] security: Move IMA and EVM to the LSM infrastructure Roberto Sassu
                   ` (16 preceding siblings ...)
  2023-08-31 10:41 ` [PATCH v2 17/25] security: Introduce inode_post_create_tmpfile hook Roberto Sassu
@ 2023-08-31 10:41 ` Roberto Sassu
  2023-08-31 22:36   ` Casey Schaufler
  2023-08-31 10:41 ` [PATCH v2 19/25] security: Introduce inode_post_remove_acl hook Roberto Sassu
                   ` (7 subsequent siblings)
  25 siblings, 1 reply; 48+ messages in thread
From: Roberto Sassu @ 2023-08-31 10:41 UTC (permalink / raw)
  To: viro, brauner, chuck.lever, jlayton, neilb, kolga, Dai.Ngo, tom,
	zohar, dmitry.kasatkin, paul, jmorris, serge, dhowells, jarkko,
	stephen.smalley.work, eparis, casey
  Cc: linux-fsdevel, linux-kernel, linux-nfs, linux-integrity,
	linux-security-module, keyrings, selinux, Roberto Sassu,
	Stefan Berger

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>
Reviewed-by: Stefan Berger <stefanb@linux.ibm.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 7fa1b738bbab..3b7dbea5c3ff 100644
--- a/fs/posix_acl.c
+++ b/fs/posix_acl.c
@@ -1137,6 +1137,7 @@ int vfs_set_acl(struct mnt_idmap *idmap, struct dentry *dentry,
 		error = -EIO;
 	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 9ae573b83737..bba1fbd97207 100644
--- a/include/linux/lsm_hook_defs.h
+++ b/include/linux/lsm_hook_defs.h
@@ -157,6 +157,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 5f296761883f..556d019ebe5c 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -367,6 +367,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,
@@ -894,6 +896,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 e5acb11f6ebd..4392fd878d58 100644
--- a/security/security.c
+++ b/security/security.c
@@ -2260,6 +2260,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 security after set_acl()
+ * @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.34.1


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

* [PATCH v2 19/25] security: Introduce inode_post_remove_acl hook
  2023-08-31 10:41 [PATCH v2 00/25] security: Move IMA and EVM to the LSM infrastructure Roberto Sassu
                   ` (17 preceding siblings ...)
  2023-08-31 10:41 ` [PATCH v2 18/25] security: Introduce inode_post_set_acl hook Roberto Sassu
@ 2023-08-31 10:41 ` Roberto Sassu
  2023-08-31 22:36   ` Casey Schaufler
  2023-08-31 11:37 ` [PATCH v2 20/25] security: Introduce key_post_create_or_update hook Roberto Sassu
                   ` (6 subsequent siblings)
  25 siblings, 1 reply; 48+ messages in thread
From: Roberto Sassu @ 2023-08-31 10:41 UTC (permalink / raw)
  To: viro, brauner, chuck.lever, jlayton, neilb, kolga, Dai.Ngo, tom,
	zohar, dmitry.kasatkin, paul, jmorris, serge, dhowells, jarkko,
	stephen.smalley.work, eparis, casey
  Cc: linux-fsdevel, linux-kernel, linux-nfs, linux-integrity,
	linux-security-module, keyrings, selinux, 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 3b7dbea5c3ff..2a2a2750b3e9 100644
--- a/fs/posix_acl.c
+++ b/fs/posix_acl.c
@@ -1246,6 +1246,7 @@ int vfs_remove_acl(struct mnt_idmap *idmap, struct dentry *dentry,
 		error = -EIO;
 	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 bba1fbd97207..eedc26790a07 100644
--- a/include/linux/lsm_hook_defs.h
+++ b/include/linux/lsm_hook_defs.h
@@ -163,6 +163,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 556d019ebe5c..e543ae80309b 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -373,6 +373,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);
@@ -915,6 +918,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 4392fd878d58..32c3dc34432e 100644
--- a/security/security.c
+++ b/security/security.c
@@ -2323,6 +2323,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.34.1


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

* [PATCH v2 20/25] security: Introduce key_post_create_or_update hook
  2023-08-31 10:41 [PATCH v2 00/25] security: Move IMA and EVM to the LSM infrastructure Roberto Sassu
                   ` (18 preceding siblings ...)
  2023-08-31 10:41 ` [PATCH v2 19/25] security: Introduce inode_post_remove_acl hook Roberto Sassu
@ 2023-08-31 11:37 ` Roberto Sassu
  2023-08-31 22:37   ` Casey Schaufler
  2023-08-31 11:37 ` [PATCH v2 21/25] ima: Move to LSM infrastructure Roberto Sassu
                   ` (5 subsequent siblings)
  25 siblings, 1 reply; 48+ messages in thread
From: Roberto Sassu @ 2023-08-31 11:37 UTC (permalink / raw)
  To: viro, brauner, chuck.lever, jlayton, neilb, kolga, Dai.Ngo, tom,
	zohar, dmitry.kasatkin, paul, jmorris, serge, dhowells, jarkko,
	stephen.smalley.work, eparis, casey
  Cc: linux-fsdevel, linux-kernel, linux-nfs, linux-integrity,
	linux-security-module, keyrings, selinux, Roberto Sassu,
	Stefan Berger

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>
---
 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 eedc26790a07..7512b4c46aa8 100644
--- a/include/linux/lsm_hook_defs.h
+++ b/include/linux/lsm_hook_defs.h
@@ -399,6 +399,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 e543ae80309b..f50b78481753 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -1959,6 +1959,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
 
@@ -1986,6 +1989,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 5c0c7df833f8..0f9c6faf3491 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 32c3dc34432e..e6783c2f0c65 100644
--- a/security/security.c
+++ b/security/security.c
@@ -5169,6 +5169,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() - Notification of key create 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.34.1


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

* [PATCH v2 21/25] ima: Move to LSM infrastructure
  2023-08-31 10:41 [PATCH v2 00/25] security: Move IMA and EVM to the LSM infrastructure Roberto Sassu
                   ` (19 preceding siblings ...)
  2023-08-31 11:37 ` [PATCH v2 20/25] security: Introduce key_post_create_or_update hook Roberto Sassu
@ 2023-08-31 11:37 ` Roberto Sassu
  2023-08-31 14:10   ` Chuck Lever
  2023-08-31 22:42   ` Casey Schaufler
  2023-08-31 11:38 ` [PATCH v2 22/25] ima: Move IMA-Appraisal " Roberto Sassu
                   ` (4 subsequent siblings)
  25 siblings, 2 replies; 48+ messages in thread
From: Roberto Sassu @ 2023-08-31 11:37 UTC (permalink / raw)
  To: viro, brauner, chuck.lever, jlayton, neilb, kolga, Dai.Ngo, tom,
	zohar, dmitry.kasatkin, paul, jmorris, serge, dhowells, jarkko,
	stephen.smalley.work, eparis, casey
  Cc: linux-fsdevel, linux-kernel, linux-nfs, linux-integrity,
	linux-security-module, keyrings, selinux, 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().

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               | 94 -------------------------------
 security/integrity/iint.c         |  7 ++-
 security/integrity/ima/ima.h      |  6 ++
 security/integrity/ima/ima_main.c | 63 ++++++++++++++-------
 security/integrity/integrity.h    |  9 +++
 security/keys/key.c               |  9 +--
 security/security.c               | 53 +++--------------
 11 files changed, 72 insertions(+), 186 deletions(-)

diff --git a/fs/file_table.c b/fs/file_table.c
index 964e24120684..7b9c756a42df 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>
 
@@ -376,7 +375,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 efed0e1e93f5..a200021209c3 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>
@@ -3636,8 +3635,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)) {
@@ -3701,7 +3698,6 @@ static int vfs_tmpfile(struct mnt_idmap *idmap,
 		spin_unlock(&inode->i_lock);
 	}
 	security_inode_post_create_tmpfile(idmap, dir, file, mode);
-	ima_post_create_tmpfile(idmap, dir, file, mode);
 	return 0;
 }
 
@@ -4049,9 +4045,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_stripped, 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 3450bb1c8a18..94bbd7ac8b68 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>
@@ -868,12 +867,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 0c55c8e7f837..6825ac1d07a9 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 6e4d060ff378..58591b5cbdb4 100644
--- a/include/linux/ima.h
+++ b/include/linux/ima.h
@@ -16,26 +16,7 @@ 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 file *file,
-				    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);
-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);
-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 +41,11 @@ 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 file *file,
-					   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 +96,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 a462df827de2..32f0f3c5c4dd 100644
--- a/security/integrity/iint.c
+++ b/security/integrity/iint.c
@@ -167,20 +167,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 c29db699c996..c0412100023e 100644
--- a/security/integrity/ima/ima.h
+++ b/security/integrity/ima/ima.h
@@ -127,6 +127,12 @@ 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
+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 f8581032e62c..0e4f882fcdce 100644
--- a/security/integrity/ima/ima_main.c
+++ b/security/integrity/ima/ima_main.c
@@ -188,7 +188,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;
@@ -413,8 +413,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;
@@ -452,8 +452,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;
@@ -511,7 +511,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;
@@ -673,9 +673,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 file *file,
-			     umode_t mode)
+static void ima_post_create_tmpfile(struct mnt_idmap *idmap, struct inode *dir,
+				    struct file *file, umode_t mode)
 {
 	struct integrity_iint_cache *iint;
 	struct inode *inode = file_inode(file);
@@ -710,9 +709,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;
@@ -751,8 +750,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;
@@ -801,8 +800,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;
@@ -835,7 +834,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;
 
@@ -889,9 +888,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) &&
@@ -1120,4 +1119,28 @@ static int __init init_ima(void)
 	return error;
 }
 
+static struct security_hook_list ima_hooks[] __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 7167a6e99bdc..7adc7d6c4f9f 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
@@ -191,6 +192,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 0f9c6faf3491..2acf9fa80735 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 e6783c2f0c65..8c5b8ffeef92 100644
--- a/security/security.c
+++ b/security/security.c
@@ -1098,12 +1098,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);
 }
 
 /**
@@ -2793,13 +2788,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);
 }
 
 /**
@@ -2828,12 +2818,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);
 }
 
 /**
@@ -3163,12 +3148,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);
 
@@ -3188,12 +3168,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);
 
@@ -3208,12 +3183,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);
 
@@ -3235,13 +3205,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.34.1


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

* [PATCH v2 22/25] ima: Move IMA-Appraisal to LSM infrastructure
  2023-08-31 10:41 [PATCH v2 00/25] security: Move IMA and EVM to the LSM infrastructure Roberto Sassu
                   ` (20 preceding siblings ...)
  2023-08-31 11:37 ` [PATCH v2 21/25] ima: Move to LSM infrastructure Roberto Sassu
@ 2023-08-31 11:38 ` Roberto Sassu
  2023-08-31 11:38 ` [PATCH v2 23/25] evm: Move " Roberto Sassu
                   ` (3 subsequent siblings)
  25 siblings, 0 replies; 48+ messages in thread
From: Roberto Sassu @ 2023-08-31 11:38 UTC (permalink / raw)
  To: viro, brauner, chuck.lever, jlayton, neilb, kolga, Dai.Ngo, tom,
	zohar, dmitry.kasatkin, paul, jmorris, serge, dhowells, jarkko,
	stephen.smalley.work, eparis, casey
  Cc: linux-fsdevel, linux-kernel, linux-nfs, linux-integrity,
	linux-security-module, keyrings, selinux, 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                   | 55 ---------------------------
 security/integrity/ima/ima.h          |  5 +++
 security/integrity/ima/ima_appraise.c | 38 +++++++++++++-----
 security/integrity/ima/ima_main.c     |  1 +
 security/security.c                   | 13 -------
 6 files changed, 35 insertions(+), 79 deletions(-)

diff --git a/fs/attr.c b/fs/attr.c
index 3c309eb456c6..63fb60195409 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"
 
@@ -487,7 +486,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 58591b5cbdb4..586e2e18e494 100644
--- a/include/linux/ima.h
+++ b/include/linux/ima.h
@@ -98,66 +98,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);
-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);
-}
-
-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 c0412100023e..d19aa9c068da 100644
--- a/security/integrity/ima/ima.h
+++ b/security/integrity/ima/ima.h
@@ -334,6 +334,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,
@@ -385,6 +386,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 c35e3537eb87..8fe6ea70f02b 100644
--- a/security/integrity/ima/ima_appraise.c
+++ b/security/integrity/ima/ima_appraise.c
@@ -634,8 +634,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 +748,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 +779,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 +788,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 +801,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[] __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 0e4f882fcdce..c31e11a5bc31 100644
--- a/security/integrity/ima/ima_main.c
+++ b/security/integrity/ima/ima_main.c
@@ -1141,6 +1141,7 @@ static struct security_hook_list ima_hooks[] __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 8c5b8ffeef92..dc863210c96e 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>
@@ -2217,9 +2216,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);
@@ -2247,9 +2243,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);
@@ -2310,9 +2303,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);
@@ -2412,9 +2402,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.34.1


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

* [PATCH v2 23/25] evm: Move to LSM infrastructure
  2023-08-31 10:41 [PATCH v2 00/25] security: Move IMA and EVM to the LSM infrastructure Roberto Sassu
                   ` (21 preceding siblings ...)
  2023-08-31 11:38 ` [PATCH v2 22/25] ima: Move IMA-Appraisal " Roberto Sassu
@ 2023-08-31 11:38 ` Roberto Sassu
  2023-08-31 22:46   ` Casey Schaufler
  2023-08-31 11:38 ` [PATCH v2 24/25] integrity: Move integrity functions to the " Roberto Sassu
                   ` (2 subsequent siblings)
  25 siblings, 1 reply; 48+ messages in thread
From: Roberto Sassu @ 2023-08-31 11:38 UTC (permalink / raw)
  To: viro, brauner, chuck.lever, jlayton, neilb, kolga, Dai.Ngo, tom,
	zohar, dmitry.kasatkin, paul, jmorris, serge, dhowells, jarkko,
	stephen.smalley.work, eparis, casey
  Cc: linux-fsdevel, linux-kernel, linux-nfs, linux-integrity,
	linux-security-module, keyrings, selinux, 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, and
consequently decrement by one 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               | 107 ------------------------------
 security/integrity/evm/evm_main.c | 103 +++++++++++++++++++++++-----
 security/integrity/iint.c         |   7 ++
 security/integrity/integrity.h    |   9 +++
 security/security.c               |  42 +++---------
 8 files changed, 113 insertions(+), 162 deletions(-)

diff --git a/fs/attr.c b/fs/attr.c
index 63fb60195409..4153f83a4a1f 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"
 
@@ -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);
-		evm_inode_post_setattr(idmap, dentry, ia_valid);
 	}
 
 	return error;
diff --git a/fs/posix_acl.c b/fs/posix_acl.c
index 2a2a2750b3e9..5cea0df45d3b 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>
 
@@ -1138,7 +1137,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:
@@ -1247,7 +1245,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 4a0280295686..4495e0b4d003 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>
@@ -557,7 +556,6 @@ __vfs_removexattr_locked(struct mnt_idmap *idmap,
 
 	fsnotify_xattr(dentry);
 	security_inode_post_removexattr(dentry, name);
-	evm_inode_post_removexattr(dentry, name);
 
 out:
 	return error;
diff --git a/include/linux/evm.h b/include/linux/evm.h
index 642e52483adc..cb481eccc967 100644
--- a/include/linux/evm.h
+++ b/include/linux/evm.h
@@ -21,44 +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);
-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);
-}
-
 int evm_inode_init_security(struct inode *inode, struct inode *dir,
 			    const struct qstr *qstr, struct xattr *xattrs,
 			    int *xattr_count);
@@ -93,75 +55,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,
diff --git a/security/integrity/evm/evm_main.c b/security/integrity/evm/evm_main.c
index 2e8f6d1c9984..adbb996e681d 100644
--- a/security/integrity/evm/evm_main.c
+++ b/security/integrity/evm/evm_main.c
@@ -567,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;
 
@@ -599,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
@@ -650,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;
 
@@ -691,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;
@@ -739,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;
@@ -757,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
@@ -767,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;
@@ -783,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)
 {
@@ -806,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;
@@ -854,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;
@@ -965,4 +1019,23 @@ static int __init init_evm(void)
 	return error;
 }
 
+static struct security_hook_list evm_hooks[] __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 32f0f3c5c4dd..dd03f978b45c 100644
--- a/security/integrity/iint.c
+++ b/security/integrity/iint.c
@@ -174,12 +174,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 __ro_after_init = {
+	.lbs_xattr_count = 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 7adc7d6c4f9f..83a465ac9013 100644
--- a/security/integrity/integrity.h
+++ b/security/integrity/integrity.h
@@ -189,6 +189,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;
 
@@ -200,6 +201,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 dc863210c96e..9ba36a8e5d65 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>
 
@@ -1616,8 +1616,8 @@ int security_inode_init_security(struct inode *inode, struct inode *dir,
 		return 0;
 
 	if (initxattrs) {
-		/* Allocate +1 for EVM and +1 as terminator. */
-		new_xattrs = kcalloc(blob_sizes.lbs_xattr_count + 2,
+		/* Allocate +1 as terminator. */
+		new_xattrs = kcalloc(blob_sizes.lbs_xattr_count + 1,
 				     sizeof(*new_xattrs), GFP_NOFS);
 		if (!new_xattrs)
 			return -ENOMEM;
@@ -1641,10 +1641,6 @@ int security_inode_init_security(struct inode *inode, struct inode *dir,
 	if (!xattr_count)
 		goto out;
 
-	ret = evm_inode_init_security(inode, dir, qstr, new_xattrs,
-				      &xattr_count);
-	if (ret)
-		goto out;
 	ret = initxattrs(inode, new_xattrs, fs_data);
 out:
 	for (; xattr_count > 0; xattr_count--)
@@ -2144,14 +2140,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);
 
@@ -2216,9 +2207,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;
 }
 
 /**
@@ -2237,15 +2226,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);
 }
 
 /**
@@ -2298,14 +2282,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);
 }
 
 /**
@@ -2341,7 +2320,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);
 }
 
 /**
@@ -2402,9 +2380,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.34.1


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

* [PATCH v2 24/25] integrity: Move integrity functions to the LSM infrastructure
  2023-08-31 10:41 [PATCH v2 00/25] security: Move IMA and EVM to the LSM infrastructure Roberto Sassu
                   ` (22 preceding siblings ...)
  2023-08-31 11:38 ` [PATCH v2 23/25] evm: Move " Roberto Sassu
@ 2023-08-31 11:38 ` Roberto Sassu
  2023-08-31 22:49   ` Casey Schaufler
  2023-08-31 11:38 ` [PATCH v2 25/25] integrity: Switch from rbtree to LSM-managed blob for integrity_iint_cache Roberto Sassu
  2023-08-31 23:01 ` [PATCH v2 00/25] security: Move IMA and EVM to the LSM infrastructure Casey Schaufler
  25 siblings, 1 reply; 48+ messages in thread
From: Roberto Sassu @ 2023-08-31 11:38 UTC (permalink / raw)
  To: viro, brauner, chuck.lever, jlayton, neilb, kolga, Dai.Ngo, tom,
	zohar, dmitry.kasatkin, paul, jmorris, serge, dhowells, jarkko,
	stephen.smalley.work, eparis, casey
  Cc: linux-fsdevel, linux-kernel, linux-nfs, linux-integrity,
	linux-security-module, keyrings, selinux, 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 2ea0f2f65ab6..afaae7ad26f4 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 dd03f978b45c..70ee803a33ea 100644
--- a/security/integrity/iint.c
+++ b/security/integrity/iint.c
@@ -138,7 +138,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;
 
@@ -167,12 +167,21 @@ static void init_once(void *foo)
 	mutex_init(&iint->mutex);
 }
 
+static struct security_hook_list integrity_hooks[] __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 83a465ac9013..e020c365997b 100644
--- a/security/integrity/integrity.h
+++ b/security/integrity/integrity.h
@@ -178,6 +178,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);
@@ -251,12 +252,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);
+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 9ba36a8e5d65..e9275335aaa7 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>
@@ -1497,7 +1496,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
@@ -3090,12 +3088,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.34.1


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

* [PATCH v2 25/25] integrity: Switch from rbtree to LSM-managed blob for integrity_iint_cache
  2023-08-31 10:41 [PATCH v2 00/25] security: Move IMA and EVM to the LSM infrastructure Roberto Sassu
                   ` (23 preceding siblings ...)
  2023-08-31 11:38 ` [PATCH v2 24/25] integrity: Move integrity functions to the " Roberto Sassu
@ 2023-08-31 11:38 ` Roberto Sassu
  2023-08-31 23:05   ` Casey Schaufler
  2023-08-31 23:01 ` [PATCH v2 00/25] security: Move IMA and EVM to the LSM infrastructure Casey Schaufler
  25 siblings, 1 reply; 48+ messages in thread
From: Roberto Sassu @ 2023-08-31 11:38 UTC (permalink / raw)
  To: viro, brauner, chuck.lever, jlayton, neilb, kolga, Dai.Ngo, tom,
	zohar, dmitry.kasatkin, paul, jmorris, serge, dhowells, jarkko,
	stephen.smalley.work, eparis, casey
  Cc: linux-fsdevel, linux-kernel, linux-nfs, linux-integrity,
	linux-security-module, keyrings, selinux, 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      | 67 +++-------------------------------
 security/integrity/integrity.h | 19 +++++++++-
 2 files changed, 24 insertions(+), 62 deletions(-)

diff --git a/security/integrity/iint.c b/security/integrity/iint.c
index 70ee803a33ea..c2fba8afbbdb 100644
--- a/security/integrity/iint.c
+++ b/security/integrity/iint.c
@@ -14,56 +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
-			return iint;
-	}
-
-	return NULL;
-}
-
 /*
  * 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)
@@ -92,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;
 
 	iint = integrity_iint_find(inode);
 	if (iint)
@@ -104,31 +71,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 if (inode > test_iint->inode) {
-			p = &(*p)->rb_right;
-		} else {
-			write_unlock(&integrity_iint_lock);
-			kmem_cache_free(iint_cache, iint);
-			return test_iint;
-		}
-	}
-
 	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;
 }
 
@@ -145,10 +91,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);
 }
@@ -188,6 +132,7 @@ static int __init integrity_lsm_init(void)
 }
 
 struct lsm_blob_sizes integrity_blob_sizes __ro_after_init = {
+	.lbs_inode = sizeof(struct integrity_iint_cache *),
 	.lbs_xattr_count = 1,
 };
 
diff --git a/security/integrity/integrity.h b/security/integrity/integrity.h
index e020c365997b..24de4ad4a37e 100644
--- a/security/integrity/integrity.h
+++ b/security/integrity/integrity.h
@@ -158,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 */
@@ -192,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.34.1


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

* Re: [PATCH v2 21/25] ima: Move to LSM infrastructure
  2023-08-31 11:37 ` [PATCH v2 21/25] ima: Move to LSM infrastructure Roberto Sassu
@ 2023-08-31 14:10   ` Chuck Lever
  2023-08-31 22:42   ` Casey Schaufler
  1 sibling, 0 replies; 48+ messages in thread
From: Chuck Lever @ 2023-08-31 14:10 UTC (permalink / raw)
  To: Roberto Sassu
  Cc: viro, brauner, jlayton, neilb, kolga, Dai.Ngo, tom, zohar,
	dmitry.kasatkin, paul, jmorris, serge, dhowells, jarkko,
	stephen.smalley.work, eparis, casey, linux-fsdevel, linux-kernel,
	linux-nfs, linux-integrity, linux-security-module, keyrings,
	selinux, Roberto Sassu

On Thu, Aug 31, 2023 at 01:37:59PM +0200, Roberto Sassu wrote:
> 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().
> 
> Signed-off-by: Roberto Sassu <roberto.sassu@huawei.com>
> ---
>  fs/file_table.c                   |  2 -
>  fs/namei.c                        |  7 ---
>  fs/nfsd/vfs.c                     |  7 ---

For the NFSD part:

Acked-by: Chuck Lever <chuck.lever@oracle.com>


>  fs/open.c                         |  1 -
>  include/linux/ima.h               | 94 -------------------------------
>  security/integrity/iint.c         |  7 ++-
>  security/integrity/ima/ima.h      |  6 ++
>  security/integrity/ima/ima_main.c | 63 ++++++++++++++-------
>  security/integrity/integrity.h    |  9 +++
>  security/keys/key.c               |  9 +--
>  security/security.c               | 53 +++--------------
>  11 files changed, 72 insertions(+), 186 deletions(-)
> 
> diff --git a/fs/file_table.c b/fs/file_table.c
> index 964e24120684..7b9c756a42df 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>
>  
> @@ -376,7 +375,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 efed0e1e93f5..a200021209c3 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>
> @@ -3636,8 +3635,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)) {
> @@ -3701,7 +3698,6 @@ static int vfs_tmpfile(struct mnt_idmap *idmap,
>  		spin_unlock(&inode->i_lock);
>  	}
>  	security_inode_post_create_tmpfile(idmap, dir, file, mode);
> -	ima_post_create_tmpfile(idmap, dir, file, mode);
>  	return 0;
>  }
>  
> @@ -4049,9 +4045,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_stripped, 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 3450bb1c8a18..94bbd7ac8b68 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>
> @@ -868,12 +867,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 0c55c8e7f837..6825ac1d07a9 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 6e4d060ff378..58591b5cbdb4 100644
> --- a/include/linux/ima.h
> +++ b/include/linux/ima.h
> @@ -16,26 +16,7 @@ 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 file *file,
> -				    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);
> -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);
> -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 +41,11 @@ 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 file *file,
> -					   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 +96,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 a462df827de2..32f0f3c5c4dd 100644
> --- a/security/integrity/iint.c
> +++ b/security/integrity/iint.c
> @@ -167,20 +167,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 c29db699c996..c0412100023e 100644
> --- a/security/integrity/ima/ima.h
> +++ b/security/integrity/ima/ima.h
> @@ -127,6 +127,12 @@ 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
> +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 f8581032e62c..0e4f882fcdce 100644
> --- a/security/integrity/ima/ima_main.c
> +++ b/security/integrity/ima/ima_main.c
> @@ -188,7 +188,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;
> @@ -413,8 +413,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;
> @@ -452,8 +452,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;
> @@ -511,7 +511,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;
> @@ -673,9 +673,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 file *file,
> -			     umode_t mode)
> +static void ima_post_create_tmpfile(struct mnt_idmap *idmap, struct inode *dir,
> +				    struct file *file, umode_t mode)
>  {
>  	struct integrity_iint_cache *iint;
>  	struct inode *inode = file_inode(file);
> @@ -710,9 +709,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;
> @@ -751,8 +750,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;
> @@ -801,8 +800,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;
> @@ -835,7 +834,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;
>  
> @@ -889,9 +888,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) &&
> @@ -1120,4 +1119,28 @@ static int __init init_ima(void)
>  	return error;
>  }
>  
> +static struct security_hook_list ima_hooks[] __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 7167a6e99bdc..7adc7d6c4f9f 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
> @@ -191,6 +192,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 0f9c6faf3491..2acf9fa80735 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 e6783c2f0c65..8c5b8ffeef92 100644
> --- a/security/security.c
> +++ b/security/security.c
> @@ -1098,12 +1098,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);
>  }
>  
>  /**
> @@ -2793,13 +2788,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);
>  }
>  
>  /**
> @@ -2828,12 +2818,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);
>  }
>  
>  /**
> @@ -3163,12 +3148,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);
>  
> @@ -3188,12 +3168,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);
>  
> @@ -3208,12 +3183,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);
>  
> @@ -3235,13 +3205,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.34.1
> 

-- 
Chuck Lever

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

* Re: [PATCH v2 12/25] security: Introduce inode_post_setattr hook
  2023-08-31 10:41 ` [PATCH v2 12/25] security: Introduce inode_post_setattr hook Roberto Sassu
@ 2023-08-31 22:28   ` Casey Schaufler
  2023-09-04 21:09   ` Jarkko Sakkinen
  1 sibling, 0 replies; 48+ messages in thread
From: Casey Schaufler @ 2023-08-31 22:28 UTC (permalink / raw)
  To: Roberto Sassu, viro, brauner, chuck.lever, jlayton, neilb, kolga,
	Dai.Ngo, tom, zohar, dmitry.kasatkin, paul, jmorris, serge,
	dhowells, jarkko, stephen.smalley.work, eparis
  Cc: linux-fsdevel, linux-kernel, linux-nfs, linux-integrity,
	linux-security-module, keyrings, selinux, Roberto Sassu,
	Stefan Berger, Casey Schaufler

On 8/31/2023 3:41 AM, 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.

Would you please include some explanation of how an LSM would use this hook?
You might start with a description of how it is used in IMA/EVM, and why that
could be generally useful.

>
> Signed-off-by: Roberto Sassu <roberto.sassu@huawei.com>
> Reviewed-by: Stefan Berger <stefanb@linux.ibm.com>
> 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 431f667726c7..3c309eb456c6 100644
> --- a/fs/attr.c
> +++ b/fs/attr.c
> @@ -486,6 +486,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 fdf075a6b1bb..995d30336cfa 100644
> --- a/include/linux/lsm_hook_defs.h
> +++ b/include/linux/lsm_hook_defs.h
> @@ -136,6 +136,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 dcb3604ffab8..820899db5276 100644
> --- a/include/linux/security.h
> +++ b/include/linux/security.h
> @@ -355,6 +355,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,
> @@ -856,6 +858,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 2b24d01cf181..764a6f28b3b9 100644
> --- a/security/security.c
> +++ b/security/security.c
> @@ -2124,6 +2124,22 @@ int security_inode_setattr(struct mnt_idmap *idmap,
>  }
>  EXPORT_SYMBOL_GPL(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 *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_getattr() - Check if getting file attributes is allowed
>   * @path: file

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

* Re: [PATCH v2 13/25] security: Introduce inode_post_removexattr hook
  2023-08-31 10:41 ` [PATCH v2 13/25] security: Introduce inode_post_removexattr hook Roberto Sassu
@ 2023-08-31 22:30   ` Casey Schaufler
  2023-09-04 21:11   ` Jarkko Sakkinen
  1 sibling, 0 replies; 48+ messages in thread
From: Casey Schaufler @ 2023-08-31 22:30 UTC (permalink / raw)
  To: Roberto Sassu, viro, brauner, chuck.lever, jlayton, neilb, kolga,
	Dai.Ngo, tom, zohar, dmitry.kasatkin, paul, jmorris, serge,
	dhowells, jarkko, stephen.smalley.work, eparis
  Cc: linux-fsdevel, linux-kernel, linux-nfs, linux-integrity,
	linux-security-module, keyrings, selinux, Roberto Sassu,
	Stefan Berger, Casey Schaufler

On 8/31/2023 3:41 AM, 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.

This applies to all new LSM hooks:

Would you please include some explanation of how an LSM would use this hook?
You might start with a description of how it is used in IMA/EVM, and why that
could be generally useful.

>
> Signed-off-by: Roberto Sassu <roberto.sassu@huawei.com>
> Reviewed-by: Stefan Berger <stefanb@linux.ibm.com>
> ---
>  fs/xattr.c                    |  9 +++++----
>  include/linux/lsm_hook_defs.h |  2 ++
>  include/linux/security.h      |  5 +++++
>  security/security.c           | 14 ++++++++++++++
>  4 files changed, 26 insertions(+), 4 deletions(-)
>
> diff --git a/fs/xattr.c b/fs/xattr.c
> index e7bbb7f57557..4a0280295686 100644
> --- a/fs/xattr.c
> +++ b/fs/xattr.c
> @@ -552,11 +552,12 @@ __vfs_removexattr_locked(struct mnt_idmap *idmap,
>  		goto out;
>  
>  	error = __vfs_removexattr(idmap, dentry, name);
> +	if (error)
> +		goto out;
>  
> -	if (!error) {
> -		fsnotify_xattr(dentry);
> -		evm_inode_post_removexattr(dentry, name);
> -	}
> +	fsnotify_xattr(dentry);
> +	security_inode_post_removexattr(dentry, name);
> +	evm_inode_post_removexattr(dentry, name);
>  
>  out:
>  	return error;
> diff --git a/include/linux/lsm_hook_defs.h b/include/linux/lsm_hook_defs.h
> index 995d30336cfa..1153e7163b8b 100644
> --- a/include/linux/lsm_hook_defs.h
> +++ b/include/linux/lsm_hook_defs.h
> @@ -148,6 +148,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 820899db5276..665bba3e0081 100644
> --- a/include/linux/security.h
> +++ b/include/linux/security.h
> @@ -374,6 +374,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,
> @@ -919,6 +920,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 764a6f28b3b9..3947159ba5e9 100644
> --- a/security/security.c
> +++ b/security/security.c
> @@ -2354,6 +2354,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

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

* Re: [PATCH v2 14/25] security: Introduce file_post_open hook
  2023-08-31 10:41 ` [PATCH v2 14/25] security: Introduce file_post_open hook Roberto Sassu
@ 2023-08-31 22:33   ` Casey Schaufler
  0 siblings, 0 replies; 48+ messages in thread
From: Casey Schaufler @ 2023-08-31 22:33 UTC (permalink / raw)
  To: Roberto Sassu, viro, brauner, chuck.lever, jlayton, neilb, kolga,
	Dai.Ngo, tom, zohar, dmitry.kasatkin, paul, jmorris, serge,
	dhowells, jarkko, stephen.smalley.work, eparis
  Cc: linux-fsdevel, linux-kernel, linux-nfs, linux-integrity,
	linux-security-module, keyrings, selinux, Roberto Sassu,
	Stefan Berger, Casey Schaufler


On 8/31/2023 3:41 AM, 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.

Repeat of new LSM hook general comment:
Would you please include some explanation of how an LSM would use this hook?
You might start with a description of how it is used in IMA/EVM, and why that
could be generally useful.

>
> Signed-off-by: Roberto Sassu <roberto.sassu@huawei.com>
> Reviewed-by: Stefan Berger <stefanb@linux.ibm.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 1f5ec71360de..7dc4626859f0 100644
> --- a/fs/namei.c
> +++ b/fs/namei.c
> @@ -3634,6 +3634,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 8a2321d19194..3450bb1c8a18 100644
> --- a/fs/nfsd/vfs.c
> +++ b/fs/nfsd/vfs.c
> @@ -862,6 +862,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 1153e7163b8b..60ed33f0c80d 100644
> --- a/include/linux/lsm_hook_defs.h
> +++ b/include/linux/lsm_hook_defs.h
> @@ -188,6 +188,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 665bba3e0081..a0f16511c059 100644
> --- a/include/linux/security.h
> +++ b/include/linux/security.h
> @@ -403,6 +403,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);
> @@ -1044,6 +1045,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 3947159ba5e9..3e0078b51e46 100644
> --- a/security/security.c
> +++ b/security/security.c
> @@ -2856,6 +2856,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

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

* Re: [PATCH v2 15/25] security: Introduce file_pre_free_security hook
  2023-08-31 10:41 ` [PATCH v2 15/25] security: Introduce file_pre_free_security hook Roberto Sassu
@ 2023-08-31 22:34   ` Casey Schaufler
  0 siblings, 0 replies; 48+ messages in thread
From: Casey Schaufler @ 2023-08-31 22:34 UTC (permalink / raw)
  To: Roberto Sassu, viro, brauner, chuck.lever, jlayton, neilb, kolga,
	Dai.Ngo, tom, zohar, dmitry.kasatkin, paul, jmorris, serge,
	dhowells, jarkko, stephen.smalley.work, eparis
  Cc: linux-fsdevel, linux-kernel, linux-nfs, linux-integrity,
	linux-security-module, keyrings, selinux, Roberto Sassu,
	Stefan Berger, Casey Schaufler

On 8/31/2023 3:41 AM, 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.

Repeat of new LSM hook general comment:
Would you please include some explanation of how an LSM would use this hook?
You might start with a description of how it is used in IMA/EVM, and why that
could be generally useful.

>
> Signed-off-by: Roberto Sassu <roberto.sassu@huawei.com>
> Reviewed-by: Stefan Berger <stefanb@linux.ibm.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 fc7d677ff5ad..964e24120684 100644
> --- a/fs/file_table.c
> +++ b/fs/file_table.c
> @@ -375,6 +375,7 @@ static void __fput(struct file *file)
>  	eventpoll_release(file);
>  	locks_remove_file(file);
>  
> +	security_file_pre_free(file);
>  	ima_file_free(file);
>  	if (unlikely(file->f_flags & FASYNC)) {
>  		if (file->f_op->fasync)
> diff --git a/include/linux/lsm_hook_defs.h b/include/linux/lsm_hook_defs.h
> index 60ed33f0c80d..797f51da3f7d 100644
> --- a/include/linux/lsm_hook_defs.h
> +++ b/include/linux/lsm_hook_defs.h
> @@ -172,6 +172,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 a0f16511c059..7871009d59ae 100644
> --- a/include/linux/security.h
> +++ b/include/linux/security.h
> @@ -389,6 +389,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,
> @@ -985,6 +986,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 3e0078b51e46..3e648aa9292c 100644
> --- a/security/security.c
> +++ b/security/security.c
> @@ -2626,6 +2626,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

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

* Re: [PATCH v2 16/25] security: Introduce path_post_mknod hook
  2023-08-31 10:41 ` [PATCH v2 16/25] security: Introduce path_post_mknod hook Roberto Sassu
@ 2023-08-31 22:34   ` Casey Schaufler
  0 siblings, 0 replies; 48+ messages in thread
From: Casey Schaufler @ 2023-08-31 22:34 UTC (permalink / raw)
  To: Roberto Sassu, viro, brauner, chuck.lever, jlayton, neilb, kolga,
	Dai.Ngo, tom, zohar, dmitry.kasatkin, paul, jmorris, serge,
	dhowells, jarkko, stephen.smalley.work, eparis
  Cc: linux-fsdevel, linux-kernel, linux-nfs, linux-integrity,
	linux-security-module, keyrings, selinux, Roberto Sassu,
	Casey Schaufler

On 8/31/2023 3:41 AM, 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.

Repeat of new LSM hook general comment:
Would you please include some explanation of how an LSM would use this hook?
You might start with a description of how it is used in IMA/EVM, and why that
could be generally useful.


>
> Signed-off-by: Roberto Sassu <roberto.sassu@huawei.com>
> ---
>  fs/namei.c                    |  5 +++++
>  include/linux/lsm_hook_defs.h |  3 +++
>  include/linux/security.h      |  9 +++++++++
>  security/security.c           | 19 +++++++++++++++++++
>  4 files changed, 36 insertions(+)
>
> diff --git a/fs/namei.c b/fs/namei.c
> index 7dc4626859f0..c8c4ab26b52a 100644
> --- a/fs/namei.c
> +++ b/fs/namei.c
> @@ -4061,6 +4061,11 @@ static int do_mknodat(int dfd, struct filename *name, umode_t mode,
>  					  dentry, mode, 0);
>  			break;
>  	}
> +
> +	if (error)
> +		goto out2;
> +
> +	security_path_post_mknod(idmap, &path, dentry, mode_stripped, 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 797f51da3f7d..b1634b5de98c 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 7871009d59ae..f210bd66e939 100644
> --- a/include/linux/security.h
> +++ b/include/linux/security.h
> @@ -1842,6 +1842,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);
> @@ -1876,6 +1879,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 3e648aa9292c..56c1c1e66fd1 100644
> --- a/security/security.c
> +++ b/security/security.c
> @@ -1702,6 +1702,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

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

* Re: [PATCH v2 17/25] security: Introduce inode_post_create_tmpfile hook
  2023-08-31 10:41 ` [PATCH v2 17/25] security: Introduce inode_post_create_tmpfile hook Roberto Sassu
@ 2023-08-31 22:35   ` Casey Schaufler
  0 siblings, 0 replies; 48+ messages in thread
From: Casey Schaufler @ 2023-08-31 22:35 UTC (permalink / raw)
  To: Roberto Sassu, viro, brauner, chuck.lever, jlayton, neilb, kolga,
	Dai.Ngo, tom, zohar, dmitry.kasatkin, paul, jmorris, serge,
	dhowells, jarkko, stephen.smalley.work, eparis
  Cc: linux-fsdevel, linux-kernel, linux-nfs, linux-integrity,
	linux-security-module, keyrings, selinux, Roberto Sassu,
	Stefan Berger, Casey Schaufler

On 8/31/2023 3:41 AM, 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.

Repeat of new LSM hook general comment:
Would you please include some explanation of how an LSM would use this hook?
You might start with a description of how it is used in IMA/EVM, and why that
could be generally useful.


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

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

* Re: [PATCH v2 18/25] security: Introduce inode_post_set_acl hook
  2023-08-31 10:41 ` [PATCH v2 18/25] security: Introduce inode_post_set_acl hook Roberto Sassu
@ 2023-08-31 22:36   ` Casey Schaufler
  0 siblings, 0 replies; 48+ messages in thread
From: Casey Schaufler @ 2023-08-31 22:36 UTC (permalink / raw)
  To: Roberto Sassu, viro, brauner, chuck.lever, jlayton, neilb, kolga,
	Dai.Ngo, tom, zohar, dmitry.kasatkin, paul, jmorris, serge,
	dhowells, jarkko, stephen.smalley.work, eparis
  Cc: linux-fsdevel, linux-kernel, linux-nfs, linux-integrity,
	linux-security-module, keyrings, selinux, Roberto Sassu,
	Stefan Berger, Casey Schaufler

On 8/31/2023 3:41 AM, 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.

Repeat of new LSM hook general comment:
Would you please include some explanation of how an LSM would use this hook?
You might start with a description of how it is used in IMA/EVM, and why that
could be generally useful.


>
> Signed-off-by: Roberto Sassu <roberto.sassu@huawei.com>
> Reviewed-by: Stefan Berger <stefanb@linux.ibm.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 7fa1b738bbab..3b7dbea5c3ff 100644
> --- a/fs/posix_acl.c
> +++ b/fs/posix_acl.c
> @@ -1137,6 +1137,7 @@ int vfs_set_acl(struct mnt_idmap *idmap, struct dentry *dentry,
>  		error = -EIO;
>  	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 9ae573b83737..bba1fbd97207 100644
> --- a/include/linux/lsm_hook_defs.h
> +++ b/include/linux/lsm_hook_defs.h
> @@ -157,6 +157,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 5f296761883f..556d019ebe5c 100644
> --- a/include/linux/security.h
> +++ b/include/linux/security.h
> @@ -367,6 +367,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,
> @@ -894,6 +896,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 e5acb11f6ebd..4392fd878d58 100644
> --- a/security/security.c
> +++ b/security/security.c
> @@ -2260,6 +2260,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 security after set_acl()
> + * @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

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

* Re: [PATCH v2 19/25] security: Introduce inode_post_remove_acl hook
  2023-08-31 10:41 ` [PATCH v2 19/25] security: Introduce inode_post_remove_acl hook Roberto Sassu
@ 2023-08-31 22:36   ` Casey Schaufler
  0 siblings, 0 replies; 48+ messages in thread
From: Casey Schaufler @ 2023-08-31 22:36 UTC (permalink / raw)
  To: Roberto Sassu, viro, brauner, chuck.lever, jlayton, neilb, kolga,
	Dai.Ngo, tom, zohar, dmitry.kasatkin, paul, jmorris, serge,
	dhowells, jarkko, stephen.smalley.work, eparis
  Cc: linux-fsdevel, linux-kernel, linux-nfs, linux-integrity,
	linux-security-module, keyrings, selinux, Roberto Sassu,
	Casey Schaufler

On 8/31/2023 3:41 AM, 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.

Repeat of new LSM hook general comment:
Would you please include some explanation of how an LSM would use this hook?
You might start with a description of how it is used in IMA/EVM, and why that
could be generally useful.


>
> 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 3b7dbea5c3ff..2a2a2750b3e9 100644
> --- a/fs/posix_acl.c
> +++ b/fs/posix_acl.c
> @@ -1246,6 +1246,7 @@ int vfs_remove_acl(struct mnt_idmap *idmap, struct dentry *dentry,
>  		error = -EIO;
>  	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 bba1fbd97207..eedc26790a07 100644
> --- a/include/linux/lsm_hook_defs.h
> +++ b/include/linux/lsm_hook_defs.h
> @@ -163,6 +163,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 556d019ebe5c..e543ae80309b 100644
> --- a/include/linux/security.h
> +++ b/include/linux/security.h
> @@ -373,6 +373,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);
> @@ -915,6 +918,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 4392fd878d58..32c3dc34432e 100644
> --- a/security/security.c
> +++ b/security/security.c
> @@ -2323,6 +2323,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

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

* Re: [PATCH v2 20/25] security: Introduce key_post_create_or_update hook
  2023-08-31 11:37 ` [PATCH v2 20/25] security: Introduce key_post_create_or_update hook Roberto Sassu
@ 2023-08-31 22:37   ` Casey Schaufler
  0 siblings, 0 replies; 48+ messages in thread
From: Casey Schaufler @ 2023-08-31 22:37 UTC (permalink / raw)
  To: Roberto Sassu, viro, brauner, chuck.lever, jlayton, neilb, kolga,
	Dai.Ngo, tom, zohar, dmitry.kasatkin, paul, jmorris, serge,
	dhowells, jarkko, stephen.smalley.work, eparis
  Cc: linux-fsdevel, linux-kernel, linux-nfs, linux-integrity,
	linux-security-module, keyrings, selinux, Roberto Sassu,
	Stefan Berger, Casey Schaufler

On 8/31/2023 4:37 AM, 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.

Repeat of new LSM hook general comment:
Would you please include some explanation of how an LSM would use this hook?
You might start with a description of how it is used in IMA/EVM, and why that
could be generally useful.


>
> Signed-off-by: Roberto Sassu <roberto.sassu@huawei.com>
> Reviewed-by: Stefan Berger <stefanb@linux.ibm.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 eedc26790a07..7512b4c46aa8 100644
> --- a/include/linux/lsm_hook_defs.h
> +++ b/include/linux/lsm_hook_defs.h
> @@ -399,6 +399,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 e543ae80309b..f50b78481753 100644
> --- a/include/linux/security.h
> +++ b/include/linux/security.h
> @@ -1959,6 +1959,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
>  
> @@ -1986,6 +1989,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 5c0c7df833f8..0f9c6faf3491 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 32c3dc34432e..e6783c2f0c65 100644
> --- a/security/security.c
> +++ b/security/security.c
> @@ -5169,6 +5169,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() - Notification of key create 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

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

* Re: [PATCH v2 21/25] ima: Move to LSM infrastructure
  2023-08-31 11:37 ` [PATCH v2 21/25] ima: Move to LSM infrastructure Roberto Sassu
  2023-08-31 14:10   ` Chuck Lever
@ 2023-08-31 22:42   ` Casey Schaufler
  1 sibling, 0 replies; 48+ messages in thread
From: Casey Schaufler @ 2023-08-31 22:42 UTC (permalink / raw)
  To: Roberto Sassu, viro, brauner, chuck.lever, jlayton, neilb, kolga,
	Dai.Ngo, tom, zohar, dmitry.kasatkin, paul, jmorris, serge,
	dhowells, jarkko, stephen.smalley.work, eparis
  Cc: linux-fsdevel, linux-kernel, linux-nfs, linux-integrity,
	linux-security-module, keyrings, selinux, Roberto Sassu,
	Casey Schaufler

On 8/31/2023 4:37 AM, Roberto Sassu wrote:
> 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().
>
> Signed-off-by: Roberto Sassu <roberto.sassu@huawei.com>

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

It's always nice to see special cases go away.

> ---
>  fs/file_table.c                   |  2 -
>  fs/namei.c                        |  7 ---
>  fs/nfsd/vfs.c                     |  7 ---
>  fs/open.c                         |  1 -
>  include/linux/ima.h               | 94 -------------------------------
>  security/integrity/iint.c         |  7 ++-
>  security/integrity/ima/ima.h      |  6 ++
>  security/integrity/ima/ima_main.c | 63 ++++++++++++++-------
>  security/integrity/integrity.h    |  9 +++
>  security/keys/key.c               |  9 +--
>  security/security.c               | 53 +++--------------
>  11 files changed, 72 insertions(+), 186 deletions(-)
>
> diff --git a/fs/file_table.c b/fs/file_table.c
> index 964e24120684..7b9c756a42df 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>
>  
> @@ -376,7 +375,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 efed0e1e93f5..a200021209c3 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>
> @@ -3636,8 +3635,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)) {
> @@ -3701,7 +3698,6 @@ static int vfs_tmpfile(struct mnt_idmap *idmap,
>  		spin_unlock(&inode->i_lock);
>  	}
>  	security_inode_post_create_tmpfile(idmap, dir, file, mode);
> -	ima_post_create_tmpfile(idmap, dir, file, mode);
>  	return 0;
>  }
>  
> @@ -4049,9 +4045,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_stripped, 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 3450bb1c8a18..94bbd7ac8b68 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>
> @@ -868,12 +867,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 0c55c8e7f837..6825ac1d07a9 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 6e4d060ff378..58591b5cbdb4 100644
> --- a/include/linux/ima.h
> +++ b/include/linux/ima.h
> @@ -16,26 +16,7 @@ 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 file *file,
> -				    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);
> -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);
> -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 +41,11 @@ 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 file *file,
> -					   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 +96,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 a462df827de2..32f0f3c5c4dd 100644
> --- a/security/integrity/iint.c
> +++ b/security/integrity/iint.c
> @@ -167,20 +167,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 c29db699c996..c0412100023e 100644
> --- a/security/integrity/ima/ima.h
> +++ b/security/integrity/ima/ima.h
> @@ -127,6 +127,12 @@ 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
> +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 f8581032e62c..0e4f882fcdce 100644
> --- a/security/integrity/ima/ima_main.c
> +++ b/security/integrity/ima/ima_main.c
> @@ -188,7 +188,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;
> @@ -413,8 +413,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;
> @@ -452,8 +452,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;
> @@ -511,7 +511,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;
> @@ -673,9 +673,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 file *file,
> -			     umode_t mode)
> +static void ima_post_create_tmpfile(struct mnt_idmap *idmap, struct inode *dir,
> +				    struct file *file, umode_t mode)
>  {
>  	struct integrity_iint_cache *iint;
>  	struct inode *inode = file_inode(file);
> @@ -710,9 +709,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;
> @@ -751,8 +750,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;
> @@ -801,8 +800,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;
> @@ -835,7 +834,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;
>  
> @@ -889,9 +888,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) &&
> @@ -1120,4 +1119,28 @@ static int __init init_ima(void)
>  	return error;
>  }
>  
> +static struct security_hook_list ima_hooks[] __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 7167a6e99bdc..7adc7d6c4f9f 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
> @@ -191,6 +192,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 0f9c6faf3491..2acf9fa80735 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 e6783c2f0c65..8c5b8ffeef92 100644
> --- a/security/security.c
> +++ b/security/security.c
> @@ -1098,12 +1098,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);
>  }
>  
>  /**
> @@ -2793,13 +2788,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);
>  }
>  
>  /**
> @@ -2828,12 +2818,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);
>  }
>  
>  /**
> @@ -3163,12 +3148,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);
>  
> @@ -3188,12 +3168,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);
>  
> @@ -3208,12 +3183,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);
>  
> @@ -3235,13 +3205,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);
>  

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

* Re: [PATCH v2 23/25] evm: Move to LSM infrastructure
  2023-08-31 11:38 ` [PATCH v2 23/25] evm: Move " Roberto Sassu
@ 2023-08-31 22:46   ` Casey Schaufler
  0 siblings, 0 replies; 48+ messages in thread
From: Casey Schaufler @ 2023-08-31 22:46 UTC (permalink / raw)
  To: Roberto Sassu, viro, brauner, chuck.lever, jlayton, neilb, kolga,
	Dai.Ngo, tom, zohar, dmitry.kasatkin, paul, jmorris, serge,
	dhowells, jarkko, stephen.smalley.work, eparis
  Cc: linux-fsdevel, linux-kernel, linux-nfs, linux-integrity,
	linux-security-module, keyrings, selinux, Roberto Sassu,
	Casey Schaufler

On 8/31/2023 4:38 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, and
> consequently decrement by one the number of xattrs to allocate in
> security_inode_init_security().
>
> Signed-off-by: Roberto Sassu <roberto.sassu@huawei.com>

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

> ---
>  fs/attr.c                         |   2 -
>  fs/posix_acl.c                    |   3 -
>  fs/xattr.c                        |   2 -
>  include/linux/evm.h               | 107 ------------------------------
>  security/integrity/evm/evm_main.c | 103 +++++++++++++++++++++++-----
>  security/integrity/iint.c         |   7 ++
>  security/integrity/integrity.h    |   9 +++
>  security/security.c               |  42 +++---------
>  8 files changed, 113 insertions(+), 162 deletions(-)
>
> diff --git a/fs/attr.c b/fs/attr.c
> index 63fb60195409..4153f83a4a1f 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"
>  
> @@ -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);
> -		evm_inode_post_setattr(idmap, dentry, ia_valid);
>  	}
>  
>  	return error;
> diff --git a/fs/posix_acl.c b/fs/posix_acl.c
> index 2a2a2750b3e9..5cea0df45d3b 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>
>  
> @@ -1138,7 +1137,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:
> @@ -1247,7 +1245,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 4a0280295686..4495e0b4d003 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>
> @@ -557,7 +556,6 @@ __vfs_removexattr_locked(struct mnt_idmap *idmap,
>  
>  	fsnotify_xattr(dentry);
>  	security_inode_post_removexattr(dentry, name);
> -	evm_inode_post_removexattr(dentry, name);
>  
>  out:
>  	return error;
> diff --git a/include/linux/evm.h b/include/linux/evm.h
> index 642e52483adc..cb481eccc967 100644
> --- a/include/linux/evm.h
> +++ b/include/linux/evm.h
> @@ -21,44 +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);
> -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);
> -}
> -
>  int evm_inode_init_security(struct inode *inode, struct inode *dir,
>  			    const struct qstr *qstr, struct xattr *xattrs,
>  			    int *xattr_count);
> @@ -93,75 +55,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,
> diff --git a/security/integrity/evm/evm_main.c b/security/integrity/evm/evm_main.c
> index 2e8f6d1c9984..adbb996e681d 100644
> --- a/security/integrity/evm/evm_main.c
> +++ b/security/integrity/evm/evm_main.c
> @@ -567,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;
>  
> @@ -599,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
> @@ -650,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;
>  
> @@ -691,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;
> @@ -739,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;
> @@ -757,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
> @@ -767,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;
> @@ -783,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)
>  {
> @@ -806,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;
> @@ -854,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;
> @@ -965,4 +1019,23 @@ static int __init init_evm(void)
>  	return error;
>  }
>  
> +static struct security_hook_list evm_hooks[] __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 32f0f3c5c4dd..dd03f978b45c 100644
> --- a/security/integrity/iint.c
> +++ b/security/integrity/iint.c
> @@ -174,12 +174,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 __ro_after_init = {
> +	.lbs_xattr_count = 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 7adc7d6c4f9f..83a465ac9013 100644
> --- a/security/integrity/integrity.h
> +++ b/security/integrity/integrity.h
> @@ -189,6 +189,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;
>  
> @@ -200,6 +201,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 dc863210c96e..9ba36a8e5d65 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>
>  
> @@ -1616,8 +1616,8 @@ int security_inode_init_security(struct inode *inode, struct inode *dir,
>  		return 0;
>  
>  	if (initxattrs) {
> -		/* Allocate +1 for EVM and +1 as terminator. */
> -		new_xattrs = kcalloc(blob_sizes.lbs_xattr_count + 2,
> +		/* Allocate +1 as terminator. */
> +		new_xattrs = kcalloc(blob_sizes.lbs_xattr_count + 1,
>  				     sizeof(*new_xattrs), GFP_NOFS);
>  		if (!new_xattrs)
>  			return -ENOMEM;
> @@ -1641,10 +1641,6 @@ int security_inode_init_security(struct inode *inode, struct inode *dir,
>  	if (!xattr_count)
>  		goto out;
>  
> -	ret = evm_inode_init_security(inode, dir, qstr, new_xattrs,
> -				      &xattr_count);
> -	if (ret)
> -		goto out;
>  	ret = initxattrs(inode, new_xattrs, fs_data);
>  out:
>  	for (; xattr_count > 0; xattr_count--)
> @@ -2144,14 +2140,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);
>  
> @@ -2216,9 +2207,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;
>  }
>  
>  /**
> @@ -2237,15 +2226,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);
>  }
>  
>  /**
> @@ -2298,14 +2282,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);
>  }
>  
>  /**
> @@ -2341,7 +2320,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);
>  }
>  
>  /**
> @@ -2402,9 +2380,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] 48+ messages in thread

* Re: [PATCH v2 24/25] integrity: Move integrity functions to the LSM infrastructure
  2023-08-31 11:38 ` [PATCH v2 24/25] integrity: Move integrity functions to the " Roberto Sassu
@ 2023-08-31 22:49   ` Casey Schaufler
  0 siblings, 0 replies; 48+ messages in thread
From: Casey Schaufler @ 2023-08-31 22:49 UTC (permalink / raw)
  To: Roberto Sassu, viro, brauner, chuck.lever, jlayton, neilb, kolga,
	Dai.Ngo, tom, zohar, dmitry.kasatkin, paul, jmorris, serge,
	dhowells, jarkko, stephen.smalley.work, eparis
  Cc: linux-fsdevel, linux-kernel, linux-nfs, linux-integrity,
	linux-security-module, keyrings, selinux, Roberto Sassu,
	Casey Schaufler

On 8/31/2023 4:38 AM, Roberto Sassu wrote:
> 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>

Reviewed-by: Casey Schaufler <casey@schaufler-ca.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 2ea0f2f65ab6..afaae7ad26f4 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 dd03f978b45c..70ee803a33ea 100644
> --- a/security/integrity/iint.c
> +++ b/security/integrity/iint.c
> @@ -138,7 +138,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;
>  
> @@ -167,12 +167,21 @@ static void init_once(void *foo)
>  	mutex_init(&iint->mutex);
>  }
>  
> +static struct security_hook_list integrity_hooks[] __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 83a465ac9013..e020c365997b 100644
> --- a/security/integrity/integrity.h
> +++ b/security/integrity/integrity.h
> @@ -178,6 +178,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);
> @@ -251,12 +252,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);
> +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 9ba36a8e5d65..e9275335aaa7 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>
> @@ -1497,7 +1496,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
> @@ -3090,12 +3088,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);
>  }
>  
>  /**

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

* Re: [PATCH v2 00/25] security: Move IMA and EVM to the LSM infrastructure
  2023-08-31 10:41 [PATCH v2 00/25] security: Move IMA and EVM to the LSM infrastructure Roberto Sassu
                   ` (24 preceding siblings ...)
  2023-08-31 11:38 ` [PATCH v2 25/25] integrity: Switch from rbtree to LSM-managed blob for integrity_iint_cache Roberto Sassu
@ 2023-08-31 23:01 ` Casey Schaufler
  25 siblings, 0 replies; 48+ messages in thread
From: Casey Schaufler @ 2023-08-31 23:01 UTC (permalink / raw)
  To: Roberto Sassu, viro, brauner, chuck.lever, jlayton, neilb, kolga,
	Dai.Ngo, tom, zohar, dmitry.kasatkin, paul, jmorris, serge,
	dhowells, jarkko, stephen.smalley.work, eparis
  Cc: linux-fsdevel, linux-kernel, linux-nfs, linux-integrity,
	linux-security-module, keyrings, selinux, Roberto Sassu,
	Casey Schaufler

On 8/31/2023 3:41 AM, Roberto Sassu wrote:
> From: Roberto Sassu <roberto.sassu@huawei.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-11 make IMA and EVM functions suitable to
> be registered to the LSM infrastructure, by aligning function parameters.
>
> Patches 12-20 add new LSM hooks in the same places where IMA and EVM
> functions are called, if there is no LSM hook already.

I've commented on the individual patches, but it seems like a general comment
might be in order. When a new LSM hook is proposed we want to see more than
"project XYZZY needs this hook" to justify it. We want to know how it is useful
for XYZZY and how it could be used in another LSM. If I were creating a new LSM
it could be useful to understand the difference between security_inode_setattr()
and security_inode_post_setattr(). As a reviewer who has had only incidental
exposure to the IMA code it's important to understand why it doesn't use the
existing hooks.

>
> Patches 21-24 do the bulk of the work, remove hardcoded calls to IMA, EVM
> and integrity 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 25 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.
>
> The patch set applies on top of lsm/next, commit 8e4672d6f902 ("lsm:
> constify the 'file' parameter in security_binder_transfer_file()")
>
> Changelog:
>
> v1:
>  - Drop 'evm: Complete description of evm_inode_setattr()', 'fs: Fix
>    description of vfs_tmpfile()' and 'security: Introduce LSM_ORDER_LAST',
>    they were sent separately (suggested by Christian Brauner)
>  - Replace dentry with file descriptor parameter for
>    security_inode_post_create_tmpfile()
>  - Introduce mode_stripped and pass it as mode argument to
>    security_path_mknod() and security_path_post_mknod()
>  - Use goto in do_mknodat() and __vfs_removexattr_locked() (suggested by
>    Mimi)
>  - Replace __lsm_ro_after_init with __ro_after_init
>  - Modify short description of security_inode_post_create_tmpfile() and
>    security_inode_post_set_acl() (suggested by Stefan)
>  - Move security_inode_post_setattr() just after security_inode_setattr()
>    (suggested by Mimi)
>  - Modify short description of security_key_post_create_or_update()
>    (suggested by Mimi)
>  - Add back exported functions ima_file_check() and
>    evm_inode_init_security() respectively to ima.h and evm.h (reported by
>    kernel robot)
>  - Remove extern from prototype declarations and fix style issues
>  - Remove unnecessary include of linux/lsm_hooks.h in ima_main.c and
>    ima_appraise.c
>
> Roberto Sassu (25):
>   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
>   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
>   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                            |  18 +-
>  fs/nfsd/vfs.c                         |   3 +-
>  fs/open.c                             |   1 -
>  fs/posix_acl.c                        |   5 +-
>  fs/xattr.c                            |   9 +-
>  include/linux/evm.h                   | 103 ----------
>  include/linux/ima.h                   | 136 -------------
>  include/linux/integrity.h             |  26 ---
>  include/linux/lsm_hook_defs.h         |  21 +-
>  include/linux/security.h              |  65 +++++++
>  security/integrity/evm/evm_main.c     | 104 ++++++++--
>  security/integrity/iint.c             |  92 +++------
>  security/integrity/ima/ima.h          |  11 ++
>  security/integrity/ima/ima_appraise.c |  37 +++-
>  security/integrity/ima/ima_main.c     |  76 ++++++--
>  security/integrity/integrity.h        |  44 ++++-
>  security/keys/key.c                   |  10 +-
>  security/security.c                   | 265 ++++++++++++++++----------
>  security/selinux/hooks.c              |   3 +-
>  security/smack/smack_lsm.c            |   4 +-
>  22 files changed, 540 insertions(+), 501 deletions(-)
>

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

* Re: [PATCH v2 25/25] integrity: Switch from rbtree to LSM-managed blob for integrity_iint_cache
  2023-08-31 11:38 ` [PATCH v2 25/25] integrity: Switch from rbtree to LSM-managed blob for integrity_iint_cache Roberto Sassu
@ 2023-08-31 23:05   ` Casey Schaufler
  0 siblings, 0 replies; 48+ messages in thread
From: Casey Schaufler @ 2023-08-31 23:05 UTC (permalink / raw)
  To: Roberto Sassu, viro, brauner, chuck.lever, jlayton, neilb, kolga,
	Dai.Ngo, tom, zohar, dmitry.kasatkin, paul, jmorris, serge,
	dhowells, jarkko, stephen.smalley.work, eparis
  Cc: linux-fsdevel, linux-kernel, linux-nfs, linux-integrity,
	linux-security-module, keyrings, selinux, Roberto Sassu,
	Casey Schaufler

On 8/31/2023 4:38 AM, Roberto Sassu wrote:
> 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>

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

> ---
>  security/integrity/iint.c      | 67 +++-------------------------------
>  security/integrity/integrity.h | 19 +++++++++-
>  2 files changed, 24 insertions(+), 62 deletions(-)
>
> diff --git a/security/integrity/iint.c b/security/integrity/iint.c
> index 70ee803a33ea..c2fba8afbbdb 100644
> --- a/security/integrity/iint.c
> +++ b/security/integrity/iint.c
> @@ -14,56 +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
> -			return iint;
> -	}
> -
> -	return NULL;
> -}
> -
>  /*
>   * 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)
> @@ -92,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;
>  
>  	iint = integrity_iint_find(inode);
>  	if (iint)
> @@ -104,31 +71,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 if (inode > test_iint->inode) {
> -			p = &(*p)->rb_right;
> -		} else {
> -			write_unlock(&integrity_iint_lock);
> -			kmem_cache_free(iint_cache, iint);
> -			return test_iint;
> -		}
> -	}
> -
>  	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;
>  }
>  
> @@ -145,10 +91,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);
>  }
> @@ -188,6 +132,7 @@ static int __init integrity_lsm_init(void)
>  }
>  
>  struct lsm_blob_sizes integrity_blob_sizes __ro_after_init = {
> +	.lbs_inode = sizeof(struct integrity_iint_cache *),
>  	.lbs_xattr_count = 1,
>  };
>  
> diff --git a/security/integrity/integrity.h b/security/integrity/integrity.h
> index e020c365997b..24de4ad4a37e 100644
> --- a/security/integrity/integrity.h
> +++ b/security/integrity/integrity.h
> @@ -158,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 */
> @@ -192,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

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

* Re: [PATCH v2 11/25] security: Align inode_setattr hook definition with EVM
  2023-08-31 10:41 ` [PATCH v2 11/25] security: Align inode_setattr hook definition with EVM Roberto Sassu
@ 2023-09-04 21:08   ` Jarkko Sakkinen
  2023-09-05 15:56     ` Casey Schaufler
  0 siblings, 1 reply; 48+ messages in thread
From: Jarkko Sakkinen @ 2023-09-04 21:08 UTC (permalink / raw)
  To: Roberto Sassu, viro, brauner, chuck.lever, jlayton, neilb, kolga,
	Dai.Ngo, tom, zohar, dmitry.kasatkin, paul, jmorris, serge,
	dhowells, stephen.smalley.work, eparis, casey
  Cc: linux-fsdevel, linux-kernel, linux-nfs, linux-integrity,
	linux-security-module, keyrings, selinux, Roberto Sassu,
	Stefan Berger

On Thu Aug 31, 2023 at 1:41 PM EEST, 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>
> 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 4bdddb52a8fe..fdf075a6b1bb 100644
> --- a/include/linux/lsm_hook_defs.h
> +++ b/include/linux/lsm_hook_defs.h
> @@ -134,7 +134,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_setattr, struct mnt_idmap *idmap, struct dentry *dentry, struct iattr *attr)

Only 99 characters, i.e. breaking into two lines is not necessary.

>  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 cb6242feb968..2b24d01cf181 100644
> --- a/security/security.c
> +++ b/security/security.c
> @@ -2117,7 +2117,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 ee7c49c2cfd3..bfcc4d9aa5ab 100644
> --- a/security/selinux/hooks.c
> +++ b/security/selinux/hooks.c
> @@ -3075,7 +3075,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 679156601a10..89f2669d50a9 100644
> --- a/security/smack/smack_lsm.c
> +++ b/security/smack/smack_lsm.c
> @@ -1181,12 +1181,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)

static int smack_inode_setattr(struct mnt_idmap *idmap, struct dentry *dentry, struct iattr *iattr)

Can be still in a single line (100 characters exactly).


>  {
>  	struct smk_audit_info ad;
>  	int rc;
> -- 
> 2.34.1


BR, Jarkko

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

* Re: [PATCH v2 12/25] security: Introduce inode_post_setattr hook
  2023-08-31 10:41 ` [PATCH v2 12/25] security: Introduce inode_post_setattr hook Roberto Sassu
  2023-08-31 22:28   ` Casey Schaufler
@ 2023-09-04 21:09   ` Jarkko Sakkinen
  1 sibling, 0 replies; 48+ messages in thread
From: Jarkko Sakkinen @ 2023-09-04 21:09 UTC (permalink / raw)
  To: Roberto Sassu, viro, brauner, chuck.lever, jlayton, neilb, kolga,
	Dai.Ngo, tom, zohar, dmitry.kasatkin, paul, jmorris, serge,
	dhowells, stephen.smalley.work, eparis, casey
  Cc: linux-fsdevel, linux-kernel, linux-nfs, linux-integrity,
	linux-security-module, keyrings, selinux, Roberto Sassu,
	Stefan Berger

On Thu Aug 31, 2023 at 1:41 PM EEST, 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>
> 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 431f667726c7..3c309eb456c6 100644
> --- a/fs/attr.c
> +++ b/fs/attr.c
> @@ -486,6 +486,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 fdf075a6b1bb..995d30336cfa 100644
> --- a/include/linux/lsm_hook_defs.h
> +++ b/include/linux/lsm_hook_defs.h
> @@ -136,6 +136,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(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 dcb3604ffab8..820899db5276 100644
> --- a/include/linux/security.h
> +++ b/include/linux/security.h
> @@ -355,6 +355,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);

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,
> @@ -856,6 +858,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 2b24d01cf181..764a6f28b3b9 100644
> --- a/security/security.c
> +++ b/security/security.c
> @@ -2124,6 +2124,22 @@ int security_inode_setattr(struct mnt_idmap *idmap,
>  }
>  EXPORT_SYMBOL_GPL(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 *dentry,
> +				 int ia_valid)

Ditto.

> +{
> +	if (unlikely(IS_PRIVATE(d_backing_inode(dentry))))
> +		return;
> +	call_void_hook(inode_post_setattr, idmap, dentry, ia_valid);
> +}
> +
>  /**
>   * security_inode_getattr() - Check if getting file attributes is allowed
>   * @path: file
> -- 
> 2.34.1


BR, Jarkko

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

* Re: [PATCH v2 13/25] security: Introduce inode_post_removexattr hook
  2023-08-31 10:41 ` [PATCH v2 13/25] security: Introduce inode_post_removexattr hook Roberto Sassu
  2023-08-31 22:30   ` Casey Schaufler
@ 2023-09-04 21:11   ` Jarkko Sakkinen
  2023-09-05  6:51     ` Roberto Sassu
  1 sibling, 1 reply; 48+ messages in thread
From: Jarkko Sakkinen @ 2023-09-04 21:11 UTC (permalink / raw)
  To: Roberto Sassu, viro, brauner, chuck.lever, jlayton, neilb, kolga,
	Dai.Ngo, tom, zohar, dmitry.kasatkin, paul, jmorris, serge,
	dhowells, stephen.smalley.work, eparis, casey
  Cc: linux-fsdevel, linux-kernel, linux-nfs, linux-integrity,
	linux-security-module, keyrings, selinux, Roberto Sassu,
	Stefan Berger

On Thu Aug 31, 2023 at 1:41 PM EEST, 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>
> ---
>  fs/xattr.c                    |  9 +++++----
>  include/linux/lsm_hook_defs.h |  2 ++
>  include/linux/security.h      |  5 +++++
>  security/security.c           | 14 ++++++++++++++
>  4 files changed, 26 insertions(+), 4 deletions(-)
>
> diff --git a/fs/xattr.c b/fs/xattr.c
> index e7bbb7f57557..4a0280295686 100644
> --- a/fs/xattr.c
> +++ b/fs/xattr.c
> @@ -552,11 +552,12 @@ __vfs_removexattr_locked(struct mnt_idmap *idmap,
>  		goto out;
>  
>  	error = __vfs_removexattr(idmap, dentry, name);
> +	if (error)
> +		goto out;
>  
> -	if (!error) {
> -		fsnotify_xattr(dentry);
> -		evm_inode_post_removexattr(dentry, name);
> -	}
> +	fsnotify_xattr(dentry);
> +	security_inode_post_removexattr(dentry, name);
> +	evm_inode_post_removexattr(dentry, name);
>  
>  out:
>  	return error;
> diff --git a/include/linux/lsm_hook_defs.h b/include/linux/lsm_hook_defs.h
> index 995d30336cfa..1153e7163b8b 100644
> --- a/include/linux/lsm_hook_defs.h
> +++ b/include/linux/lsm_hook_defs.h
> @@ -148,6 +148,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 820899db5276..665bba3e0081 100644
> --- a/include/linux/security.h
> +++ b/include/linux/security.h
> @@ -374,6 +374,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,
> @@ -919,6 +920,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 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 764a6f28b3b9..3947159ba5e9 100644
> --- a/security/security.c
> +++ b/security/security.c
> @@ -2354,6 +2354,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.34.1


These odd splits are everywhere in the patch set. Just (nit)picking some.

It is huge patch set so I don't really get for addign extra lines for no
good reason.

BR, Jarkko

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

* Re: [PATCH v2 13/25] security: Introduce inode_post_removexattr hook
  2023-09-04 21:11   ` Jarkko Sakkinen
@ 2023-09-05  6:51     ` Roberto Sassu
  2023-09-05 16:49       ` Mimi Zohar
  0 siblings, 1 reply; 48+ messages in thread
From: Roberto Sassu @ 2023-09-05  6:51 UTC (permalink / raw)
  To: Jarkko Sakkinen, viro, brauner, chuck.lever, jlayton, neilb,
	kolga, Dai.Ngo, tom, zohar, dmitry.kasatkin, paul, jmorris,
	serge, dhowells, stephen.smalley.work, eparis, casey
  Cc: linux-fsdevel, linux-kernel, linux-nfs, linux-integrity,
	linux-security-module, keyrings, selinux, Roberto Sassu,
	Stefan Berger

On Tue, 2023-09-05 at 00:11 +0300, Jarkko Sakkinen wrote:
> On Thu Aug 31, 2023 at 1:41 PM EEST, 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>
> > ---
> >  fs/xattr.c                    |  9 +++++----
> >  include/linux/lsm_hook_defs.h |  2 ++
> >  include/linux/security.h      |  5 +++++
> >  security/security.c           | 14 ++++++++++++++
> >  4 files changed, 26 insertions(+), 4 deletions(-)
> > 
> > diff --git a/fs/xattr.c b/fs/xattr.c
> > index e7bbb7f57557..4a0280295686 100644
> > --- a/fs/xattr.c
> > +++ b/fs/xattr.c
> > @@ -552,11 +552,12 @@ __vfs_removexattr_locked(struct mnt_idmap *idmap,
> >  		goto out;
> >  
> >  	error = __vfs_removexattr(idmap, dentry, name);
> > +	if (error)
> > +		goto out;
> >  
> > -	if (!error) {
> > -		fsnotify_xattr(dentry);
> > -		evm_inode_post_removexattr(dentry, name);
> > -	}
> > +	fsnotify_xattr(dentry);
> > +	security_inode_post_removexattr(dentry, name);
> > +	evm_inode_post_removexattr(dentry, name);
> >  
> >  out:
> >  	return error;
> > diff --git a/include/linux/lsm_hook_defs.h b/include/linux/lsm_hook_defs.h
> > index 995d30336cfa..1153e7163b8b 100644
> > --- a/include/linux/lsm_hook_defs.h
> > +++ b/include/linux/lsm_hook_defs.h
> > @@ -148,6 +148,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 820899db5276..665bba3e0081 100644
> > --- a/include/linux/security.h
> > +++ b/include/linux/security.h
> > @@ -374,6 +374,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,
> > @@ -919,6 +920,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 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 764a6f28b3b9..3947159ba5e9 100644
> > --- a/security/security.c
> > +++ b/security/security.c
> > @@ -2354,6 +2354,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.34.1
> 
> 
> These odd splits are everywhere in the patch set. Just (nit)picking some.
> 
> It is huge patch set so I don't really get for addign extra lines for no
> good reason.

Thanks for the review, Jarkko.

I don't know... to be honest I still prefer to stay within 80
characters.

Roberto


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

* Re: [PATCH v2 11/25] security: Align inode_setattr hook definition with EVM
  2023-09-04 21:08   ` Jarkko Sakkinen
@ 2023-09-05 15:56     ` Casey Schaufler
  2023-09-11 10:50       ` Jarkko Sakkinen
  0 siblings, 1 reply; 48+ messages in thread
From: Casey Schaufler @ 2023-09-05 15:56 UTC (permalink / raw)
  To: Jarkko Sakkinen, Roberto Sassu, viro, brauner, chuck.lever,
	jlayton, neilb, kolga, Dai.Ngo, tom, zohar, dmitry.kasatkin,
	paul, jmorris, serge, dhowells, stephen.smalley.work, eparis
  Cc: linux-fsdevel, linux-kernel, linux-nfs, linux-integrity,
	linux-security-module, keyrings, selinux, Roberto Sassu,
	Stefan Berger, Casey Schaufler

On 9/4/2023 2:08 PM, Jarkko Sakkinen wrote:
> On Thu Aug 31, 2023 at 1:41 PM EEST, 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>
>> 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 4bdddb52a8fe..fdf075a6b1bb 100644
>> --- a/include/linux/lsm_hook_defs.h
>> +++ b/include/linux/lsm_hook_defs.h
>> @@ -134,7 +134,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_setattr, struct mnt_idmap *idmap, struct dentry *dentry, struct iattr *attr)
>
> Only 99 characters, i.e. breaking into two lines is not necessary.

We're keeping the LSM code in the ancient 80 character format.
Until we get some fresh, young maintainers involved who can convince
us that line wrapped 80 character terminals are kewl we're sticking
with what we know.

	https://lwn.net/Articles/822168/

>
>>  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 cb6242feb968..2b24d01cf181 100644
>> --- a/security/security.c
>> +++ b/security/security.c
>> @@ -2117,7 +2117,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 ee7c49c2cfd3..bfcc4d9aa5ab 100644
>> --- a/security/selinux/hooks.c
>> +++ b/security/selinux/hooks.c
>> @@ -3075,7 +3075,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 679156601a10..89f2669d50a9 100644
>> --- a/security/smack/smack_lsm.c
>> +++ b/security/smack/smack_lsm.c
>> @@ -1181,12 +1181,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)
> static int smack_inode_setattr(struct mnt_idmap *idmap, struct dentry *dentry, struct iattr *iattr)
>
> Can be still in a single line (100 characters exactly).
>
>
>>  {
>>  	struct smk_audit_info ad;
>>  	int rc;
>> -- 
>> 2.34.1
>
> BR, Jarkko

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

* Re: [PATCH v2 13/25] security: Introduce inode_post_removexattr hook
  2023-09-05  6:51     ` Roberto Sassu
@ 2023-09-05 16:49       ` Mimi Zohar
  0 siblings, 0 replies; 48+ messages in thread
From: Mimi Zohar @ 2023-09-05 16:49 UTC (permalink / raw)
  To: Roberto Sassu, Jarkko Sakkinen, viro, brauner, chuck.lever,
	jlayton, neilb, kolga, Dai.Ngo, tom, dmitry.kasatkin, paul,
	jmorris, serge, dhowells, stephen.smalley.work, eparis, casey
  Cc: linux-fsdevel, linux-kernel, linux-nfs, linux-integrity,
	linux-security-module, keyrings, selinux, Roberto Sassu,
	Stefan Berger

On Tue, 2023-09-05 at 08:51 +0200, Roberto Sassu wrote:
> On Tue, 2023-09-05 at 00:11 +0300, Jarkko Sakkinen wrote:
> > On Thu Aug 31, 2023 at 1:41 PM EEST, 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>
> > > ---
> > >  fs/xattr.c                    |  9 +++++----
> > >  include/linux/lsm_hook_defs.h |  2 ++
> > >  include/linux/security.h      |  5 +++++
> > >  security/security.c           | 14 ++++++++++++++
> > >  4 files changed, 26 insertions(+), 4 deletions(-)
> > > 
> > > diff --git a/fs/xattr.c b/fs/xattr.c
> > > index e7bbb7f57557..4a0280295686 100644
> > > --- a/fs/xattr.c
> > > +++ b/fs/xattr.c
> > > @@ -552,11 +552,12 @@ __vfs_removexattr_locked(struct mnt_idmap *idmap,
> > >  		goto out;
> > >  
> > >  	error = __vfs_removexattr(idmap, dentry, name);
> > > +	if (error)
> > > +		goto out;
> > >  
> > > -	if (!error) {
> > > -		fsnotify_xattr(dentry);
> > > -		evm_inode_post_removexattr(dentry, name);
> > > -	}
> > > +	fsnotify_xattr(dentry);
> > > +	security_inode_post_removexattr(dentry, name);
> > > +	evm_inode_post_removexattr(dentry, name);
> > >  
> > >  out:
> > >  	return error;
> > > diff --git a/include/linux/lsm_hook_defs.h b/include/linux/lsm_hook_defs.h
> > > index 995d30336cfa..1153e7163b8b 100644
> > > --- a/include/linux/lsm_hook_defs.h
> > > +++ b/include/linux/lsm_hook_defs.h
> > > @@ -148,6 +148,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 820899db5276..665bba3e0081 100644
> > > --- a/include/linux/security.h
> > > +++ b/include/linux/security.h
> > > @@ -374,6 +374,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,
> > > @@ -919,6 +920,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 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 764a6f28b3b9..3947159ba5e9 100644
> > > --- a/security/security.c
> > > +++ b/security/security.c
> > > @@ -2354,6 +2354,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.34.1
> > 
> > 
> > These odd splits are everywhere in the patch set. Just (nit)picking some.
> > 
> > It is huge patch set so I don't really get for addign extra lines for no
> > good reason.
> 
> Thanks for the review, Jarkko.
> 
> I don't know... to be honest I still prefer to stay within 80
> characters.

I agree.

-- 
thanks,

Mimi



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

* Re: [PATCH v2 11/25] security: Align inode_setattr hook definition with EVM
  2023-09-05 15:56     ` Casey Schaufler
@ 2023-09-11 10:50       ` Jarkko Sakkinen
  0 siblings, 0 replies; 48+ messages in thread
From: Jarkko Sakkinen @ 2023-09-11 10:50 UTC (permalink / raw)
  To: Casey Schaufler, Roberto Sassu, viro, brauner, chuck.lever,
	jlayton, neilb, kolga, Dai.Ngo, tom, zohar, dmitry.kasatkin,
	paul, jmorris, serge, dhowells, stephen.smalley.work, eparis
  Cc: linux-fsdevel, linux-kernel, linux-nfs, linux-integrity,
	linux-security-module, keyrings, selinux, Roberto Sassu,
	Stefan Berger

On Tue Sep 5, 2023 at 6:56 PM EEST, Casey Schaufler wrote:
> On 9/4/2023 2:08 PM, Jarkko Sakkinen wrote:
> > On Thu Aug 31, 2023 at 1:41 PM EEST, 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>
> >> 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 4bdddb52a8fe..fdf075a6b1bb 100644
> >> --- a/include/linux/lsm_hook_defs.h
> >> +++ b/include/linux/lsm_hook_defs.h
> >> @@ -134,7 +134,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_setattr, struct mnt_idmap *idmap, struct dentry *dentry, struct iattr *attr)
> >
> > Only 99 characters, i.e. breaking into two lines is not necessary.
>
> We're keeping the LSM code in the ancient 80 character format.
> Until we get some fresh, young maintainers involved who can convince
> us that line wrapped 80 character terminals are kewl we're sticking
> with what we know.
>
> 	https://lwn.net/Articles/822168/

Pretty artificial counter-example tbh :-) Even with Rust people tend to
stick one character variable names for trivial integer indices.

BR, Jarkko

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

end of thread, other threads:[~2023-09-11 22:00 UTC | newest]

Thread overview: 48+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-08-31 10:41 [PATCH v2 00/25] security: Move IMA and EVM to the LSM infrastructure Roberto Sassu
2023-08-31 10:41 ` [PATCH v2 01/25] ima: Align ima_inode_post_setattr() definition with " Roberto Sassu
2023-08-31 10:41 ` [PATCH v2 02/25] ima: Align ima_post_path_mknod() " Roberto Sassu
2023-08-31 10:41 ` [PATCH v2 03/25] ima: Align ima_post_create_tmpfile() " Roberto Sassu
2023-08-31 10:41 ` [PATCH v2 04/25] ima: Align ima_file_mprotect() " Roberto Sassu
2023-08-31 10:41 ` [PATCH v2 05/25] ima: Align ima_inode_setxattr() " Roberto Sassu
2023-08-31 10:41 ` [PATCH v2 06/25] ima: Align ima_inode_removexattr() " Roberto Sassu
2023-08-31 10:41 ` [PATCH v2 07/25] ima: Align ima_post_read_file() " Roberto Sassu
2023-08-31 10:41 ` [PATCH v2 08/25] evm: Align evm_inode_post_setattr() " Roberto Sassu
2023-08-31 10:41 ` [PATCH v2 09/25] evm: Align evm_inode_setxattr() " Roberto Sassu
2023-08-31 10:41 ` [PATCH v2 10/25] evm: Align evm_inode_post_setxattr() " Roberto Sassu
2023-08-31 10:41 ` [PATCH v2 11/25] security: Align inode_setattr hook definition with EVM Roberto Sassu
2023-09-04 21:08   ` Jarkko Sakkinen
2023-09-05 15:56     ` Casey Schaufler
2023-09-11 10:50       ` Jarkko Sakkinen
2023-08-31 10:41 ` [PATCH v2 12/25] security: Introduce inode_post_setattr hook Roberto Sassu
2023-08-31 22:28   ` Casey Schaufler
2023-09-04 21:09   ` Jarkko Sakkinen
2023-08-31 10:41 ` [PATCH v2 13/25] security: Introduce inode_post_removexattr hook Roberto Sassu
2023-08-31 22:30   ` Casey Schaufler
2023-09-04 21:11   ` Jarkko Sakkinen
2023-09-05  6:51     ` Roberto Sassu
2023-09-05 16:49       ` Mimi Zohar
2023-08-31 10:41 ` [PATCH v2 14/25] security: Introduce file_post_open hook Roberto Sassu
2023-08-31 22:33   ` Casey Schaufler
2023-08-31 10:41 ` [PATCH v2 15/25] security: Introduce file_pre_free_security hook Roberto Sassu
2023-08-31 22:34   ` Casey Schaufler
2023-08-31 10:41 ` [PATCH v2 16/25] security: Introduce path_post_mknod hook Roberto Sassu
2023-08-31 22:34   ` Casey Schaufler
2023-08-31 10:41 ` [PATCH v2 17/25] security: Introduce inode_post_create_tmpfile hook Roberto Sassu
2023-08-31 22:35   ` Casey Schaufler
2023-08-31 10:41 ` [PATCH v2 18/25] security: Introduce inode_post_set_acl hook Roberto Sassu
2023-08-31 22:36   ` Casey Schaufler
2023-08-31 10:41 ` [PATCH v2 19/25] security: Introduce inode_post_remove_acl hook Roberto Sassu
2023-08-31 22:36   ` Casey Schaufler
2023-08-31 11:37 ` [PATCH v2 20/25] security: Introduce key_post_create_or_update hook Roberto Sassu
2023-08-31 22:37   ` Casey Schaufler
2023-08-31 11:37 ` [PATCH v2 21/25] ima: Move to LSM infrastructure Roberto Sassu
2023-08-31 14:10   ` Chuck Lever
2023-08-31 22:42   ` Casey Schaufler
2023-08-31 11:38 ` [PATCH v2 22/25] ima: Move IMA-Appraisal " Roberto Sassu
2023-08-31 11:38 ` [PATCH v2 23/25] evm: Move " Roberto Sassu
2023-08-31 22:46   ` Casey Schaufler
2023-08-31 11:38 ` [PATCH v2 24/25] integrity: Move integrity functions to the " Roberto Sassu
2023-08-31 22:49   ` Casey Schaufler
2023-08-31 11:38 ` [PATCH v2 25/25] integrity: Switch from rbtree to LSM-managed blob for integrity_iint_cache Roberto Sassu
2023-08-31 23:05   ` Casey Schaufler
2023-08-31 23:01 ` [PATCH v2 00/25] security: Move IMA and EVM to the LSM infrastructure Casey Schaufler

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).