evm: Align evm_inode_init_security() definition with LSM infrastructure
authorRoberto Sassu <roberto.sassu@huawei.com>
Sat, 10 Jun 2023 07:57:37 +0000 (09:57 +0200)
committerPaul Moore <paul@paul-moore.com>
Mon, 10 Jul 2023 17:59:38 +0000 (13:59 -0400)
Change the evm_inode_init_security() definition to align with the LSM
infrastructure. Keep the existing behavior of including in the HMAC
calculation only the first xattr provided by LSMs.

Changing the evm_inode_init_security() definition requires passing the
xattr array allocated by security_inode_init_security(), and the number of
xattrs filled by previously invoked LSMs.

Use the newly introduced lsm_get_xattr_slot() to position EVM correctly in
the xattrs array, like a regular LSM, and to increment the number of filled
slots. For now, the LSM infrastructure allocates enough xattrs slots to
store the EVM xattr, without using the reservation mechanism.

Signed-off-by: Roberto Sassu <roberto.sassu@huawei.com>
Reviewed-by: Mimi Zohar <zohar@linux.ibm.com>
Acked-by: Mimi Zohar <zohar@linux.ibm.com>
Signed-off-by: Paul Moore <paul@paul-moore.com>
include/linux/evm.h
security/integrity/evm/evm_main.c
security/security.c

index 7dc1ee74169fdc98d6f8789ad0e3a3f5157d70b5..01fc495a83e27816088954955a3e56e6da470acf 100644 (file)
@@ -56,9 +56,10 @@ static inline void evm_inode_post_set_acl(struct dentry *dentry,
 {
        return evm_inode_post_setxattr(dentry, acl_name, NULL, 0);
 }
-extern int evm_inode_init_security(struct inode *inode,
-                                  const struct xattr *xattr_array,
-                                  struct xattr *evm);
+
+int evm_inode_init_security(struct inode *inode, struct inode *dir,
+                           const struct qstr *qstr, struct xattr *xattrs,
+                           int *xattr_count);
 extern bool evm_revalidate_status(const char *xattr_name);
 extern int evm_protected_xattr_if_enabled(const char *req_xattr_name);
 extern int evm_read_protected_xattrs(struct dentry *dentry, u8 *buffer,
@@ -157,9 +158,10 @@ static inline void evm_inode_post_set_acl(struct dentry *dentry,
        return;
 }
 
-static inline int evm_inode_init_security(struct inode *inode,
-                                         const struct xattr *xattr_array,
-                                         struct xattr *evm)
+static inline int evm_inode_init_security(struct inode *inode, struct inode *dir,
+                                         const struct qstr *qstr,
+                                         struct xattr *xattrs,
+                                         int *xattr_count)
 {
        return 0;
 }
index c9b6e2a43478a0e5f8dd8bd65f62af62a9bfad7a..84eaf05ce0d4f79d9144e3c1bd900603779f560c 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/evm.h>
 #include <linux/magic.h>
 #include <linux/posix_acl_xattr.h>
+#include <linux/lsm_hooks.h>
 
 #include <crypto/hash.h>
 #include <crypto/hash_info.h>
@@ -866,23 +867,26 @@ void evm_inode_post_setattr(struct dentry *dentry, int ia_valid)
 /*
  * evm_inode_init_security - initializes security.evm HMAC value
  */
-int evm_inode_init_security(struct inode *inode,
-                                const struct xattr *lsm_xattr,
-                                struct xattr *evm_xattr)
+int evm_inode_init_security(struct inode *inode, struct inode *dir,
+                           const struct qstr *qstr, struct xattr *xattrs,
+                           int *xattr_count)
 {
        struct evm_xattr *xattr_data;
+       struct xattr *evm_xattr;
        int rc;
 
-       if (!(evm_initialized & EVM_INIT_HMAC) ||
-           !evm_protected_xattr(lsm_xattr->name))
+       if (!(evm_initialized & EVM_INIT_HMAC) || !xattrs ||
+           !evm_protected_xattr(xattrs->name))
                return 0;
 
+       evm_xattr = lsm_get_xattr_slot(xattrs, xattr_count);
+
        xattr_data = kzalloc(sizeof(*xattr_data), GFP_NOFS);
        if (!xattr_data)
                return -ENOMEM;
 
        xattr_data->data.type = EVM_XATTR_HMAC;
-       rc = evm_init_hmac(inode, lsm_xattr, xattr_data->digest);
+       rc = evm_init_hmac(inode, xattrs, xattr_data->digest);
        if (rc < 0)
                goto out;
 
index b3ba030c7546383c287ae341191192ca1b39fadd..cfdd0cbbcb91b423736f1715fc72551c07fbbb1a 100644 (file)
@@ -1647,8 +1647,8 @@ int security_inode_init_security(struct inode *inode, struct inode *dir,
        if (!xattr_count)
                goto out;
 
-       ret = evm_inode_init_security(inode, new_xattrs,
-                                     &new_xattrs[xattr_count]);
+       ret = evm_inode_init_security(inode, dir, qstr, new_xattrs,
+                                     &xattr_count);
        if (ret)
                goto out;
        ret = initxattrs(inode, new_xattrs, fs_data);