Commit 8b9d0b82 authored by Roberto Sassu's avatar Roberto Sassu Committed by Paul Moore
Browse files

security: Introduce inode_post_set_acl hook



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: default avatarRoberto Sassu <roberto.sassu@huawei.com>
Reviewed-by: default avatarStefan Berger <stefanb@linux.ibm.com>
Acked-by: default avatarCasey Schaufler <casey@schaufler-ca.com>
Reviewed-by: default avatarMimi Zohar <zohar@linux.ibm.com>
Acked-by: default avatarChristian Brauner <brauner@kernel.org>
Signed-off-by: default avatarPaul Moore <paul@paul-moore.com>
parent a7811e34
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -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);
	}

+2 −0
Original line number Diff line number Diff line
@@ -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,
+7 −0
Original line number Diff line number Diff line
@@ -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)
+17 −0
Original line number Diff line number Diff line
@@ -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