Skip to content

Commit defdd02

Browse files
alberandbrauner
authored andcommitted
lsm: introduce new hooks for setting/getting inode fsxattr
Introduce new hooks for setting and getting filesystem extended attributes on inode (FS_IOC_FSGETXATTR). Cc: selinux@vger.kernel.org Cc: Paul Moore <paul@paul-moore.com> Acked-by: Paul Moore <paul@paul-moore.com> Signed-off-by: Andrey Albershteyn <aalbersh@kernel.org> Link: https://lore.kernel.org/20250630-xattrat-syscall-v6-2-c4e3bc35227b@kernel.org Signed-off-by: Christian Brauner <brauner@kernel.org>
1 parent 2f952c9 commit defdd02

4 files changed

Lines changed: 64 additions & 3 deletions

File tree

fs/file_attr.c

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -77,10 +77,15 @@ EXPORT_SYMBOL(fileattr_fill_flags);
7777
int vfs_fileattr_get(struct dentry *dentry, struct fileattr *fa)
7878
{
7979
struct inode *inode = d_inode(dentry);
80+
int error;
8081

8182
if (!inode->i_op->fileattr_get)
8283
return -ENOIOCTLCMD;
8384

85+
error = security_inode_file_getattr(dentry, fa);
86+
if (error)
87+
return error;
88+
8489
return inode->i_op->fileattr_get(dentry, fa);
8590
}
8691
EXPORT_SYMBOL(vfs_fileattr_get);
@@ -243,12 +248,20 @@ int vfs_fileattr_set(struct mnt_idmap *idmap, struct dentry *dentry,
243248
} else {
244249
fa->flags |= old_ma.flags & ~FS_COMMON_FL;
245250
}
251+
246252
err = fileattr_set_prepare(inode, &old_ma, fa);
247-
if (!err)
248-
err = inode->i_op->fileattr_set(idmap, dentry, fa);
253+
if (err)
254+
goto out;
255+
err = security_inode_file_setattr(dentry, fa);
256+
if (err)
257+
goto out;
258+
err = inode->i_op->fileattr_set(idmap, dentry, fa);
259+
if (err)
260+
goto out;
249261
}
250-
inode_unlock(inode);
251262

263+
out:
264+
inode_unlock(inode);
252265
return err;
253266
}
254267
EXPORT_SYMBOL(vfs_fileattr_set);

include/linux/lsm_hook_defs.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,8 @@ LSM_HOOK(int, 0, inode_removexattr, struct mnt_idmap *idmap,
157157
struct dentry *dentry, const char *name)
158158
LSM_HOOK(void, LSM_RET_VOID, inode_post_removexattr, struct dentry *dentry,
159159
const char *name)
160+
LSM_HOOK(int, 0, inode_file_setattr, struct dentry *dentry, struct fileattr *fa)
161+
LSM_HOOK(int, 0, inode_file_getattr, struct dentry *dentry, struct fileattr *fa)
160162
LSM_HOOK(int, 0, inode_set_acl, struct mnt_idmap *idmap,
161163
struct dentry *dentry, const char *acl_name, struct posix_acl *kacl)
162164
LSM_HOOK(void, LSM_RET_VOID, inode_post_set_acl, struct dentry *dentry,

include/linux/security.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -451,6 +451,10 @@ int security_inode_listxattr(struct dentry *dentry);
451451
int security_inode_removexattr(struct mnt_idmap *idmap,
452452
struct dentry *dentry, const char *name);
453453
void security_inode_post_removexattr(struct dentry *dentry, const char *name);
454+
int security_inode_file_setattr(struct dentry *dentry,
455+
struct fileattr *fa);
456+
int security_inode_file_getattr(struct dentry *dentry,
457+
struct fileattr *fa);
454458
int security_inode_need_killpriv(struct dentry *dentry);
455459
int security_inode_killpriv(struct mnt_idmap *idmap, struct dentry *dentry);
456460
int security_inode_getsecurity(struct mnt_idmap *idmap,
@@ -1052,6 +1056,18 @@ static inline void security_inode_post_removexattr(struct dentry *dentry,
10521056
const char *name)
10531057
{ }
10541058

1059+
static inline int security_inode_file_setattr(struct dentry *dentry,
1060+
struct fileattr *fa)
1061+
{
1062+
return 0;
1063+
}
1064+
1065+
static inline int security_inode_file_getattr(struct dentry *dentry,
1066+
struct fileattr *fa)
1067+
{
1068+
return 0;
1069+
}
1070+
10551071
static inline int security_inode_need_killpriv(struct dentry *dentry)
10561072
{
10571073
return cap_inode_need_killpriv(dentry);

security/security.c

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2622,6 +2622,36 @@ void security_inode_post_removexattr(struct dentry *dentry, const char *name)
26222622
call_void_hook(inode_post_removexattr, dentry, name);
26232623
}
26242624

2625+
/**
2626+
* security_inode_file_setattr() - check if setting fsxattr is allowed
2627+
* @dentry: file to set filesystem extended attributes on
2628+
* @fa: extended attributes to set on the inode
2629+
*
2630+
* Called when file_setattr() syscall or FS_IOC_FSSETXATTR ioctl() is called on
2631+
* inode
2632+
*
2633+
* Return: Returns 0 if permission is granted.
2634+
*/
2635+
int security_inode_file_setattr(struct dentry *dentry, struct fileattr *fa)
2636+
{
2637+
return call_int_hook(inode_file_setattr, dentry, fa);
2638+
}
2639+
2640+
/**
2641+
* security_inode_file_getattr() - check if retrieving fsxattr is allowed
2642+
* @dentry: file to retrieve filesystem extended attributes from
2643+
* @fa: extended attributes to get
2644+
*
2645+
* Called when file_getattr() syscall or FS_IOC_FSGETXATTR ioctl() is called on
2646+
* inode
2647+
*
2648+
* Return: Returns 0 if permission is granted.
2649+
*/
2650+
int security_inode_file_getattr(struct dentry *dentry, struct fileattr *fa)
2651+
{
2652+
return call_int_hook(inode_file_getattr, dentry, fa);
2653+
}
2654+
26252655
/**
26262656
* security_inode_need_killpriv() - Check if security_inode_killpriv() required
26272657
* @dentry: associated dentry

0 commit comments

Comments
 (0)