0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014 #include <linux/kernel.h>
0015 #include <linux/slab.h>
0016 #include <linux/atomic.h>
0017 #include <linux/fs.h>
0018 #include <linux/sched.h>
0019 #include <linux/cred.h>
0020 #include <linux/posix_acl.h>
0021 #include <linux/posix_acl_xattr.h>
0022 #include <linux/xattr.h>
0023 #include <linux/export.h>
0024 #include <linux/user_namespace.h>
0025 #include <linux/namei.h>
0026 #include <linux/mnt_idmapping.h>
0027
0028 static struct posix_acl **acl_by_type(struct inode *inode, int type)
0029 {
0030 switch (type) {
0031 case ACL_TYPE_ACCESS:
0032 return &inode->i_acl;
0033 case ACL_TYPE_DEFAULT:
0034 return &inode->i_default_acl;
0035 default:
0036 BUG();
0037 }
0038 }
0039
0040 struct posix_acl *get_cached_acl(struct inode *inode, int type)
0041 {
0042 struct posix_acl **p = acl_by_type(inode, type);
0043 struct posix_acl *acl;
0044
0045 for (;;) {
0046 rcu_read_lock();
0047 acl = rcu_dereference(*p);
0048 if (!acl || is_uncached_acl(acl) ||
0049 refcount_inc_not_zero(&acl->a_refcount))
0050 break;
0051 rcu_read_unlock();
0052 cpu_relax();
0053 }
0054 rcu_read_unlock();
0055 return acl;
0056 }
0057 EXPORT_SYMBOL(get_cached_acl);
0058
0059 struct posix_acl *get_cached_acl_rcu(struct inode *inode, int type)
0060 {
0061 struct posix_acl *acl = rcu_dereference(*acl_by_type(inode, type));
0062
0063 if (acl == ACL_DONT_CACHE) {
0064 struct posix_acl *ret;
0065
0066 ret = inode->i_op->get_acl(inode, type, LOOKUP_RCU);
0067 if (!IS_ERR(ret))
0068 acl = ret;
0069 }
0070
0071 return acl;
0072 }
0073 EXPORT_SYMBOL(get_cached_acl_rcu);
0074
0075 void set_cached_acl(struct inode *inode, int type, struct posix_acl *acl)
0076 {
0077 struct posix_acl **p = acl_by_type(inode, type);
0078 struct posix_acl *old;
0079
0080 old = xchg(p, posix_acl_dup(acl));
0081 if (!is_uncached_acl(old))
0082 posix_acl_release(old);
0083 }
0084 EXPORT_SYMBOL(set_cached_acl);
0085
0086 static void __forget_cached_acl(struct posix_acl **p)
0087 {
0088 struct posix_acl *old;
0089
0090 old = xchg(p, ACL_NOT_CACHED);
0091 if (!is_uncached_acl(old))
0092 posix_acl_release(old);
0093 }
0094
0095 void forget_cached_acl(struct inode *inode, int type)
0096 {
0097 __forget_cached_acl(acl_by_type(inode, type));
0098 }
0099 EXPORT_SYMBOL(forget_cached_acl);
0100
0101 void forget_all_cached_acls(struct inode *inode)
0102 {
0103 __forget_cached_acl(&inode->i_acl);
0104 __forget_cached_acl(&inode->i_default_acl);
0105 }
0106 EXPORT_SYMBOL(forget_all_cached_acls);
0107
0108 struct posix_acl *get_acl(struct inode *inode, int type)
0109 {
0110 void *sentinel;
0111 struct posix_acl **p;
0112 struct posix_acl *acl;
0113
0114
0115
0116
0117
0118
0119
0120 acl = get_cached_acl(inode, type);
0121 if (!is_uncached_acl(acl))
0122 return acl;
0123
0124 if (!IS_POSIXACL(inode))
0125 return NULL;
0126
0127 sentinel = uncached_acl_sentinel(current);
0128 p = acl_by_type(inode, type);
0129
0130
0131
0132
0133
0134
0135
0136
0137
0138 cmpxchg(p, ACL_NOT_CACHED, sentinel);
0139
0140
0141
0142
0143
0144
0145
0146
0147
0148 if (!inode->i_op->get_acl) {
0149 set_cached_acl(inode, type, NULL);
0150 return NULL;
0151 }
0152 acl = inode->i_op->get_acl(inode, type, false);
0153
0154 if (IS_ERR(acl)) {
0155
0156
0157
0158
0159 cmpxchg(p, sentinel, ACL_NOT_CACHED);
0160 return acl;
0161 }
0162
0163
0164
0165
0166 posix_acl_dup(acl);
0167 if (unlikely(cmpxchg(p, sentinel, acl) != sentinel))
0168 posix_acl_release(acl);
0169 return acl;
0170 }
0171 EXPORT_SYMBOL(get_acl);
0172
0173
0174
0175
0176 void
0177 posix_acl_init(struct posix_acl *acl, int count)
0178 {
0179 refcount_set(&acl->a_refcount, 1);
0180 acl->a_count = count;
0181 }
0182 EXPORT_SYMBOL(posix_acl_init);
0183
0184
0185
0186
0187 struct posix_acl *
0188 posix_acl_alloc(int count, gfp_t flags)
0189 {
0190 const size_t size = sizeof(struct posix_acl) +
0191 count * sizeof(struct posix_acl_entry);
0192 struct posix_acl *acl = kmalloc(size, flags);
0193 if (acl)
0194 posix_acl_init(acl, count);
0195 return acl;
0196 }
0197 EXPORT_SYMBOL(posix_acl_alloc);
0198
0199
0200
0201
0202 struct posix_acl *
0203 posix_acl_clone(const struct posix_acl *acl, gfp_t flags)
0204 {
0205 struct posix_acl *clone = NULL;
0206
0207 if (acl) {
0208 int size = sizeof(struct posix_acl) + acl->a_count *
0209 sizeof(struct posix_acl_entry);
0210 clone = kmemdup(acl, size, flags);
0211 if (clone)
0212 refcount_set(&clone->a_refcount, 1);
0213 }
0214 return clone;
0215 }
0216 EXPORT_SYMBOL_GPL(posix_acl_clone);
0217
0218
0219
0220
0221 int
0222 posix_acl_valid(struct user_namespace *user_ns, const struct posix_acl *acl)
0223 {
0224 const struct posix_acl_entry *pa, *pe;
0225 int state = ACL_USER_OBJ;
0226 int needs_mask = 0;
0227
0228 FOREACH_ACL_ENTRY(pa, acl, pe) {
0229 if (pa->e_perm & ~(ACL_READ|ACL_WRITE|ACL_EXECUTE))
0230 return -EINVAL;
0231 switch (pa->e_tag) {
0232 case ACL_USER_OBJ:
0233 if (state == ACL_USER_OBJ) {
0234 state = ACL_USER;
0235 break;
0236 }
0237 return -EINVAL;
0238
0239 case ACL_USER:
0240 if (state != ACL_USER)
0241 return -EINVAL;
0242 if (!kuid_has_mapping(user_ns, pa->e_uid))
0243 return -EINVAL;
0244 needs_mask = 1;
0245 break;
0246
0247 case ACL_GROUP_OBJ:
0248 if (state == ACL_USER) {
0249 state = ACL_GROUP;
0250 break;
0251 }
0252 return -EINVAL;
0253
0254 case ACL_GROUP:
0255 if (state != ACL_GROUP)
0256 return -EINVAL;
0257 if (!kgid_has_mapping(user_ns, pa->e_gid))
0258 return -EINVAL;
0259 needs_mask = 1;
0260 break;
0261
0262 case ACL_MASK:
0263 if (state != ACL_GROUP)
0264 return -EINVAL;
0265 state = ACL_OTHER;
0266 break;
0267
0268 case ACL_OTHER:
0269 if (state == ACL_OTHER ||
0270 (state == ACL_GROUP && !needs_mask)) {
0271 state = 0;
0272 break;
0273 }
0274 return -EINVAL;
0275
0276 default:
0277 return -EINVAL;
0278 }
0279 }
0280 if (state == 0)
0281 return 0;
0282 return -EINVAL;
0283 }
0284 EXPORT_SYMBOL(posix_acl_valid);
0285
0286
0287
0288
0289
0290 int
0291 posix_acl_equiv_mode(const struct posix_acl *acl, umode_t *mode_p)
0292 {
0293 const struct posix_acl_entry *pa, *pe;
0294 umode_t mode = 0;
0295 int not_equiv = 0;
0296
0297
0298
0299
0300 if (!acl)
0301 return 0;
0302
0303 FOREACH_ACL_ENTRY(pa, acl, pe) {
0304 switch (pa->e_tag) {
0305 case ACL_USER_OBJ:
0306 mode |= (pa->e_perm & S_IRWXO) << 6;
0307 break;
0308 case ACL_GROUP_OBJ:
0309 mode |= (pa->e_perm & S_IRWXO) << 3;
0310 break;
0311 case ACL_OTHER:
0312 mode |= pa->e_perm & S_IRWXO;
0313 break;
0314 case ACL_MASK:
0315 mode = (mode & ~S_IRWXG) |
0316 ((pa->e_perm & S_IRWXO) << 3);
0317 not_equiv = 1;
0318 break;
0319 case ACL_USER:
0320 case ACL_GROUP:
0321 not_equiv = 1;
0322 break;
0323 default:
0324 return -EINVAL;
0325 }
0326 }
0327 if (mode_p)
0328 *mode_p = (*mode_p & ~S_IRWXUGO) | mode;
0329 return not_equiv;
0330 }
0331 EXPORT_SYMBOL(posix_acl_equiv_mode);
0332
0333
0334
0335
0336 struct posix_acl *
0337 posix_acl_from_mode(umode_t mode, gfp_t flags)
0338 {
0339 struct posix_acl *acl = posix_acl_alloc(3, flags);
0340 if (!acl)
0341 return ERR_PTR(-ENOMEM);
0342
0343 acl->a_entries[0].e_tag = ACL_USER_OBJ;
0344 acl->a_entries[0].e_perm = (mode & S_IRWXU) >> 6;
0345
0346 acl->a_entries[1].e_tag = ACL_GROUP_OBJ;
0347 acl->a_entries[1].e_perm = (mode & S_IRWXG) >> 3;
0348
0349 acl->a_entries[2].e_tag = ACL_OTHER;
0350 acl->a_entries[2].e_perm = (mode & S_IRWXO);
0351 return acl;
0352 }
0353 EXPORT_SYMBOL(posix_acl_from_mode);
0354
0355
0356
0357
0358
0359 int
0360 posix_acl_permission(struct user_namespace *mnt_userns, struct inode *inode,
0361 const struct posix_acl *acl, int want)
0362 {
0363 const struct posix_acl_entry *pa, *pe, *mask_obj;
0364 struct user_namespace *fs_userns = i_user_ns(inode);
0365 int found = 0;
0366 vfsuid_t vfsuid;
0367 vfsgid_t vfsgid;
0368
0369 want &= MAY_READ | MAY_WRITE | MAY_EXEC;
0370
0371 FOREACH_ACL_ENTRY(pa, acl, pe) {
0372 switch(pa->e_tag) {
0373 case ACL_USER_OBJ:
0374
0375 vfsuid = i_uid_into_vfsuid(mnt_userns, inode);
0376 if (vfsuid_eq_kuid(vfsuid, current_fsuid()))
0377 goto check_perm;
0378 break;
0379 case ACL_USER:
0380 vfsuid = make_vfsuid(mnt_userns, fs_userns,
0381 pa->e_uid);
0382 if (vfsuid_eq_kuid(vfsuid, current_fsuid()))
0383 goto mask;
0384 break;
0385 case ACL_GROUP_OBJ:
0386 vfsgid = i_gid_into_vfsgid(mnt_userns, inode);
0387 if (vfsgid_in_group_p(vfsgid)) {
0388 found = 1;
0389 if ((pa->e_perm & want) == want)
0390 goto mask;
0391 }
0392 break;
0393 case ACL_GROUP:
0394 vfsgid = make_vfsgid(mnt_userns, fs_userns,
0395 pa->e_gid);
0396 if (vfsgid_in_group_p(vfsgid)) {
0397 found = 1;
0398 if ((pa->e_perm & want) == want)
0399 goto mask;
0400 }
0401 break;
0402 case ACL_MASK:
0403 break;
0404 case ACL_OTHER:
0405 if (found)
0406 return -EACCES;
0407 else
0408 goto check_perm;
0409 default:
0410 return -EIO;
0411 }
0412 }
0413 return -EIO;
0414
0415 mask:
0416 for (mask_obj = pa+1; mask_obj != pe; mask_obj++) {
0417 if (mask_obj->e_tag == ACL_MASK) {
0418 if ((pa->e_perm & mask_obj->e_perm & want) == want)
0419 return 0;
0420 return -EACCES;
0421 }
0422 }
0423
0424 check_perm:
0425 if ((pa->e_perm & want) == want)
0426 return 0;
0427 return -EACCES;
0428 }
0429
0430
0431
0432
0433
0434
0435
0436
0437
0438 static int posix_acl_create_masq(struct posix_acl *acl, umode_t *mode_p)
0439 {
0440 struct posix_acl_entry *pa, *pe;
0441 struct posix_acl_entry *group_obj = NULL, *mask_obj = NULL;
0442 umode_t mode = *mode_p;
0443 int not_equiv = 0;
0444
0445
0446
0447 FOREACH_ACL_ENTRY(pa, acl, pe) {
0448 switch(pa->e_tag) {
0449 case ACL_USER_OBJ:
0450 pa->e_perm &= (mode >> 6) | ~S_IRWXO;
0451 mode &= (pa->e_perm << 6) | ~S_IRWXU;
0452 break;
0453
0454 case ACL_USER:
0455 case ACL_GROUP:
0456 not_equiv = 1;
0457 break;
0458
0459 case ACL_GROUP_OBJ:
0460 group_obj = pa;
0461 break;
0462
0463 case ACL_OTHER:
0464 pa->e_perm &= mode | ~S_IRWXO;
0465 mode &= pa->e_perm | ~S_IRWXO;
0466 break;
0467
0468 case ACL_MASK:
0469 mask_obj = pa;
0470 not_equiv = 1;
0471 break;
0472
0473 default:
0474 return -EIO;
0475 }
0476 }
0477
0478 if (mask_obj) {
0479 mask_obj->e_perm &= (mode >> 3) | ~S_IRWXO;
0480 mode &= (mask_obj->e_perm << 3) | ~S_IRWXG;
0481 } else {
0482 if (!group_obj)
0483 return -EIO;
0484 group_obj->e_perm &= (mode >> 3) | ~S_IRWXO;
0485 mode &= (group_obj->e_perm << 3) | ~S_IRWXG;
0486 }
0487
0488 *mode_p = (*mode_p & ~S_IRWXUGO) | mode;
0489 return not_equiv;
0490 }
0491
0492
0493
0494
0495 static int __posix_acl_chmod_masq(struct posix_acl *acl, umode_t mode)
0496 {
0497 struct posix_acl_entry *group_obj = NULL, *mask_obj = NULL;
0498 struct posix_acl_entry *pa, *pe;
0499
0500
0501
0502 FOREACH_ACL_ENTRY(pa, acl, pe) {
0503 switch(pa->e_tag) {
0504 case ACL_USER_OBJ:
0505 pa->e_perm = (mode & S_IRWXU) >> 6;
0506 break;
0507
0508 case ACL_USER:
0509 case ACL_GROUP:
0510 break;
0511
0512 case ACL_GROUP_OBJ:
0513 group_obj = pa;
0514 break;
0515
0516 case ACL_MASK:
0517 mask_obj = pa;
0518 break;
0519
0520 case ACL_OTHER:
0521 pa->e_perm = (mode & S_IRWXO);
0522 break;
0523
0524 default:
0525 return -EIO;
0526 }
0527 }
0528
0529 if (mask_obj) {
0530 mask_obj->e_perm = (mode & S_IRWXG) >> 3;
0531 } else {
0532 if (!group_obj)
0533 return -EIO;
0534 group_obj->e_perm = (mode & S_IRWXG) >> 3;
0535 }
0536
0537 return 0;
0538 }
0539
0540 int
0541 __posix_acl_create(struct posix_acl **acl, gfp_t gfp, umode_t *mode_p)
0542 {
0543 struct posix_acl *clone = posix_acl_clone(*acl, gfp);
0544 int err = -ENOMEM;
0545 if (clone) {
0546 err = posix_acl_create_masq(clone, mode_p);
0547 if (err < 0) {
0548 posix_acl_release(clone);
0549 clone = NULL;
0550 }
0551 }
0552 posix_acl_release(*acl);
0553 *acl = clone;
0554 return err;
0555 }
0556 EXPORT_SYMBOL(__posix_acl_create);
0557
0558 int
0559 __posix_acl_chmod(struct posix_acl **acl, gfp_t gfp, umode_t mode)
0560 {
0561 struct posix_acl *clone = posix_acl_clone(*acl, gfp);
0562 int err = -ENOMEM;
0563 if (clone) {
0564 err = __posix_acl_chmod_masq(clone, mode);
0565 if (err) {
0566 posix_acl_release(clone);
0567 clone = NULL;
0568 }
0569 }
0570 posix_acl_release(*acl);
0571 *acl = clone;
0572 return err;
0573 }
0574 EXPORT_SYMBOL(__posix_acl_chmod);
0575
0576
0577
0578
0579
0580
0581
0582
0583
0584
0585
0586
0587
0588
0589 int
0590 posix_acl_chmod(struct user_namespace *mnt_userns, struct inode *inode,
0591 umode_t mode)
0592 {
0593 struct posix_acl *acl;
0594 int ret = 0;
0595
0596 if (!IS_POSIXACL(inode))
0597 return 0;
0598 if (!inode->i_op->set_acl)
0599 return -EOPNOTSUPP;
0600
0601 acl = get_acl(inode, ACL_TYPE_ACCESS);
0602 if (IS_ERR_OR_NULL(acl)) {
0603 if (acl == ERR_PTR(-EOPNOTSUPP))
0604 return 0;
0605 return PTR_ERR(acl);
0606 }
0607
0608 ret = __posix_acl_chmod(&acl, GFP_KERNEL, mode);
0609 if (ret)
0610 return ret;
0611 ret = inode->i_op->set_acl(mnt_userns, inode, acl, ACL_TYPE_ACCESS);
0612 posix_acl_release(acl);
0613 return ret;
0614 }
0615 EXPORT_SYMBOL(posix_acl_chmod);
0616
0617 int
0618 posix_acl_create(struct inode *dir, umode_t *mode,
0619 struct posix_acl **default_acl, struct posix_acl **acl)
0620 {
0621 struct posix_acl *p;
0622 struct posix_acl *clone;
0623 int ret;
0624
0625 *acl = NULL;
0626 *default_acl = NULL;
0627
0628 if (S_ISLNK(*mode) || !IS_POSIXACL(dir))
0629 return 0;
0630
0631 p = get_acl(dir, ACL_TYPE_DEFAULT);
0632 if (!p || p == ERR_PTR(-EOPNOTSUPP)) {
0633 *mode &= ~current_umask();
0634 return 0;
0635 }
0636 if (IS_ERR(p))
0637 return PTR_ERR(p);
0638
0639 ret = -ENOMEM;
0640 clone = posix_acl_clone(p, GFP_NOFS);
0641 if (!clone)
0642 goto err_release;
0643
0644 ret = posix_acl_create_masq(clone, mode);
0645 if (ret < 0)
0646 goto err_release_clone;
0647
0648 if (ret == 0)
0649 posix_acl_release(clone);
0650 else
0651 *acl = clone;
0652
0653 if (!S_ISDIR(*mode))
0654 posix_acl_release(p);
0655 else
0656 *default_acl = p;
0657
0658 return 0;
0659
0660 err_release_clone:
0661 posix_acl_release(clone);
0662 err_release:
0663 posix_acl_release(p);
0664 return ret;
0665 }
0666 EXPORT_SYMBOL_GPL(posix_acl_create);
0667
0668
0669
0670
0671
0672
0673
0674
0675
0676
0677
0678
0679
0680
0681
0682
0683
0684
0685
0686
0687
0688
0689
0690 int posix_acl_update_mode(struct user_namespace *mnt_userns,
0691 struct inode *inode, umode_t *mode_p,
0692 struct posix_acl **acl)
0693 {
0694 umode_t mode = inode->i_mode;
0695 int error;
0696
0697 error = posix_acl_equiv_mode(*acl, &mode);
0698 if (error < 0)
0699 return error;
0700 if (error == 0)
0701 *acl = NULL;
0702 if (!vfsgid_in_group_p(i_gid_into_vfsgid(mnt_userns, inode)) &&
0703 !capable_wrt_inode_uidgid(mnt_userns, inode, CAP_FSETID))
0704 mode &= ~S_ISGID;
0705 *mode_p = mode;
0706 return 0;
0707 }
0708 EXPORT_SYMBOL(posix_acl_update_mode);
0709
0710
0711
0712
0713 static int posix_acl_fix_xattr_common(void *value, size_t size)
0714 {
0715 struct posix_acl_xattr_header *header = value;
0716 int count;
0717
0718 if (!header)
0719 return -EINVAL;
0720 if (size < sizeof(struct posix_acl_xattr_header))
0721 return -EINVAL;
0722 if (header->a_version != cpu_to_le32(POSIX_ACL_XATTR_VERSION))
0723 return -EINVAL;
0724
0725 count = posix_acl_xattr_count(size);
0726 if (count < 0)
0727 return -EINVAL;
0728 if (count == 0)
0729 return -EINVAL;
0730
0731 return count;
0732 }
0733
0734 void posix_acl_getxattr_idmapped_mnt(struct user_namespace *mnt_userns,
0735 const struct inode *inode,
0736 void *value, size_t size)
0737 {
0738 struct posix_acl_xattr_header *header = value;
0739 struct posix_acl_xattr_entry *entry = (void *)(header + 1), *end;
0740 struct user_namespace *fs_userns = i_user_ns(inode);
0741 int count;
0742 vfsuid_t vfsuid;
0743 vfsgid_t vfsgid;
0744 kuid_t uid;
0745 kgid_t gid;
0746
0747 if (no_idmapping(mnt_userns, i_user_ns(inode)))
0748 return;
0749
0750 count = posix_acl_fix_xattr_common(value, size);
0751 if (count < 0)
0752 return;
0753
0754 for (end = entry + count; entry != end; entry++) {
0755 switch (le16_to_cpu(entry->e_tag)) {
0756 case ACL_USER:
0757 uid = make_kuid(&init_user_ns, le32_to_cpu(entry->e_id));
0758 vfsuid = make_vfsuid(mnt_userns, fs_userns, uid);
0759 entry->e_id = cpu_to_le32(from_kuid(&init_user_ns,
0760 vfsuid_into_kuid(vfsuid)));
0761 break;
0762 case ACL_GROUP:
0763 gid = make_kgid(&init_user_ns, le32_to_cpu(entry->e_id));
0764 vfsgid = make_vfsgid(mnt_userns, fs_userns, gid);
0765 entry->e_id = cpu_to_le32(from_kgid(&init_user_ns,
0766 vfsgid_into_kgid(vfsgid)));
0767 break;
0768 default:
0769 break;
0770 }
0771 }
0772 }
0773
0774 void posix_acl_setxattr_idmapped_mnt(struct user_namespace *mnt_userns,
0775 const struct inode *inode,
0776 void *value, size_t size)
0777 {
0778 struct posix_acl_xattr_header *header = value;
0779 struct posix_acl_xattr_entry *entry = (void *)(header + 1), *end;
0780 struct user_namespace *fs_userns = i_user_ns(inode);
0781 int count;
0782 vfsuid_t vfsuid;
0783 vfsgid_t vfsgid;
0784 kuid_t uid;
0785 kgid_t gid;
0786
0787 if (no_idmapping(mnt_userns, i_user_ns(inode)))
0788 return;
0789
0790 count = posix_acl_fix_xattr_common(value, size);
0791 if (count < 0)
0792 return;
0793
0794 for (end = entry + count; entry != end; entry++) {
0795 switch (le16_to_cpu(entry->e_tag)) {
0796 case ACL_USER:
0797 uid = make_kuid(&init_user_ns, le32_to_cpu(entry->e_id));
0798 vfsuid = VFSUIDT_INIT(uid);
0799 uid = from_vfsuid(mnt_userns, fs_userns, vfsuid);
0800 entry->e_id = cpu_to_le32(from_kuid(&init_user_ns, uid));
0801 break;
0802 case ACL_GROUP:
0803 gid = make_kgid(&init_user_ns, le32_to_cpu(entry->e_id));
0804 vfsgid = VFSGIDT_INIT(gid);
0805 gid = from_vfsgid(mnt_userns, fs_userns, vfsgid);
0806 entry->e_id = cpu_to_le32(from_kgid(&init_user_ns, gid));
0807 break;
0808 default:
0809 break;
0810 }
0811 }
0812 }
0813
0814 static void posix_acl_fix_xattr_userns(
0815 struct user_namespace *to, struct user_namespace *from,
0816 void *value, size_t size)
0817 {
0818 struct posix_acl_xattr_header *header = value;
0819 struct posix_acl_xattr_entry *entry = (void *)(header + 1), *end;
0820 int count;
0821 kuid_t uid;
0822 kgid_t gid;
0823
0824 count = posix_acl_fix_xattr_common(value, size);
0825 if (count < 0)
0826 return;
0827
0828 for (end = entry + count; entry != end; entry++) {
0829 switch(le16_to_cpu(entry->e_tag)) {
0830 case ACL_USER:
0831 uid = make_kuid(from, le32_to_cpu(entry->e_id));
0832 entry->e_id = cpu_to_le32(from_kuid(to, uid));
0833 break;
0834 case ACL_GROUP:
0835 gid = make_kgid(from, le32_to_cpu(entry->e_id));
0836 entry->e_id = cpu_to_le32(from_kgid(to, gid));
0837 break;
0838 default:
0839 break;
0840 }
0841 }
0842 }
0843
0844 void posix_acl_fix_xattr_from_user(void *value, size_t size)
0845 {
0846 struct user_namespace *user_ns = current_user_ns();
0847 if (user_ns == &init_user_ns)
0848 return;
0849 posix_acl_fix_xattr_userns(&init_user_ns, user_ns, value, size);
0850 }
0851
0852 void posix_acl_fix_xattr_to_user(void *value, size_t size)
0853 {
0854 struct user_namespace *user_ns = current_user_ns();
0855 if (user_ns == &init_user_ns)
0856 return;
0857 posix_acl_fix_xattr_userns(user_ns, &init_user_ns, value, size);
0858 }
0859
0860
0861
0862
0863 struct posix_acl *
0864 posix_acl_from_xattr(struct user_namespace *user_ns,
0865 const void *value, size_t size)
0866 {
0867 const struct posix_acl_xattr_header *header = value;
0868 const struct posix_acl_xattr_entry *entry = (const void *)(header + 1), *end;
0869 int count;
0870 struct posix_acl *acl;
0871 struct posix_acl_entry *acl_e;
0872
0873 if (!value)
0874 return NULL;
0875 if (size < sizeof(struct posix_acl_xattr_header))
0876 return ERR_PTR(-EINVAL);
0877 if (header->a_version != cpu_to_le32(POSIX_ACL_XATTR_VERSION))
0878 return ERR_PTR(-EOPNOTSUPP);
0879
0880 count = posix_acl_xattr_count(size);
0881 if (count < 0)
0882 return ERR_PTR(-EINVAL);
0883 if (count == 0)
0884 return NULL;
0885
0886 acl = posix_acl_alloc(count, GFP_NOFS);
0887 if (!acl)
0888 return ERR_PTR(-ENOMEM);
0889 acl_e = acl->a_entries;
0890
0891 for (end = entry + count; entry != end; acl_e++, entry++) {
0892 acl_e->e_tag = le16_to_cpu(entry->e_tag);
0893 acl_e->e_perm = le16_to_cpu(entry->e_perm);
0894
0895 switch(acl_e->e_tag) {
0896 case ACL_USER_OBJ:
0897 case ACL_GROUP_OBJ:
0898 case ACL_MASK:
0899 case ACL_OTHER:
0900 break;
0901
0902 case ACL_USER:
0903 acl_e->e_uid =
0904 make_kuid(user_ns,
0905 le32_to_cpu(entry->e_id));
0906 if (!uid_valid(acl_e->e_uid))
0907 goto fail;
0908 break;
0909 case ACL_GROUP:
0910 acl_e->e_gid =
0911 make_kgid(user_ns,
0912 le32_to_cpu(entry->e_id));
0913 if (!gid_valid(acl_e->e_gid))
0914 goto fail;
0915 break;
0916
0917 default:
0918 goto fail;
0919 }
0920 }
0921 return acl;
0922
0923 fail:
0924 posix_acl_release(acl);
0925 return ERR_PTR(-EINVAL);
0926 }
0927 EXPORT_SYMBOL (posix_acl_from_xattr);
0928
0929
0930
0931
0932 int
0933 posix_acl_to_xattr(struct user_namespace *user_ns, const struct posix_acl *acl,
0934 void *buffer, size_t size)
0935 {
0936 struct posix_acl_xattr_header *ext_acl = buffer;
0937 struct posix_acl_xattr_entry *ext_entry;
0938 int real_size, n;
0939
0940 real_size = posix_acl_xattr_size(acl->a_count);
0941 if (!buffer)
0942 return real_size;
0943 if (real_size > size)
0944 return -ERANGE;
0945
0946 ext_entry = (void *)(ext_acl + 1);
0947 ext_acl->a_version = cpu_to_le32(POSIX_ACL_XATTR_VERSION);
0948
0949 for (n=0; n < acl->a_count; n++, ext_entry++) {
0950 const struct posix_acl_entry *acl_e = &acl->a_entries[n];
0951 ext_entry->e_tag = cpu_to_le16(acl_e->e_tag);
0952 ext_entry->e_perm = cpu_to_le16(acl_e->e_perm);
0953 switch(acl_e->e_tag) {
0954 case ACL_USER:
0955 ext_entry->e_id =
0956 cpu_to_le32(from_kuid(user_ns, acl_e->e_uid));
0957 break;
0958 case ACL_GROUP:
0959 ext_entry->e_id =
0960 cpu_to_le32(from_kgid(user_ns, acl_e->e_gid));
0961 break;
0962 default:
0963 ext_entry->e_id = cpu_to_le32(ACL_UNDEFINED_ID);
0964 break;
0965 }
0966 }
0967 return real_size;
0968 }
0969 EXPORT_SYMBOL (posix_acl_to_xattr);
0970
0971 static int
0972 posix_acl_xattr_get(const struct xattr_handler *handler,
0973 struct dentry *unused, struct inode *inode,
0974 const char *name, void *value, size_t size)
0975 {
0976 struct posix_acl *acl;
0977 int error;
0978
0979 if (!IS_POSIXACL(inode))
0980 return -EOPNOTSUPP;
0981 if (S_ISLNK(inode->i_mode))
0982 return -EOPNOTSUPP;
0983
0984 acl = get_acl(inode, handler->flags);
0985 if (IS_ERR(acl))
0986 return PTR_ERR(acl);
0987 if (acl == NULL)
0988 return -ENODATA;
0989
0990 error = posix_acl_to_xattr(&init_user_ns, acl, value, size);
0991 posix_acl_release(acl);
0992
0993 return error;
0994 }
0995
0996 int
0997 set_posix_acl(struct user_namespace *mnt_userns, struct inode *inode,
0998 int type, struct posix_acl *acl)
0999 {
1000 if (!IS_POSIXACL(inode))
1001 return -EOPNOTSUPP;
1002 if (!inode->i_op->set_acl)
1003 return -EOPNOTSUPP;
1004
1005 if (type == ACL_TYPE_DEFAULT && !S_ISDIR(inode->i_mode))
1006 return acl ? -EACCES : 0;
1007 if (!inode_owner_or_capable(mnt_userns, inode))
1008 return -EPERM;
1009
1010 if (acl) {
1011 int ret = posix_acl_valid(inode->i_sb->s_user_ns, acl);
1012 if (ret)
1013 return ret;
1014 }
1015 return inode->i_op->set_acl(mnt_userns, inode, acl, type);
1016 }
1017 EXPORT_SYMBOL(set_posix_acl);
1018
1019 static int
1020 posix_acl_xattr_set(const struct xattr_handler *handler,
1021 struct user_namespace *mnt_userns,
1022 struct dentry *unused, struct inode *inode,
1023 const char *name, const void *value, size_t size,
1024 int flags)
1025 {
1026 struct posix_acl *acl = NULL;
1027 int ret;
1028
1029 if (value) {
1030 acl = posix_acl_from_xattr(&init_user_ns, value, size);
1031 if (IS_ERR(acl))
1032 return PTR_ERR(acl);
1033 }
1034 ret = set_posix_acl(mnt_userns, inode, handler->flags, acl);
1035 posix_acl_release(acl);
1036 return ret;
1037 }
1038
1039 static bool
1040 posix_acl_xattr_list(struct dentry *dentry)
1041 {
1042 return IS_POSIXACL(d_backing_inode(dentry));
1043 }
1044
1045 const struct xattr_handler posix_acl_access_xattr_handler = {
1046 .name = XATTR_NAME_POSIX_ACL_ACCESS,
1047 .flags = ACL_TYPE_ACCESS,
1048 .list = posix_acl_xattr_list,
1049 .get = posix_acl_xattr_get,
1050 .set = posix_acl_xattr_set,
1051 };
1052 EXPORT_SYMBOL_GPL(posix_acl_access_xattr_handler);
1053
1054 const struct xattr_handler posix_acl_default_xattr_handler = {
1055 .name = XATTR_NAME_POSIX_ACL_DEFAULT,
1056 .flags = ACL_TYPE_DEFAULT,
1057 .list = posix_acl_xattr_list,
1058 .get = posix_acl_xattr_get,
1059 .set = posix_acl_xattr_set,
1060 };
1061 EXPORT_SYMBOL_GPL(posix_acl_default_xattr_handler);
1062
1063 int simple_set_acl(struct user_namespace *mnt_userns, struct inode *inode,
1064 struct posix_acl *acl, int type)
1065 {
1066 int error;
1067
1068 if (type == ACL_TYPE_ACCESS) {
1069 error = posix_acl_update_mode(mnt_userns, inode,
1070 &inode->i_mode, &acl);
1071 if (error)
1072 return error;
1073 }
1074
1075 inode->i_ctime = current_time(inode);
1076 set_cached_acl(inode, type, acl);
1077 return 0;
1078 }
1079
1080 int simple_acl_create(struct inode *dir, struct inode *inode)
1081 {
1082 struct posix_acl *default_acl, *acl;
1083 int error;
1084
1085 error = posix_acl_create(dir, &inode->i_mode, &default_acl, &acl);
1086 if (error)
1087 return error;
1088
1089 set_cached_acl(inode, ACL_TYPE_DEFAULT, default_acl);
1090 set_cached_acl(inode, ACL_TYPE_ACCESS, acl);
1091
1092 if (default_acl)
1093 posix_acl_release(default_acl);
1094 if (acl)
1095 posix_acl_release(acl);
1096 return 0;
1097 }