diff options
author | Christian Brauner <brauner@kernel.org> | 2022-09-22 18:17:22 +0300 |
---|---|---|
committer | Christian Brauner (Microsoft) <brauner@kernel.org> | 2022-10-20 11:13:31 +0300 |
commit | 318e66856ddec05384f32d60b5598128289f4e7b (patch) | |
tree | 5df1c4b7fbc3e2328be5f016393f2c6decf99b20 /fs/posix_acl.c | |
parent | 31acceb97500dd6e9105526301d76488cd6ca21c (diff) | |
download | linux-318e66856ddec05384f32d60b5598128289f4e7b.tar.xz |
xattr: use posix acl api
In previous patches we built a new posix api solely around get and set
inode operations. Now that we have all the pieces in place we can switch
the system calls and the vfs over to only rely on this api when
interacting with posix acls. This finally removes all type unsafety and
type conversion issues explained in detail in [1] that we aim to get rid
of.
With the new posix acl api we immediately translate into an appropriate
kernel internal struct posix_acl format both when getting and setting
posix acls. This is a stark contrast to before were we hacked unsafe raw
values into the uapi struct that was stored in a void pointer relying
and having filesystems and security modules hack around in the uapi
struct as well.
Link: https://lore.kernel.org/all/20220801145520.1532837-1-brauner@kernel.org [1]
Signed-off-by: Christian Brauner (Microsoft) <brauner@kernel.org>
Diffstat (limited to 'fs/posix_acl.c')
-rw-r--r-- | fs/posix_acl.c | 37 |
1 files changed, 37 insertions, 0 deletions
diff --git a/fs/posix_acl.c b/fs/posix_acl.c index 3a141082b24c..14b87653b797 100644 --- a/fs/posix_acl.c +++ b/fs/posix_acl.c @@ -1544,3 +1544,40 @@ out_inode_unlock: return error; } EXPORT_SYMBOL_GPL(vfs_remove_acl); + +int do_set_acl(struct user_namespace *mnt_userns, struct dentry *dentry, + const char *acl_name, const void *kvalue, size_t size) +{ + int error; + struct posix_acl *acl = NULL; + + if (size) { + /* + * Note that posix_acl_from_xattr() uses GFP_NOFS when it + * probably doesn't need to here. + */ + acl = posix_acl_from_xattr(current_user_ns(), kvalue, size); + if (IS_ERR(acl)) + return PTR_ERR(acl); + } + + error = vfs_set_acl(mnt_userns, dentry, acl_name, acl); + posix_acl_release(acl); + return error; +} + +ssize_t do_get_acl(struct user_namespace *mnt_userns, struct dentry *dentry, + const char *acl_name, void *kvalue, size_t size) +{ + ssize_t error; + struct posix_acl *acl; + + acl = vfs_get_acl(mnt_userns, dentry, acl_name); + if (IS_ERR(acl)) + return PTR_ERR(acl); + + error = vfs_posix_acl_to_xattr(mnt_userns, d_inode(dentry), + acl, kvalue, size); + posix_acl_release(acl); + return error; +} |