posix_acl.c (97acb6a8fcc4e5c2cdc2693a35acdc5a7461aaa3) | posix_acl.c (36f05cab0a2c97bda288c3b6a557ec5fb8d9bba6) |
---|---|
1// SPDX-License-Identifier: GPL-2.0-only 2/* 3 * Copyright (C) 2002,2003 by Andreas Gruenbacher <a.gruenbacher@computer.org> 4 * 5 * Fixes from William Schumacher incorporated on 15 March 2001. 6 * (Reported by Charles Bertsch, <CBertsch@microtest.com>). 7 */ 8 --- 10 unchanged lines hidden (view full) --- 19#include <linux/cred.h> 20#include <linux/posix_acl.h> 21#include <linux/posix_acl_xattr.h> 22#include <linux/xattr.h> 23#include <linux/export.h> 24#include <linux/user_namespace.h> 25#include <linux/namei.h> 26#include <linux/mnt_idmapping.h> | 1// SPDX-License-Identifier: GPL-2.0-only 2/* 3 * Copyright (C) 2002,2003 by Andreas Gruenbacher <a.gruenbacher@computer.org> 4 * 5 * Fixes from William Schumacher incorporated on 15 March 2001. 6 * (Reported by Charles Bertsch, <CBertsch@microtest.com>). 7 */ 8 --- 10 unchanged lines hidden (view full) --- 19#include <linux/cred.h> 20#include <linux/posix_acl.h> 21#include <linux/posix_acl_xattr.h> 22#include <linux/xattr.h> 23#include <linux/export.h> 24#include <linux/user_namespace.h> 25#include <linux/namei.h> 26#include <linux/mnt_idmapping.h> |
27#include <linux/iversion.h> |
|
27 28static struct posix_acl **acl_by_type(struct inode *inode, int type) 29{ 30 switch (type) { 31 case ACL_TYPE_ACCESS: 32 return &inode->i_acl; 33 case ACL_TYPE_DEFAULT: 34 return &inode->i_default_acl; --- 321 unchanged lines hidden (view full) --- 356 * Return 0 if current is granted want access to the inode 357 * by the acl. Returns -E... otherwise. 358 */ 359int 360posix_acl_permission(struct user_namespace *mnt_userns, struct inode *inode, 361 const struct posix_acl *acl, int want) 362{ 363 const struct posix_acl_entry *pa, *pe, *mask_obj; | 28 29static struct posix_acl **acl_by_type(struct inode *inode, int type) 30{ 31 switch (type) { 32 case ACL_TYPE_ACCESS: 33 return &inode->i_acl; 34 case ACL_TYPE_DEFAULT: 35 return &inode->i_default_acl; --- 321 unchanged lines hidden (view full) --- 357 * Return 0 if current is granted want access to the inode 358 * by the acl. Returns -E... otherwise. 359 */ 360int 361posix_acl_permission(struct user_namespace *mnt_userns, struct inode *inode, 362 const struct posix_acl *acl, int want) 363{ 364 const struct posix_acl_entry *pa, *pe, *mask_obj; |
365 struct user_namespace *fs_userns = i_user_ns(inode); |
|
364 int found = 0; 365 vfsuid_t vfsuid; 366 vfsgid_t vfsgid; 367 368 want &= MAY_READ | MAY_WRITE | MAY_EXEC; 369 370 FOREACH_ACL_ENTRY(pa, acl, pe) { 371 switch(pa->e_tag) { 372 case ACL_USER_OBJ: 373 /* (May have been checked already) */ 374 vfsuid = i_uid_into_vfsuid(mnt_userns, inode); 375 if (vfsuid_eq_kuid(vfsuid, current_fsuid())) 376 goto check_perm; 377 break; 378 case ACL_USER: | 366 int found = 0; 367 vfsuid_t vfsuid; 368 vfsgid_t vfsgid; 369 370 want &= MAY_READ | MAY_WRITE | MAY_EXEC; 371 372 FOREACH_ACL_ENTRY(pa, acl, pe) { 373 switch(pa->e_tag) { 374 case ACL_USER_OBJ: 375 /* (May have been checked already) */ 376 vfsuid = i_uid_into_vfsuid(mnt_userns, inode); 377 if (vfsuid_eq_kuid(vfsuid, current_fsuid())) 378 goto check_perm; 379 break; 380 case ACL_USER: |
379 vfsuid = make_vfsuid(mnt_userns, &init_user_ns, | 381 vfsuid = make_vfsuid(mnt_userns, fs_userns, |
380 pa->e_uid); 381 if (vfsuid_eq_kuid(vfsuid, current_fsuid())) 382 goto mask; 383 break; 384 case ACL_GROUP_OBJ: 385 vfsgid = i_gid_into_vfsgid(mnt_userns, inode); 386 if (vfsgid_in_group_p(vfsgid)) { 387 found = 1; 388 if ((pa->e_perm & want) == want) 389 goto mask; 390 } 391 break; 392 case ACL_GROUP: | 382 pa->e_uid); 383 if (vfsuid_eq_kuid(vfsuid, current_fsuid())) 384 goto mask; 385 break; 386 case ACL_GROUP_OBJ: 387 vfsgid = i_gid_into_vfsgid(mnt_userns, inode); 388 if (vfsgid_in_group_p(vfsgid)) { 389 found = 1; 390 if ((pa->e_perm & want) == want) 391 goto mask; 392 } 393 break; 394 case ACL_GROUP: |
393 vfsgid = make_vfsgid(mnt_userns, &init_user_ns, | 395 vfsgid = make_vfsgid(mnt_userns, fs_userns, |
394 pa->e_gid); 395 if (vfsgid_in_group_p(vfsgid)) { 396 found = 1; 397 if ((pa->e_perm & want) == want) 398 goto mask; 399 } 400 break; 401 case ACL_MASK: --- 329 unchanged lines hidden (view full) --- 731} 732 733void posix_acl_getxattr_idmapped_mnt(struct user_namespace *mnt_userns, 734 const struct inode *inode, 735 void *value, size_t size) 736{ 737 struct posix_acl_xattr_header *header = value; 738 struct posix_acl_xattr_entry *entry = (void *)(header + 1), *end; | 396 pa->e_gid); 397 if (vfsgid_in_group_p(vfsgid)) { 398 found = 1; 399 if ((pa->e_perm & want) == want) 400 goto mask; 401 } 402 break; 403 case ACL_MASK: --- 329 unchanged lines hidden (view full) --- 733} 734 735void posix_acl_getxattr_idmapped_mnt(struct user_namespace *mnt_userns, 736 const struct inode *inode, 737 void *value, size_t size) 738{ 739 struct posix_acl_xattr_header *header = value; 740 struct posix_acl_xattr_entry *entry = (void *)(header + 1), *end; |
741 struct user_namespace *fs_userns = i_user_ns(inode); |
|
739 int count; 740 vfsuid_t vfsuid; 741 vfsgid_t vfsgid; 742 kuid_t uid; 743 kgid_t gid; 744 745 if (no_idmapping(mnt_userns, i_user_ns(inode))) 746 return; 747 748 count = posix_acl_fix_xattr_common(value, size); 749 if (count < 0) 750 return; 751 752 for (end = entry + count; entry != end; entry++) { 753 switch (le16_to_cpu(entry->e_tag)) { 754 case ACL_USER: 755 uid = make_kuid(&init_user_ns, le32_to_cpu(entry->e_id)); | 742 int count; 743 vfsuid_t vfsuid; 744 vfsgid_t vfsgid; 745 kuid_t uid; 746 kgid_t gid; 747 748 if (no_idmapping(mnt_userns, i_user_ns(inode))) 749 return; 750 751 count = posix_acl_fix_xattr_common(value, size); 752 if (count < 0) 753 return; 754 755 for (end = entry + count; entry != end; entry++) { 756 switch (le16_to_cpu(entry->e_tag)) { 757 case ACL_USER: 758 uid = make_kuid(&init_user_ns, le32_to_cpu(entry->e_id)); |
756 vfsuid = make_vfsuid(mnt_userns, &init_user_ns, uid); | 759 vfsuid = make_vfsuid(mnt_userns, fs_userns, uid); |
757 entry->e_id = cpu_to_le32(from_kuid(&init_user_ns, 758 vfsuid_into_kuid(vfsuid))); 759 break; 760 case ACL_GROUP: 761 gid = make_kgid(&init_user_ns, le32_to_cpu(entry->e_id)); | 760 entry->e_id = cpu_to_le32(from_kuid(&init_user_ns, 761 vfsuid_into_kuid(vfsuid))); 762 break; 763 case ACL_GROUP: 764 gid = make_kgid(&init_user_ns, le32_to_cpu(entry->e_id)); |
762 vfsgid = make_vfsgid(mnt_userns, &init_user_ns, gid); | 765 vfsgid = make_vfsgid(mnt_userns, fs_userns, gid); |
763 entry->e_id = cpu_to_le32(from_kgid(&init_user_ns, 764 vfsgid_into_kgid(vfsgid))); 765 break; 766 default: 767 break; 768 } 769 } 770} 771 772void posix_acl_setxattr_idmapped_mnt(struct user_namespace *mnt_userns, 773 const struct inode *inode, 774 void *value, size_t size) 775{ 776 struct posix_acl_xattr_header *header = value; 777 struct posix_acl_xattr_entry *entry = (void *)(header + 1), *end; | 766 entry->e_id = cpu_to_le32(from_kgid(&init_user_ns, 767 vfsgid_into_kgid(vfsgid))); 768 break; 769 default: 770 break; 771 } 772 } 773} 774 775void posix_acl_setxattr_idmapped_mnt(struct user_namespace *mnt_userns, 776 const struct inode *inode, 777 void *value, size_t size) 778{ 779 struct posix_acl_xattr_header *header = value; 780 struct posix_acl_xattr_entry *entry = (void *)(header + 1), *end; |
781 struct user_namespace *fs_userns = i_user_ns(inode); |
|
778 int count; 779 vfsuid_t vfsuid; 780 vfsgid_t vfsgid; 781 kuid_t uid; 782 kgid_t gid; 783 784 if (no_idmapping(mnt_userns, i_user_ns(inode))) 785 return; 786 787 count = posix_acl_fix_xattr_common(value, size); 788 if (count < 0) 789 return; 790 791 for (end = entry + count; entry != end; entry++) { 792 switch (le16_to_cpu(entry->e_tag)) { 793 case ACL_USER: 794 uid = make_kuid(&init_user_ns, le32_to_cpu(entry->e_id)); 795 vfsuid = VFSUIDT_INIT(uid); | 782 int count; 783 vfsuid_t vfsuid; 784 vfsgid_t vfsgid; 785 kuid_t uid; 786 kgid_t gid; 787 788 if (no_idmapping(mnt_userns, i_user_ns(inode))) 789 return; 790 791 count = posix_acl_fix_xattr_common(value, size); 792 if (count < 0) 793 return; 794 795 for (end = entry + count; entry != end; entry++) { 796 switch (le16_to_cpu(entry->e_tag)) { 797 case ACL_USER: 798 uid = make_kuid(&init_user_ns, le32_to_cpu(entry->e_id)); 799 vfsuid = VFSUIDT_INIT(uid); |
796 uid = from_vfsuid(mnt_userns, &init_user_ns, vfsuid); | 800 uid = from_vfsuid(mnt_userns, fs_userns, vfsuid); |
797 entry->e_id = cpu_to_le32(from_kuid(&init_user_ns, uid)); 798 break; 799 case ACL_GROUP: 800 gid = make_kgid(&init_user_ns, le32_to_cpu(entry->e_id)); 801 vfsgid = VFSGIDT_INIT(gid); | 801 entry->e_id = cpu_to_le32(from_kuid(&init_user_ns, uid)); 802 break; 803 case ACL_GROUP: 804 gid = make_kgid(&init_user_ns, le32_to_cpu(entry->e_id)); 805 vfsgid = VFSGIDT_INIT(gid); |
802 gid = from_vfsgid(mnt_userns, &init_user_ns, vfsgid); | 806 gid = from_vfsgid(mnt_userns, fs_userns, vfsgid); |
803 entry->e_id = cpu_to_le32(from_kgid(&init_user_ns, gid)); 804 break; 805 default: 806 break; 807 } 808 } 809} 810 --- 254 unchanged lines hidden (view full) --- 1065 if (type == ACL_TYPE_ACCESS) { 1066 error = posix_acl_update_mode(mnt_userns, inode, 1067 &inode->i_mode, &acl); 1068 if (error) 1069 return error; 1070 } 1071 1072 inode->i_ctime = current_time(inode); | 807 entry->e_id = cpu_to_le32(from_kgid(&init_user_ns, gid)); 808 break; 809 default: 810 break; 811 } 812 } 813} 814 --- 254 unchanged lines hidden (view full) --- 1069 if (type == ACL_TYPE_ACCESS) { 1070 error = posix_acl_update_mode(mnt_userns, inode, 1071 &inode->i_mode, &acl); 1072 if (error) 1073 return error; 1074 } 1075 1076 inode->i_ctime = current_time(inode); |
1077 if (IS_I_VERSION(inode)) 1078 inode_inc_iversion(inode); |
|
1073 set_cached_acl(inode, type, acl); 1074 return 0; 1075} 1076 1077int simple_acl_create(struct inode *dir, struct inode *inode) 1078{ 1079 struct posix_acl *default_acl, *acl; 1080 int error; --- 14 unchanged lines hidden --- | 1079 set_cached_acl(inode, type, acl); 1080 return 0; 1081} 1082 1083int simple_acl_create(struct inode *dir, struct inode *inode) 1084{ 1085 struct posix_acl *default_acl, *acl; 1086 int error; --- 14 unchanged lines hidden --- |