Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge tag 'fs.idmapped.overlay.acl.v5.20' of git://git.kernel.org/pub/scm/linux/kernel/git/brauner/linux

Pull acl updates from Christian Brauner:
"Last cycle we introduced support for mounting overlayfs on top of
idmapped mounts. While looking into additional testing we realized
that posix acls don't really work correctly with stacking filesystems
on top of idmapped layers.

We already knew what the fix were but it would require work that is
more suitable for the merge window so we turned off posix acls for
v5.19 for overlayfs on top of idmapped layers with Miklos routing my
patch upstream in 72a8e05d4f66 ("Merge tag 'ovl-fixes-5.19-rc7' [..]").

This contains the work to support posix acls for overlayfs on top of
idmapped layers. Since the posix acl fixes should use the new
vfs{g,u}id_t work the associated branch has been merged in. (We sent a
pull request for this earlier.)

We've also pulled in Miklos pull request containing my patch to turn
of posix acls on top of idmapped layers. This allowed us to avoid
rebasing the branch which we didn't like because we were already at
rc7 by then. Merging it in allows this branch to first fix posix acls
and then to cleanly revert the temporary fix it brought in by commit
4a47c6385bb4 ("ovl: turn of SB_POSIXACL with idmapped layers
temporarily").

The last patch in this series adds Seth Forshee as a co-maintainer for
idmapped mounts. Seth has been integral to all of this work and is
also the main architect behind the filesystem idmapping work which
ultimately made filesystems such as FUSE and overlayfs available in
containers. He continues to be active in both development and review.
I'm very happy he decided to help and he has my full trust. This
increases the bus factor which is always great for work like this. I'm
honestly very excited about this because I think in general we don't
do great in the bringing on new maintainers department"

For more explanations of the ACL issues, see

https://lore.kernel.org/all/20220801145520.1532837-1-brauner@kernel.org/

* tag 'fs.idmapped.overlay.acl.v5.20' of git://git.kernel.org/pub/scm/linux/kernel/git/brauner/linux:
Add Seth Forshee as co-maintainer for idmapped mounts
Revert "ovl: turn of SB_POSIXACL with idmapped layers temporarily"
ovl: handle idmappings in ovl_get_acl()
acl: make posix_acl_clone() available to overlayfs
acl: port to vfs{g,u}id_t
acl: move idmapped mount fixup into vfs_{g,s}etxattr()
mnt_idmapping: add vfs[g,u]id_into_k[g,u]id()

+273 -113
-4
Documentation/filesystems/overlayfs.rst
··· 466 466 persistent and could change even while the overlay filesystem is mounted, as 467 467 summarized in the `Inode properties`_ table above. 468 468 469 - 4) "idmapped mounts" 470 - When the upper or lower layers are idmapped mounts overlayfs will be mounted 471 - without support for POSIX Access Control Lists (ACLs). This limitation will 472 - eventually be lifted. 473 469 474 470 Changes to underlying filesystems 475 471 ---------------------------------
+1
MAINTAINERS
··· 9620 9620 9621 9621 IDMAPPED MOUNTS 9622 9622 M: Christian Brauner <brauner@kernel.org> 9623 + M: Seth Forshee <sforshee@kernel.org> 9623 9624 L: linux-fsdevel@vger.kernel.org 9624 9625 S: Maintained 9625 9626 T: git git://git.kernel.org/pub/scm/linux/kernel/git/brauner/linux.git
+1 -1
fs/ksmbd/vfs.c
··· 963 963 */ 964 964 int ksmbd_vfs_setxattr(struct user_namespace *user_ns, 965 965 struct dentry *dentry, const char *attr_name, 966 - const void *attr_value, size_t attr_size, int flags) 966 + void *attr_value, size_t attr_size, int flags) 967 967 { 968 968 int err; 969 969
+1 -1
fs/ksmbd/vfs.h
··· 109 109 int attr_name_len); 110 110 int ksmbd_vfs_setxattr(struct user_namespace *user_ns, 111 111 struct dentry *dentry, const char *attr_name, 112 - const void *attr_value, size_t attr_size, int flags); 112 + void *attr_value, size_t attr_size, int flags); 113 113 int ksmbd_vfs_xattr_stream_name(char *stream_name, char **xattr_stream_name, 114 114 size_t *xattr_stream_name_size, int s_type); 115 115 int ksmbd_vfs_remove_xattr(struct user_namespace *user_ns,
+79 -8
fs/overlayfs/inode.c
··· 454 454 return res; 455 455 } 456 456 457 + /* 458 + * Apply the idmapping of the layer to POSIX ACLs. The caller must pass a clone 459 + * of the POSIX ACLs retrieved from the lower layer to this function to not 460 + * alter the POSIX ACLs for the underlying filesystem. 461 + */ 462 + static void ovl_idmap_posix_acl(struct user_namespace *mnt_userns, 463 + struct posix_acl *acl) 464 + { 465 + for (unsigned int i = 0; i < acl->a_count; i++) { 466 + vfsuid_t vfsuid; 467 + vfsgid_t vfsgid; 468 + 469 + struct posix_acl_entry *e = &acl->a_entries[i]; 470 + switch (e->e_tag) { 471 + case ACL_USER: 472 + vfsuid = make_vfsuid(mnt_userns, &init_user_ns, e->e_uid); 473 + e->e_uid = vfsuid_into_kuid(vfsuid); 474 + break; 475 + case ACL_GROUP: 476 + vfsgid = make_vfsgid(mnt_userns, &init_user_ns, e->e_gid); 477 + e->e_gid = vfsgid_into_kgid(vfsgid); 478 + break; 479 + } 480 + } 481 + } 482 + 483 + /* 484 + * When the relevant layer is an idmapped mount we need to take the idmapping 485 + * of the layer into account and translate any ACL_{GROUP,USER} values 486 + * according to the idmapped mount. 487 + * 488 + * We cannot alter the ACLs returned from the relevant layer as that would 489 + * alter the cached values filesystem wide for the lower filesystem. Instead we 490 + * can clone the ACLs and then apply the relevant idmapping of the layer. 491 + * 492 + * This is obviously only relevant when idmapped layers are used. 493 + */ 457 494 struct posix_acl *ovl_get_acl(struct inode *inode, int type, bool rcu) 458 495 { 459 496 struct inode *realinode = ovl_inode_real(inode); 460 - const struct cred *old_cred; 461 - struct posix_acl *acl; 497 + struct posix_acl *acl, *clone; 498 + struct path realpath; 462 499 463 500 if (!IS_ENABLED(CONFIG_FS_POSIX_ACL) || !IS_POSIXACL(realinode)) 464 501 return NULL; 465 502 503 + /* Careful in RCU walk mode */ 504 + ovl_i_path_real(inode, &realpath); 505 + if (!realpath.dentry) { 506 + WARN_ON(!rcu); 507 + return ERR_PTR(-ECHILD); 508 + } 509 + 510 + if (rcu) { 511 + acl = get_cached_acl_rcu(realinode, type); 512 + } else { 513 + const struct cred *old_cred; 514 + 515 + old_cred = ovl_override_creds(inode->i_sb); 516 + acl = get_acl(realinode, type); 517 + revert_creds(old_cred); 518 + } 519 + /* 520 + * If there are no POSIX ACLs, or we encountered an error, 521 + * or the layer isn't idmapped we don't need to do anything. 522 + */ 523 + if (!is_idmapped_mnt(realpath.mnt) || IS_ERR_OR_NULL(acl)) 524 + return acl; 525 + 526 + /* 527 + * We only get here if the layer is idmapped. So drop out of RCU path 528 + * walk so we can clone the ACLs. There's no need to release the ACLs 529 + * since get_cached_acl_rcu() doesn't take a reference on the ACLs. 530 + */ 466 531 if (rcu) 467 - return get_cached_acl_rcu(realinode, type); 532 + return ERR_PTR(-ECHILD); 468 533 469 - old_cred = ovl_override_creds(inode->i_sb); 470 - acl = get_acl(realinode, type); 471 - revert_creds(old_cred); 472 - 473 - return acl; 534 + clone = posix_acl_clone(acl, GFP_KERNEL); 535 + if (!clone) 536 + clone = ERR_PTR(-ENOMEM); 537 + else 538 + ovl_idmap_posix_acl(mnt_user_ns(realpath.mnt), clone); 539 + /* 540 + * Since we're not in RCU path walk we always need to release the 541 + * original ACLs. 542 + */ 543 + posix_acl_release(acl); 544 + return clone; 474 545 } 475 546 476 547 int ovl_update_time(struct inode *inode, struct timespec64 *ts, int flags)
+2 -1
fs/overlayfs/overlayfs.h
··· 249 249 const char *name, const void *value, 250 250 size_t size, int flags) 251 251 { 252 - int err = vfs_setxattr(ovl_upper_mnt_userns(ofs), dentry, name, value, size, flags); 252 + int err = vfs_setxattr(ovl_upper_mnt_userns(ofs), dentry, name, 253 + (void *)value, size, flags); 253 254 254 255 pr_debug("setxattr(%pd2, \"%s\", \"%*pE\", %zu, %d) = %i\n", 255 256 dentry, name, min((int)size, 48), value, size, flags, err);
+1 -24
fs/overlayfs/super.c
··· 1003 1003 struct dentry *dentry, struct inode *inode, 1004 1004 const char *name, void *buffer, size_t size) 1005 1005 { 1006 - if (!IS_POSIXACL(inode)) 1007 - return -EOPNOTSUPP; 1008 - 1009 1006 return ovl_xattr_get(dentry, inode, handler->name, buffer, size); 1010 1007 } 1011 1008 ··· 1017 1020 struct inode *realinode = ovl_inode_real(inode); 1018 1021 struct posix_acl *acl = NULL; 1019 1022 int err; 1020 - 1021 - if (!IS_POSIXACL(inode)) 1022 - return -EOPNOTSUPP; 1023 1023 1024 1024 /* Check that everything is OK before copy-up */ 1025 1025 if (value) { ··· 1960 1966 return root; 1961 1967 } 1962 1968 1963 - static bool ovl_has_idmapped_layers(struct ovl_fs *ofs) 1964 - { 1965 - 1966 - unsigned int i; 1967 - const struct vfsmount *mnt; 1968 - 1969 - for (i = 0; i < ofs->numlayer; i++) { 1970 - mnt = ofs->layers[i].mnt; 1971 - if (mnt && is_idmapped_mnt(mnt)) 1972 - return true; 1973 - } 1974 - return false; 1975 - } 1976 - 1977 1969 static int ovl_fill_super(struct super_block *sb, void *data, int silent) 1978 1970 { 1979 1971 struct path upperpath = { }; ··· 2129 2149 sb->s_xattr = ofs->config.userxattr ? ovl_user_xattr_handlers : 2130 2150 ovl_trusted_xattr_handlers; 2131 2151 sb->s_fs_info = ofs; 2132 - if (ovl_has_idmapped_layers(ofs)) 2133 - pr_warn("POSIX ACLs are not yet supported with idmapped layers, mounting without ACL support.\n"); 2134 - else 2135 - sb->s_flags |= SB_POSIXACL; 2152 + sb->s_flags |= SB_POSIXACL; 2136 2153 sb->s_iflags |= SB_I_SKIP_SYNC; 2137 2154 2138 2155 err = -ENOMEM;
+120 -54
fs/posix_acl.c
··· 199 199 /* 200 200 * Clone an ACL. 201 201 */ 202 - static struct posix_acl * 202 + struct posix_acl * 203 203 posix_acl_clone(const struct posix_acl *acl, gfp_t flags) 204 204 { 205 205 struct posix_acl *clone = NULL; ··· 213 213 } 214 214 return clone; 215 215 } 216 + EXPORT_SYMBOL_GPL(posix_acl_clone); 216 217 217 218 /* 218 219 * Check if an acl is valid. Returns 0 if it is, or -E... otherwise. ··· 362 361 { 363 362 const struct posix_acl_entry *pa, *pe, *mask_obj; 364 363 int found = 0; 365 - kuid_t uid; 366 - kgid_t gid; 364 + vfsuid_t vfsuid; 365 + vfsgid_t vfsgid; 367 366 368 367 want &= MAY_READ | MAY_WRITE | MAY_EXEC; 369 368 ··· 371 370 switch(pa->e_tag) { 372 371 case ACL_USER_OBJ: 373 372 /* (May have been checked already) */ 374 - uid = i_uid_into_mnt(mnt_userns, inode); 375 - if (uid_eq(uid, current_fsuid())) 373 + vfsuid = i_uid_into_vfsuid(mnt_userns, inode); 374 + if (vfsuid_eq_kuid(vfsuid, current_fsuid())) 376 375 goto check_perm; 377 376 break; 378 377 case ACL_USER: 379 - uid = mapped_kuid_fs(mnt_userns, 380 - i_user_ns(inode), 378 + vfsuid = make_vfsuid(mnt_userns, &init_user_ns, 381 379 pa->e_uid); 382 - if (uid_eq(uid, current_fsuid())) 380 + if (vfsuid_eq_kuid(vfsuid, current_fsuid())) 383 381 goto mask; 384 382 break; 385 383 case ACL_GROUP_OBJ: 386 - gid = i_gid_into_mnt(mnt_userns, inode); 387 - if (in_group_p(gid)) { 384 + vfsgid = i_gid_into_vfsgid(mnt_userns, inode); 385 + if (vfsgid_in_group_p(vfsgid)) { 388 386 found = 1; 389 387 if ((pa->e_perm & want) == want) 390 388 goto mask; 391 389 } 392 390 break; 393 391 case ACL_GROUP: 394 - gid = mapped_kgid_fs(mnt_userns, 395 - i_user_ns(inode), 392 + vfsgid = make_vfsgid(mnt_userns, &init_user_ns, 396 393 pa->e_gid); 397 - if (in_group_p(gid)) { 394 + if (vfsgid_in_group_p(vfsgid)) { 398 395 found = 1; 399 396 if ((pa->e_perm & want) == want) 400 397 goto mask; ··· 698 699 return error; 699 700 if (error == 0) 700 701 *acl = NULL; 701 - if (!in_group_p(i_gid_into_mnt(mnt_userns, inode)) && 702 + if (!vfsgid_in_group_p(i_gid_into_vfsgid(mnt_userns, inode)) && 702 703 !capable_wrt_inode_uidgid(mnt_userns, inode, CAP_FSETID)) 703 704 mode &= ~S_ISGID; 704 705 *mode_p = mode; ··· 709 710 /* 710 711 * Fix up the uids and gids in posix acl extended attributes in place. 711 712 */ 713 + static int posix_acl_fix_xattr_common(void *value, size_t size) 714 + { 715 + struct posix_acl_xattr_header *header = value; 716 + int count; 717 + 718 + if (!header) 719 + return -EINVAL; 720 + if (size < sizeof(struct posix_acl_xattr_header)) 721 + return -EINVAL; 722 + if (header->a_version != cpu_to_le32(POSIX_ACL_XATTR_VERSION)) 723 + return -EINVAL; 724 + 725 + count = posix_acl_xattr_count(size); 726 + if (count < 0) 727 + return -EINVAL; 728 + if (count == 0) 729 + return -EINVAL; 730 + 731 + return count; 732 + } 733 + 734 + void posix_acl_getxattr_idmapped_mnt(struct user_namespace *mnt_userns, 735 + const struct inode *inode, 736 + void *value, size_t size) 737 + { 738 + struct posix_acl_xattr_header *header = value; 739 + struct posix_acl_xattr_entry *entry = (void *)(header + 1), *end; 740 + int count; 741 + vfsuid_t vfsuid; 742 + vfsgid_t vfsgid; 743 + kuid_t uid; 744 + kgid_t gid; 745 + 746 + if (no_idmapping(mnt_userns, i_user_ns(inode))) 747 + return; 748 + 749 + count = posix_acl_fix_xattr_common(value, size); 750 + if (count < 0) 751 + return; 752 + 753 + for (end = entry + count; entry != end; entry++) { 754 + switch (le16_to_cpu(entry->e_tag)) { 755 + case ACL_USER: 756 + uid = make_kuid(&init_user_ns, le32_to_cpu(entry->e_id)); 757 + vfsuid = make_vfsuid(mnt_userns, &init_user_ns, uid); 758 + entry->e_id = cpu_to_le32(from_kuid(&init_user_ns, 759 + vfsuid_into_kuid(vfsuid))); 760 + break; 761 + case ACL_GROUP: 762 + gid = make_kgid(&init_user_ns, le32_to_cpu(entry->e_id)); 763 + vfsgid = make_vfsgid(mnt_userns, &init_user_ns, gid); 764 + entry->e_id = cpu_to_le32(from_kgid(&init_user_ns, 765 + vfsgid_into_kgid(vfsgid))); 766 + break; 767 + default: 768 + break; 769 + } 770 + } 771 + } 772 + 773 + void posix_acl_setxattr_idmapped_mnt(struct user_namespace *mnt_userns, 774 + const struct inode *inode, 775 + void *value, size_t size) 776 + { 777 + struct posix_acl_xattr_header *header = value; 778 + struct posix_acl_xattr_entry *entry = (void *)(header + 1), *end; 779 + int count; 780 + vfsuid_t vfsuid; 781 + vfsgid_t vfsgid; 782 + kuid_t uid; 783 + kgid_t gid; 784 + 785 + if (no_idmapping(mnt_userns, i_user_ns(inode))) 786 + return; 787 + 788 + count = posix_acl_fix_xattr_common(value, size); 789 + if (count < 0) 790 + return; 791 + 792 + for (end = entry + count; entry != end; entry++) { 793 + switch (le16_to_cpu(entry->e_tag)) { 794 + case ACL_USER: 795 + uid = make_kuid(&init_user_ns, le32_to_cpu(entry->e_id)); 796 + vfsuid = VFSUIDT_INIT(uid); 797 + uid = from_vfsuid(mnt_userns, &init_user_ns, vfsuid); 798 + entry->e_id = cpu_to_le32(from_kuid(&init_user_ns, uid)); 799 + break; 800 + case ACL_GROUP: 801 + gid = make_kgid(&init_user_ns, le32_to_cpu(entry->e_id)); 802 + vfsgid = VFSGIDT_INIT(gid); 803 + gid = from_vfsgid(mnt_userns, &init_user_ns, vfsgid); 804 + entry->e_id = cpu_to_le32(from_kgid(&init_user_ns, gid)); 805 + break; 806 + default: 807 + break; 808 + } 809 + } 810 + } 811 + 712 812 static void posix_acl_fix_xattr_userns( 713 813 struct user_namespace *to, struct user_namespace *from, 714 - struct user_namespace *mnt_userns, 715 - void *value, size_t size, bool from_user) 814 + void *value, size_t size) 716 815 { 717 816 struct posix_acl_xattr_header *header = value; 718 817 struct posix_acl_xattr_entry *entry = (void *)(header + 1), *end; ··· 818 721 kuid_t uid; 819 722 kgid_t gid; 820 723 821 - if (!value) 822 - return; 823 - if (size < sizeof(struct posix_acl_xattr_header)) 824 - return; 825 - if (header->a_version != cpu_to_le32(POSIX_ACL_XATTR_VERSION)) 826 - return; 827 - 828 - count = posix_acl_xattr_count(size); 724 + count = posix_acl_fix_xattr_common(value, size); 829 725 if (count < 0) 830 - return; 831 - if (count == 0) 832 726 return; 833 727 834 728 for (end = entry + count; entry != end; entry++) { 835 729 switch(le16_to_cpu(entry->e_tag)) { 836 730 case ACL_USER: 837 731 uid = make_kuid(from, le32_to_cpu(entry->e_id)); 838 - if (from_user) 839 - uid = mapped_kuid_user(mnt_userns, &init_user_ns, uid); 840 - else 841 - uid = mapped_kuid_fs(mnt_userns, &init_user_ns, uid); 842 732 entry->e_id = cpu_to_le32(from_kuid(to, uid)); 843 733 break; 844 734 case ACL_GROUP: 845 735 gid = make_kgid(from, le32_to_cpu(entry->e_id)); 846 - if (from_user) 847 - gid = mapped_kgid_user(mnt_userns, &init_user_ns, gid); 848 - else 849 - gid = mapped_kgid_fs(mnt_userns, &init_user_ns, gid); 850 736 entry->e_id = cpu_to_le32(from_kgid(to, gid)); 851 737 break; 852 738 default: ··· 838 758 } 839 759 } 840 760 841 - void posix_acl_fix_xattr_from_user(struct user_namespace *mnt_userns, 842 - struct inode *inode, 843 - void *value, size_t size) 761 + void posix_acl_fix_xattr_from_user(void *value, size_t size) 844 762 { 845 763 struct user_namespace *user_ns = current_user_ns(); 846 - 847 - /* Leave ids untouched on non-idmapped mounts. */ 848 - if (no_idmapping(mnt_userns, i_user_ns(inode))) 849 - mnt_userns = &init_user_ns; 850 - if ((user_ns == &init_user_ns) && (mnt_userns == &init_user_ns)) 764 + if (user_ns == &init_user_ns) 851 765 return; 852 - posix_acl_fix_xattr_userns(&init_user_ns, user_ns, mnt_userns, value, 853 - size, true); 766 + posix_acl_fix_xattr_userns(&init_user_ns, user_ns, value, size); 854 767 } 855 768 856 - void posix_acl_fix_xattr_to_user(struct user_namespace *mnt_userns, 857 - struct inode *inode, 858 - void *value, size_t size) 769 + void posix_acl_fix_xattr_to_user(void *value, size_t size) 859 770 { 860 771 struct user_namespace *user_ns = current_user_ns(); 861 - 862 - /* Leave ids untouched on non-idmapped mounts. */ 863 - if (no_idmapping(mnt_userns, i_user_ns(inode))) 864 - mnt_userns = &init_user_ns; 865 - if ((user_ns == &init_user_ns) && (mnt_userns == &init_user_ns)) 772 + if (user_ns == &init_user_ns) 866 773 return; 867 - posix_acl_fix_xattr_userns(user_ns, &init_user_ns, mnt_userns, value, 868 - size, false); 774 + posix_acl_fix_xattr_userns(user_ns, &init_user_ns, value, size); 869 775 } 870 776 871 777 /*
+18 -7
fs/xattr.c
··· 282 282 } 283 283 EXPORT_SYMBOL_GPL(__vfs_setxattr_locked); 284 284 285 + static inline bool is_posix_acl_xattr(const char *name) 286 + { 287 + return (strcmp(name, XATTR_NAME_POSIX_ACL_ACCESS) == 0) || 288 + (strcmp(name, XATTR_NAME_POSIX_ACL_DEFAULT) == 0); 289 + } 290 + 285 291 int 286 292 vfs_setxattr(struct user_namespace *mnt_userns, struct dentry *dentry, 287 - const char *name, const void *value, size_t size, int flags) 293 + const char *name, void *value, size_t size, int flags) 288 294 { 289 295 struct inode *inode = dentry->d_inode; 290 296 struct inode *delegated_inode = NULL; ··· 298 292 int error; 299 293 300 294 if (size && strcmp(name, XATTR_NAME_CAPS) == 0) { 301 - error = cap_convert_nscap(mnt_userns, dentry, &value, size); 295 + error = cap_convert_nscap(mnt_userns, dentry, 296 + (const void **)&value, size); 302 297 if (error < 0) 303 298 return error; 304 299 size = error; 305 300 } 301 + 302 + if (size && is_posix_acl_xattr(name)) 303 + posix_acl_setxattr_idmapped_mnt(mnt_userns, inode, value, size); 306 304 307 305 retry_deleg: 308 306 inode_lock(inode); ··· 441 431 return ret; 442 432 } 443 433 nolsm: 444 - return __vfs_getxattr(dentry, inode, name, value, size); 434 + error = __vfs_getxattr(dentry, inode, name, value, size); 435 + if (error > 0 && is_posix_acl_xattr(name)) 436 + posix_acl_getxattr_idmapped_mnt(mnt_userns, inode, value, size); 437 + return error; 445 438 } 446 439 EXPORT_SYMBOL_GPL(vfs_getxattr); 447 440 ··· 590 577 if (ctx->size && 591 578 ((strcmp(ctx->kname->name, XATTR_NAME_POSIX_ACL_ACCESS) == 0) || 592 579 (strcmp(ctx->kname->name, XATTR_NAME_POSIX_ACL_DEFAULT) == 0))) 593 - posix_acl_fix_xattr_from_user(mnt_userns, d_inode(d), 594 - ctx->kvalue, ctx->size); 580 + posix_acl_fix_xattr_from_user(ctx->kvalue, ctx->size); 595 581 } 596 582 597 583 int do_setxattr(struct user_namespace *mnt_userns, struct dentry *dentry, ··· 707 695 if (error > 0) { 708 696 if ((strcmp(kname, XATTR_NAME_POSIX_ACL_ACCESS) == 0) || 709 697 (strcmp(kname, XATTR_NAME_POSIX_ACL_DEFAULT) == 0)) 710 - posix_acl_fix_xattr_to_user(mnt_userns, d_inode(d), 711 - ctx->kvalue, error); 698 + posix_acl_fix_xattr_to_user(ctx->kvalue, error); 712 699 if (ctx->size && copy_to_user(ctx->value, ctx->kvalue, error)) 713 700 error = -EFAULT; 714 701 } else if (error == -ERANGE && ctx->size >= XATTR_SIZE_MAX) {
+26
include/linux/mnt_idmapping.h
··· 334 334 } 335 335 336 336 /** 337 + * vfsuid_into_kuid - convert vfsuid into kuid 338 + * @vfsuid: the vfsuid to convert 339 + * 340 + * This can be used when a vfsuid is committed as a kuid. 341 + * 342 + * Return: a kuid with the value of @vfsuid 343 + */ 344 + static inline kuid_t vfsuid_into_kuid(vfsuid_t vfsuid) 345 + { 346 + return AS_KUIDT(vfsuid); 347 + } 348 + 349 + /** 337 350 * from_vfsgid - map a vfsgid into the filesystem idmapping 338 351 * @mnt_userns: the mount's idmapping 339 352 * @fs_userns: the filesystem's idmapping ··· 417 404 vfsgid_t vfsgid) 418 405 { 419 406 return gid_valid(from_vfsgid(mnt_userns, fs_userns, vfsgid)); 407 + } 408 + 409 + /** 410 + * vfsgid_into_kgid - convert vfsgid into kgid 411 + * @vfsgid: the vfsgid to convert 412 + * 413 + * This can be used when a vfsgid is committed as a kgid. 414 + * 415 + * Return: a kgid with the value of @vfsgid 416 + */ 417 + static inline kgid_t vfsgid_into_kgid(vfsgid_t vfsgid) 418 + { 419 + return AS_KGIDT(vfsgid); 420 420 } 421 421 422 422 /**
+1
include/linux/posix_acl.h
··· 73 73 struct posix_acl *); 74 74 75 75 struct posix_acl *get_cached_acl_rcu(struct inode *inode, int type); 76 + struct posix_acl *posix_acl_clone(const struct posix_acl *acl, gfp_t flags); 76 77 77 78 #ifdef CONFIG_FS_POSIX_ACL 78 79 int posix_acl_chmod(struct user_namespace *, struct inode *, umode_t);
+22 -12
include/linux/posix_acl_xattr.h
··· 33 33 } 34 34 35 35 #ifdef CONFIG_FS_POSIX_ACL 36 - void posix_acl_fix_xattr_from_user(struct user_namespace *mnt_userns, 37 - struct inode *inode, 38 - void *value, size_t size); 39 - void posix_acl_fix_xattr_to_user(struct user_namespace *mnt_userns, 40 - struct inode *inode, 41 - void *value, size_t size); 36 + void posix_acl_fix_xattr_from_user(void *value, size_t size); 37 + void posix_acl_fix_xattr_to_user(void *value, size_t size); 38 + void posix_acl_getxattr_idmapped_mnt(struct user_namespace *mnt_userns, 39 + const struct inode *inode, 40 + void *value, size_t size); 41 + void posix_acl_setxattr_idmapped_mnt(struct user_namespace *mnt_userns, 42 + const struct inode *inode, 43 + void *value, size_t size); 42 44 #else 43 - static inline void posix_acl_fix_xattr_from_user(struct user_namespace *mnt_userns, 44 - struct inode *inode, 45 - void *value, size_t size) 45 + static inline void posix_acl_fix_xattr_from_user(void *value, size_t size) 46 46 { 47 47 } 48 - static inline void posix_acl_fix_xattr_to_user(struct user_namespace *mnt_userns, 49 - struct inode *inode, 50 - void *value, size_t size) 48 + static inline void posix_acl_fix_xattr_to_user(void *value, size_t size) 49 + { 50 + } 51 + static inline void 52 + posix_acl_getxattr_idmapped_mnt(struct user_namespace *mnt_userns, 53 + const struct inode *inode, void *value, 54 + size_t size) 55 + { 56 + } 57 + static inline void 58 + posix_acl_setxattr_idmapped_mnt(struct user_namespace *mnt_userns, 59 + const struct inode *inode, void *value, 60 + size_t size) 51 61 { 52 62 } 53 63 #endif
+1 -1
include/linux/xattr.h
··· 61 61 const char *, const void *, size_t, int, 62 62 struct inode **); 63 63 int vfs_setxattr(struct user_namespace *, struct dentry *, const char *, 64 - const void *, size_t, int); 64 + void *, size_t, int); 65 65 int __vfs_removexattr(struct user_namespace *, struct dentry *, const char *); 66 66 int __vfs_removexattr_locked(struct user_namespace *, struct dentry *, 67 67 const char *, struct inode **);