Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * Copyright (C) 2002,2003 by Andreas Gruenbacher <a.gruenbacher@computer.org>
0004  *
0005  * Fixes from William Schumacher incorporated on 15 March 2001.
0006  *    (Reported by Charles Bertsch, <CBertsch@microtest.com>).
0007  */
0008 
0009 /*
0010  *  This file contains generic functions for manipulating
0011  *  POSIX 1003.1e draft standard 17 ACLs.
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      * The sentinel is used to detect when another operation like
0116      * set_cached_acl() or forget_cached_acl() races with get_acl().
0117      * It is guaranteed that is_uncached_acl(sentinel) is true.
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      * If the ACL isn't being read yet, set our sentinel.  Otherwise, the
0132      * current value of the ACL will not be ACL_NOT_CACHED and so our own
0133      * sentinel will not be set; another task will update the cache.  We
0134      * could wait for that other task to complete its job, but it's easier
0135      * to just call ->get_acl to fetch the ACL ourself.  (This is going to
0136      * be an unlikely race.)
0137      */
0138     cmpxchg(p, ACL_NOT_CACHED, sentinel);
0139 
0140     /*
0141      * Normally, the ACL returned by ->get_acl will be cached.
0142      * A filesystem can prevent that by calling
0143      * forget_cached_acl(inode, type) in ->get_acl.
0144      *
0145      * If the filesystem doesn't have a get_acl() function at all, we'll
0146      * just create the negative cache entry.
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          * Remove our sentinel so that we don't block future attempts
0157          * to cache the ACL.
0158          */
0159         cmpxchg(p, sentinel, ACL_NOT_CACHED);
0160         return acl;
0161     }
0162 
0163     /*
0164      * Cache the result, but only if our sentinel is still in place.
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  * Init a fresh posix_acl
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  * Allocate a new ACL with the specified number of entries.
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  * Clone an ACL.
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  * Check if an acl is valid. Returns 0 if it is, or -E... otherwise.
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  * Returns 0 if the acl can be exactly represented in the traditional
0288  * file mode permission bits, or else 1. Returns -E... on error.
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      * A null ACL can always be presented as mode bits.
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  * Create an ACL representing the file mode permission bits of an inode.
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  * Return 0 if current is granted want access to the inode
0357  * by the acl. Returns -E... otherwise.
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                 /* (May have been checked already) */
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  * Modify acl when creating a new inode. The caller must ensure the acl is
0432  * only referenced once.
0433  *
0434  * mode_p initially must contain the mode parameter to the open() / creat()
0435  * system calls. All permissions that are not granted by the acl are removed.
0436  * The permissions in the acl are changed to reflect the mode_p parameter.
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     /* assert(atomic_read(acl->a_refcount) == 1); */
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  * Modify the ACL for the chmod syscall.
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     /* assert(atomic_read(acl->a_refcount) == 1); */
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  * posix_acl_chmod - chmod a posix acl
0578  *
0579  * @mnt_userns: user namespace of the mount @inode was found from
0580  * @inode:  inode to check permissions on
0581  * @mode:   the new mode of @inode
0582  *
0583  * If the inode has been found through an idmapped mount the user namespace of
0584  * the vfsmount must be passed through @mnt_userns. This function will then
0585  * take care to map the inode according to @mnt_userns before checking
0586  * permissions. On non-idmapped mounts or if permission checking is to be
0587  * performed on the raw inode simply passs init_user_ns.
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  * posix_acl_update_mode  -  update mode in set_acl
0670  * @mnt_userns: user namespace of the mount @inode was found from
0671  * @inode:  target inode
0672  * @mode_p: mode (pointer) for update
0673  * @acl:    acl pointer
0674  *
0675  * Update the file mode when setting an ACL: compute the new file permission
0676  * bits based on the ACL.  In addition, if the ACL is equivalent to the new
0677  * file mode, set *@acl to NULL to indicate that no ACL should be set.
0678  *
0679  * As with chmod, clear the setgid bit if the caller is not in the owning group
0680  * or capable of CAP_FSETID (see inode_change_ok).
0681  *
0682  * If the inode has been found through an idmapped mount the user namespace of
0683  * the vfsmount must be passed through @mnt_userns. This function will then
0684  * take care to map the inode according to @mnt_userns before checking
0685  * permissions. On non-idmapped mounts or if permission checking is to be
0686  * performed on the raw inode simply passs init_user_ns.
0687  *
0688  * Called from set_acl inode operations.
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  * Fix up the uids and gids in posix acl extended attributes in place.
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  * Convert from extended attribute to in-memory representation.
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  * Convert from in-memory to extended attribute representation.
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 }