security: Introduce inode_post_set_acl hook
authorRoberto Sassu <roberto.sassu@huawei.com>
Thu, 15 Feb 2024 10:31:04 +0000 (11:31 +0100)
committerPaul Moore <paul@paul-moore.com>
Fri, 16 Feb 2024 04:43:44 +0000 (23:43 -0500)
In preparation for moving IMA and EVM to the LSM infrastructure, introduce
the inode_post_set_acl hook.

At inode_set_acl hook, EVM verifies the file's existing HMAC value. At
inode_post_set_acl, EVM re-calculates the file's HMAC based on the modified
POSIX ACL and other file metadata.

Other LSMs could similarly take some action after successful POSIX ACL
change.

The new hook cannot return an error and cannot cause the operation to be
reverted.

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>
Reviewed-by: Mimi Zohar <zohar@linux.ibm.com>
Acked-by: Christian Brauner <brauner@kernel.org>
Signed-off-by: Paul Moore <paul@paul-moore.com>
fs/posix_acl.c
include/linux/lsm_hook_defs.h
include/linux/security.h
security/security.c

index e1af20893ebe1ed400acb7c7215377868f623bbf..7556ee9f8a514fe54887d1e6a154607f5f54d11c 100644 (file)
@@ -1137,6 +1137,7 @@ retry_deleg:
                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);
        }
 
index 87f60b47dfcadfce57b04b1e2883b2066f23644f..b0125c99f80a3ad747c0a92f637b9a7e3e9f6e0e 100644 (file)
@@ -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,
index 1cb60428261778a7723c26768e63fed2abd611ed..c372797e16170a303906351ad1636e960f86c53f 100644 (file)
@@ -372,6 +372,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,
@@ -915,6 +917,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)
index 710db090aa8b301ff9189fc8d3f2e5dbc01df741..52f62f7850870f19c3432bad17409dc270c7a470 100644 (file)
@@ -2350,6 +2350,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 from posix acls set
+ * @dentry: file
+ * @acl_name: acl name
+ * @kacl: acl struct
+ *
+ * Update inode security data after successfully setting posix acls 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