Skip to content

Commit

Permalink
Merge tag 'fs.acl.rework.prep.v6.1' of git://git.kernel.org/pub/scm/l…
Browse files Browse the repository at this point in the history
…inux/kernel/git/vfs/idmapping

Pull vfs acl updates from Christian Brauner:
 "These are general fixes and preparatory changes related to the ongoing
  posix acl rework. The actual rework where we build a type safe posix
  acl api wasn't ready for this merge window but we're hopeful for the
  next merge window.

  General fixes:

   - Some filesystems like 9p and cifs have to implement custom posix
     acl handlers because they require access to the dentry in order to
     set and get posix acls while the set and get inode operations
     currently don't. But the ntfs3 filesystem has no such requirement
     and thus implemented custom posix acl xattr handlers when it really
     didn't have to. So this pr contains patch that just implements set
     and get inode operations for ntfs3 and switches it to rely on the
     generic posix acl xattr handlers. (We would've appreciated reviews
     from the ntfs3 maintainers but we didn't get any. But hey, if we
     really broke it we'll fix it. But fstests for ntfs3 said it's
     fine.)

   - The posix_acl_fix_xattr_common() helper has been adapted so it can
     be used by a few more callers and avoiding open-coding the same
     checks over and over.

  Other than the two general fixes this series introduces a new helper
  vfs_set_acl_prepare(). The reason for this helper is so that we can
  mitigate one of the source that change {g,u}id values directly in the
  uapi struct. With the vfs_set_acl_prepare() helper we can move the
  idmapped mount fixup into the generic posix acl set handler.

  The advantage of this is that it allows us to remove the
  posix_acl_setxattr_idmapped_mnt() helper which so far we had to call
  in vfs_setxattr() to account for idmapped mounts. While semantically
  correct the problem with this approach was that we had to keep the
  value parameter of the generic vfs_setxattr() call as non-const. This
  is rectified in this series.

  Ultimately, we will get rid of all the extreme kludges and type
  unsafety once we have merged the posix api - hopefully during the next
  merge window - built solely around get and set inode operations. Which
  incidentally will also improve handling of posix acls in security and
  especially in integrity modesl. While this will come with temporarily
  having two inode operation for posix acls that is nothing compared to
  the problems we have right now and so well worth it. We'll end up with
  something that we can actually reason about instead of needing to
  write novels to explain what's going on"

* tag 'fs.acl.rework.prep.v6.1' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/idmapping:
  xattr: always us is_posix_acl_xattr() helper
  acl: fix the comments of posix_acl_xattr_set
  xattr: constify value argument in vfs_setxattr()
  ovl: use vfs_set_acl_prepare()
  acl: move idmapping handling into posix_acl_xattr_set()
  acl: add vfs_set_acl_prepare()
  acl: return EOPNOTSUPP in posix_acl_fix_xattr_common()
  ntfs3: rework xattr handlers and switch to POSIX ACL VFS helpers
  • Loading branch information
torvalds committed Oct 4, 2022
2 parents da380ae + 38e3163 commit 223b845
Show file tree
Hide file tree
Showing 9 changed files with 264 additions and 191 deletions.
2 changes: 0 additions & 2 deletions fs/ntfs3/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -1927,8 +1927,6 @@ const struct inode_operations ntfs_link_inode_operations = {
.setattr = ntfs3_setattr,
.listxattr = ntfs_listxattr,
.permission = ntfs_permission,
.get_acl = ntfs_get_acl,
.set_acl = ntfs_set_acl,
};

const struct address_space_operations ntfs_aops = {
Expand Down
102 changes: 6 additions & 96 deletions fs/ntfs3/xattr.c
Original file line number Diff line number Diff line change
Expand Up @@ -625,67 +625,6 @@ int ntfs_set_acl(struct user_namespace *mnt_userns, struct inode *inode,
return ntfs_set_acl_ex(mnt_userns, inode, acl, type, false);
}

static int ntfs_xattr_get_acl(struct user_namespace *mnt_userns,
struct inode *inode, int type, void *buffer,
size_t size)
{
struct posix_acl *acl;
int err;

if (!(inode->i_sb->s_flags & SB_POSIXACL)) {
ntfs_inode_warn(inode, "add mount option \"acl\" to use acl");
return -EOPNOTSUPP;
}

acl = ntfs_get_acl(inode, type, false);
if (IS_ERR(acl))
return PTR_ERR(acl);

if (!acl)
return -ENODATA;

err = posix_acl_to_xattr(&init_user_ns, acl, buffer, size);
posix_acl_release(acl);

return err;
}

static int ntfs_xattr_set_acl(struct user_namespace *mnt_userns,
struct inode *inode, int type, const void *value,
size_t size)
{
struct posix_acl *acl;
int err;

if (!(inode->i_sb->s_flags & SB_POSIXACL)) {
ntfs_inode_warn(inode, "add mount option \"acl\" to use acl");
return -EOPNOTSUPP;
}

if (!inode_owner_or_capable(mnt_userns, inode))
return -EPERM;

if (!value) {
acl = NULL;
} else {
acl = posix_acl_from_xattr(&init_user_ns, value, size);
if (IS_ERR(acl))
return PTR_ERR(acl);

if (acl) {
err = posix_acl_valid(&init_user_ns, acl);
if (err)
goto release_and_out;
}
}

err = ntfs_set_acl(mnt_userns, inode, acl, type);

release_and_out:
posix_acl_release(acl);
return err;
}

/*
* ntfs_init_acl - Initialize the ACLs of a new inode.
*
Expand Down Expand Up @@ -852,23 +791,6 @@ static int ntfs_getxattr(const struct xattr_handler *handler, struct dentry *de,
goto out;
}

#ifdef CONFIG_NTFS3_FS_POSIX_ACL
if ((name_len == sizeof(XATTR_NAME_POSIX_ACL_ACCESS) - 1 &&
!memcmp(name, XATTR_NAME_POSIX_ACL_ACCESS,
sizeof(XATTR_NAME_POSIX_ACL_ACCESS))) ||
(name_len == sizeof(XATTR_NAME_POSIX_ACL_DEFAULT) - 1 &&
!memcmp(name, XATTR_NAME_POSIX_ACL_DEFAULT,
sizeof(XATTR_NAME_POSIX_ACL_DEFAULT)))) {
/* TODO: init_user_ns? */
err = ntfs_xattr_get_acl(
&init_user_ns, inode,
name_len == sizeof(XATTR_NAME_POSIX_ACL_ACCESS) - 1
? ACL_TYPE_ACCESS
: ACL_TYPE_DEFAULT,
buffer, size);
goto out;
}
#endif
/* Deal with NTFS extended attribute. */
err = ntfs_get_ea(inode, name, name_len, buffer, size, NULL);

