Skip to content

Commit dae52cb

Browse files
robertosassupcmoore
authored andcommitted
security: Introduce inode_post_removexattr hook
In preparation for moving IMA and EVM to the LSM infrastructure, introduce the inode_post_removexattr hook. At inode_removexattr hook, EVM verifies the file's existing HMAC value. At inode_post_removexattr, EVM re-calculates the file's HMAC with the passed xattr removed and other file metadata. Other LSMs could similarly take some action after successful xattr removal. The new hook cannot return an error and cannot cause the operation to be reverted. Signed-off-by: Roberto Sassu <[email protected]> Reviewed-by: Stefan Berger <[email protected]> Reviewed-by: Mimi Zohar <[email protected]> Reviewed-by: Casey Schaufler <[email protected]> Acked-by: Christian Brauner <[email protected]> Signed-off-by: Paul Moore <[email protected]>
1 parent 77fa6f3 commit dae52cb

File tree

4 files changed

+26
-4
lines changed

4 files changed

+26
-4
lines changed

fs/xattr.c

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -552,11 +552,12 @@ __vfs_removexattr_locked(struct mnt_idmap *idmap,
552552
goto out;
553553

554554
error = __vfs_removexattr(idmap, dentry, name);
555+
if (error)
556+
return error;
555557

556-
if (!error) {
557-
fsnotify_xattr(dentry);
558-
evm_inode_post_removexattr(dentry, name);
559-
}
558+
fsnotify_xattr(dentry);
559+
security_inode_post_removexattr(dentry, name);
560+
evm_inode_post_removexattr(dentry, name);
560561

561562
out:
562563
return error;

include/linux/lsm_hook_defs.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,8 @@ LSM_HOOK(int, 0, inode_getxattr, struct dentry *dentry, const char *name)
149149
LSM_HOOK(int, 0, inode_listxattr, struct dentry *dentry)
150150
LSM_HOOK(int, 0, inode_removexattr, struct mnt_idmap *idmap,
151151
struct dentry *dentry, const char *name)
152+
LSM_HOOK(void, LSM_RET_VOID, inode_post_removexattr, struct dentry *dentry,
153+
const char *name)
152154
LSM_HOOK(int, 0, inode_set_acl, struct mnt_idmap *idmap,
153155
struct dentry *dentry, const char *acl_name, struct posix_acl *kacl)
154156
LSM_HOOK(int, 0, inode_get_acl, struct mnt_idmap *idmap,

include/linux/security.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -380,6 +380,7 @@ int security_inode_getxattr(struct dentry *dentry, const char *name);
380380
int security_inode_listxattr(struct dentry *dentry);
381381
int security_inode_removexattr(struct mnt_idmap *idmap,
382382
struct dentry *dentry, const char *name);
383+
void security_inode_post_removexattr(struct dentry *dentry, const char *name);
383384
int security_inode_need_killpriv(struct dentry *dentry);
384385
int security_inode_killpriv(struct mnt_idmap *idmap, struct dentry *dentry);
385386
int security_inode_getsecurity(struct mnt_idmap *idmap,
@@ -942,6 +943,10 @@ static inline int security_inode_removexattr(struct mnt_idmap *idmap,
942943
return cap_inode_removexattr(idmap, dentry, name);
943944
}
944945

946+
static inline void security_inode_post_removexattr(struct dentry *dentry,
947+
const char *name)
948+
{ }
949+
945950
static inline int security_inode_need_killpriv(struct dentry *dentry)
946951
{
947952
return cap_inode_need_killpriv(dentry);

security/security.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2452,6 +2452,20 @@ int security_inode_removexattr(struct mnt_idmap *idmap,
24522452
return evm_inode_removexattr(idmap, dentry, name);
24532453
}
24542454

2455+
/**
2456+
* security_inode_post_removexattr() - Update the inode after a removexattr op
2457+
* @dentry: file
2458+
* @name: xattr name
2459+
*
2460+
* Update the inode after a successful removexattr operation.
2461+
*/
2462+
void security_inode_post_removexattr(struct dentry *dentry, const char *name)
2463+
{
2464+
if (unlikely(IS_PRIVATE(d_backing_inode(dentry))))
2465+
return;
2466+
call_void_hook(inode_post_removexattr, dentry, name);
2467+
}
2468+
24552469
/**
24562470
* security_inode_need_killpriv() - Check if security_inode_killpriv() required
24572471
* @dentry: associated dentry

0 commit comments

Comments
 (0)