The uapi POSIX ACL struct passed through the value argument during
setxattr() contains {g,u}id values encoded via ACL_{GROUP,USER} entries
that should actually be stored in the form of k{g,u}id_t (See [1] for a
long explanation of the issue.).
In 0c5fd887d2
("acl: move idmapped mount fixup into vfs_{g,s}etxattr()")
we took the mount's idmapping into account in order to let overlayfs
handle POSIX ACLs on idmapped layers correctly. The fixup is currently
performed directly in vfs_setxattr() which piles on top of the earlier
hackiness by handling the mount's idmapping and stuff the vfs{g,u}id_t
values into the uapi struct as well. While that is all correct and works
fine it's just ugly.
Now that we have introduced vfs_make_posix_acl() earlier move handling
idmapped mounts out of vfs_setxattr() and into the POSIX ACL handler
where it belongs.
Note that we also need to call vfs_make_posix_acl() for EVM which
interpretes POSIX ACLs during security_inode_setxattr(). Leave them a
longer comment for future reference.
All filesystems that support idmapped mounts via FS_ALLOW_IDMAP use the
standard POSIX ACL xattr handlers and are covered by this change. This
includes overlayfs which simply calls vfs_{g,s}etxattr().
The following filesystems use custom POSIX ACL xattr handlers: 9p, cifs,
ecryptfs, and ntfs3 (and overlayfs but we've covered that in the paragraph
above) and none of them support idmapped mounts yet.
Link: https://lore.kernel.org/all/20220801145520.1532837-1-brauner@kernel.org/ [1]
Signed-off-by: Christian Brauner (Microsoft) <brauner@kernel.org>
Reviewed-by: Seth Forshee (DigitalOcean) <sforshee@kernel.org>
68 lines
2.0 KiB
C
68 lines
2.0 KiB
C
/* SPDX-License-Identifier: GPL-2.0 */
|
|
/*
|
|
File: linux/posix_acl_xattr.h
|
|
|
|
Extended attribute system call representation of Access Control Lists.
|
|
|
|
Copyright (C) 2000 by Andreas Gruenbacher <a.gruenbacher@computer.org>
|
|
Copyright (C) 2002 SGI - Silicon Graphics, Inc <linux-xfs@oss.sgi.com>
|
|
*/
|
|
#ifndef _POSIX_ACL_XATTR_H
|
|
#define _POSIX_ACL_XATTR_H
|
|
|
|
#include <uapi/linux/xattr.h>
|
|
#include <uapi/linux/posix_acl_xattr.h>
|
|
#include <linux/posix_acl.h>
|
|
|
|
static inline size_t
|
|
posix_acl_xattr_size(int count)
|
|
{
|
|
return (sizeof(struct posix_acl_xattr_header) +
|
|
(count * sizeof(struct posix_acl_xattr_entry)));
|
|
}
|
|
|
|
static inline int
|
|
posix_acl_xattr_count(size_t size)
|
|
{
|
|
if (size < sizeof(struct posix_acl_xattr_header))
|
|
return -1;
|
|
size -= sizeof(struct posix_acl_xattr_header);
|
|
if (size % sizeof(struct posix_acl_xattr_entry))
|
|
return -1;
|
|
return size / sizeof(struct posix_acl_xattr_entry);
|
|
}
|
|
|
|
#ifdef CONFIG_FS_POSIX_ACL
|
|
void posix_acl_fix_xattr_from_user(void *value, size_t size);
|
|
void posix_acl_fix_xattr_to_user(void *value, size_t size);
|
|
void posix_acl_getxattr_idmapped_mnt(struct user_namespace *mnt_userns,
|
|
const struct inode *inode,
|
|
void *value, size_t size);
|
|
#else
|
|
static inline void posix_acl_fix_xattr_from_user(void *value, size_t size)
|
|
{
|
|
}
|
|
static inline void posix_acl_fix_xattr_to_user(void *value, size_t size)
|
|
{
|
|
}
|
|
static inline void
|
|
posix_acl_getxattr_idmapped_mnt(struct user_namespace *mnt_userns,
|
|
const struct inode *inode, void *value,
|
|
size_t size)
|
|
{
|
|
}
|
|
#endif
|
|
|
|
struct posix_acl *posix_acl_from_xattr(struct user_namespace *user_ns,
|
|
const void *value, size_t size);
|
|
int posix_acl_to_xattr(struct user_namespace *user_ns,
|
|
const struct posix_acl *acl, void *buffer, size_t size);
|
|
struct posix_acl *vfs_set_acl_prepare(struct user_namespace *mnt_userns,
|
|
struct user_namespace *fs_userns,
|
|
const void *value, size_t size);
|
|
|
|
extern const struct xattr_handler posix_acl_access_xattr_handler;
|
|
extern const struct xattr_handler posix_acl_default_xattr_handler;
|
|
|
|
#endif /* _POSIX_ACL_XATTR_H */
|