Expand Down Expand Up @@ -981,22 +903,6 @@ static noinline int ntfs_setxattr(const struct xattr_handler *handler,
goto out;
}

#ifdef CONFIG_NTFS3_FS_POSIX_ACL
if ((name_len == sizeof(XATTR_NAME_POSIX_ACL_ACCESS) - 1 &&
!memcmp(name, XATTR_NAME_POSIX_ACL_ACCESS,
sizeof(XATTR_NAME_POSIX_ACL_ACCESS))) ||
(name_len == sizeof(XATTR_NAME_POSIX_ACL_DEFAULT) - 1 &&
!memcmp(name, XATTR_NAME_POSIX_ACL_DEFAULT,
sizeof(XATTR_NAME_POSIX_ACL_DEFAULT)))) {
err = ntfs_xattr_set_acl(
mnt_userns, inode,
name_len == sizeof(XATTR_NAME_POSIX_ACL_ACCESS) - 1
? ACL_TYPE_ACCESS
: ACL_TYPE_DEFAULT,
value, size);
goto out;
}
#endif
/* Deal with NTFS extended attribute. */
err = ntfs_set_ea(inode, name, name_len, value, size, flags, 0);

Expand Down Expand Up @@ -1086,15 +992,19 @@ static bool ntfs_xattr_user_list(struct dentry *dentry)
}

// clang-format off
static const struct xattr_handler ntfs_xattr_handler = {
static const struct xattr_handler ntfs_other_xattr_handler = {
.prefix = "",
.get = ntfs_getxattr,
.set = ntfs_setxattr,
.list = ntfs_xattr_user_list,
};

const struct xattr_handler *ntfs_xattr_handlers[] = {
&ntfs_xattr_handler,
#ifdef CONFIG_NTFS3_FS_POSIX_ACL
&posix_acl_access_xattr_handler,
&posix_acl_default_xattr_handler,
#endif
&ntfs_other_xattr_handler,
NULL,
};
// clang-format on
2 changes: 1 addition & 1 deletion fs/overlayfs/overlayfs.h
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,7 @@ static inline int ovl_do_setxattr(struct ovl_fs *ofs, struct dentry *dentry,
size_t size, int flags)
{
int err = vfs_setxattr(ovl_upper_mnt_userns(ofs), dentry, name,
(void *)value, size, flags);
value, size, flags);

pr_debug("setxattr(%pd2, \"%s\", \"%*pE\", %zu, %d) = %i\n",
dentry, name, min((int)size, 48), value, size, flags, err);
Expand Down
15 changes: 14 additions & 1 deletion fs/overlayfs/super.c
Original file line number Diff line number Diff line change
Expand Up @@ -1022,7 +1022,20 @@ ovl_posix_acl_xattr_set(const struct xattr_handler *handler,

/* Check that everything is OK before copy-up */
if (value) {
acl = posix_acl_from_xattr(&init_user_ns, value, size);
/* The above comment can be understood in two ways:
*
* 1. We just want to check whether the basic POSIX ACL format
* is ok. For example, if the header is correct and the size
* is sane.
* 2. We want to know whether the ACL_{GROUP,USER} entries can
* be mapped according to the underlying filesystem.
*
* Currently, we only check 1. If we wanted to check 2. we
* would need to pass the mnt_userns and the fs_userns of the
* underlying filesystem. But frankly, I think checking 1. is
* enough to start the copy-up.
*/
acl = vfs_set_acl_prepare(&init_user_ns, &init_user_ns, value, size);
if (IS_ERR(acl))
return PTR_ERR(acl);
}
Expand Down
Loading

0 comments on commit 223b845

Please sign in to comment.