LCOV - code coverage report
Current view: top level - fs - posix_acl.c (source / functions) Hit Total Coverage
Test: fstests of 6.5.0-rc3-djwx @ Mon Jul 31 20:08:22 PDT 2023 Lines: 456 559 81.6 %
Date: 2023-07-31 20:08:22 Functions: 31 37 83.8 %

          Line data    Source code
       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             : 
       9             : /*
      10             :  *  This file contains generic functions for manipulating
      11             :  *  POSIX 1003.1e draft standard 17 ACLs.
      12             :  */
      13             : 
      14             : #include <linux/kernel.h>
      15             : #include <linux/slab.h>
      16             : #include <linux/atomic.h>
      17             : #include <linux/fs.h>
      18             : #include <linux/sched.h>
      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>
      28             : #include <linux/security.h>
      29             : #include <linux/evm.h>
      30             : #include <linux/fsnotify.h>
      31             : #include <linux/filelock.h>
      32             : 
      33             : #include "internal.h"
      34             : 
      35             : static struct posix_acl **acl_by_type(struct inode *inode, int type)
      36             : {
      37  6737126648 :         switch (type) {
      38  6668133802 :         case ACL_TYPE_ACCESS:
      39  6668133802 :                 return &inode->i_acl;
      40    68992846 :         case ACL_TYPE_DEFAULT:
      41    68992846 :                 return &inode->i_default_acl;
      42           0 :         default:
      43   284446462 :                 BUG();
      44             :         }
      45             : }
      46             : 
      47   284446462 : struct posix_acl *get_cached_acl(struct inode *inode, int type)
      48             : {
      49   284446462 :         struct posix_acl **p = acl_by_type(inode, type);
      50   284446462 :         struct posix_acl *acl;
      51             : 
      52   284446462 :         for (;;) {
      53   284446462 :                 rcu_read_lock();
      54   284259995 :                 acl = rcu_dereference(*p);
      55   284474986 :                 if (!acl || is_uncached_acl(acl) ||
      56      214991 :                     refcount_inc_not_zero(&acl->a_refcount))
      57             :                         break;
      58           0 :                 rcu_read_unlock();
      59           0 :                 cpu_relax();
      60             :         }
      61   284259995 :         rcu_read_unlock();
      62   284327172 :         return acl;
      63             : }
      64             : EXPORT_SYMBOL(get_cached_acl);
      65             : 
      66  6435416821 : struct posix_acl *get_cached_acl_rcu(struct inode *inode, int type)
      67             : {
      68  6435416821 :         struct posix_acl *acl = rcu_dereference(*acl_by_type(inode, type));
      69             : 
      70  6435416821 :         if (acl == ACL_DONT_CACHE) {
      71     1641155 :                 struct posix_acl *ret;
      72             : 
      73     1641155 :                 ret = inode->i_op->get_inode_acl(inode, type, LOOKUP_RCU);
      74     1641156 :                 if (!IS_ERR(ret))
      75     1640682 :                         acl = ret;
      76             :         }
      77             : 
      78  6435416822 :         return acl;
      79             : }
      80             : EXPORT_SYMBOL(get_cached_acl_rcu);
      81             : 
      82    15937780 : void set_cached_acl(struct inode *inode, int type, struct posix_acl *acl)
      83             : {
      84    15937780 :         struct posix_acl **p = acl_by_type(inode, type);
      85    15937780 :         struct posix_acl *old;
      86             : 
      87    16162165 :         old = xchg(p, posix_acl_dup(acl));
      88    16029313 :         if (!is_uncached_acl(old))
      89    15803739 :                 posix_acl_release(old);
      90    16020402 : }
      91             : EXPORT_SYMBOL(set_cached_acl);
      92             : 
      93          11 : static void __forget_cached_acl(struct posix_acl **p)
      94             : {
      95          11 :         struct posix_acl *old;
      96             : 
      97          11 :         old = xchg(p, ACL_NOT_CACHED);
      98          11 :         if (!is_uncached_acl(old))
      99          11 :                 posix_acl_release(old);
     100          11 : }
     101             : 
     102          11 : void forget_cached_acl(struct inode *inode, int type)
     103             : {
     104          22 :         __forget_cached_acl(acl_by_type(inode, type));
     105          11 : }
     106             : EXPORT_SYMBOL(forget_cached_acl);
     107             : 
     108           0 : void forget_all_cached_acls(struct inode *inode)
     109             : {
     110           0 :         __forget_cached_acl(&inode->i_acl);
     111           0 :         __forget_cached_acl(&inode->i_default_acl);
     112           0 : }
     113             : EXPORT_SYMBOL(forget_all_cached_acls);
     114             : 
     115   284249228 : static struct posix_acl *__get_acl(struct mnt_idmap *idmap,
     116             :                                    struct dentry *dentry, struct inode *inode,
     117             :                                    int type)
     118             : {
     119   284249228 :         struct posix_acl *sentinel;
     120   284249228 :         struct posix_acl **p;
     121   284249228 :         struct posix_acl *acl;
     122             : 
     123             :         /*
     124             :          * The sentinel is used to detect when another operation like
     125             :          * set_cached_acl() or forget_cached_acl() races with get_inode_acl().
     126             :          * It is guaranteed that is_uncached_acl(sentinel) is true.
     127             :          */
     128             : 
     129   284249228 :         acl = get_cached_acl(inode, type);
     130   284172051 :         if (!is_uncached_acl(acl))
     131             :                 return acl;
     132             : 
     133     1325574 :         if (!IS_POSIXACL(inode))
     134             :                 return NULL;
     135             : 
     136     1325574 :         sentinel = uncached_acl_sentinel(current);
     137     1325574 :         p = acl_by_type(inode, type);
     138             : 
     139             :         /*
     140             :          * If the ACL isn't being read yet, set our sentinel.  Otherwise, the
     141             :          * current value of the ACL will not be ACL_NOT_CACHED and so our own
     142             :          * sentinel will not be set; another task will update the cache.  We
     143             :          * could wait for that other task to complete its job, but it's easier
     144             :          * to just call ->get_inode_acl to fetch the ACL ourself.  (This is
     145             :          * going to be an unlikely race.)
     146             :          */
     147     1325574 :         cmpxchg(p, ACL_NOT_CACHED, sentinel);
     148             : 
     149             :         /*
     150             :          * Normally, the ACL returned by ->get{_inode}_acl will be cached.
     151             :          * A filesystem can prevent that by calling
     152             :          * forget_cached_acl(inode, type) in ->get{_inode}_acl.
     153             :          *
     154             :          * If the filesystem doesn't have a get{_inode}_ acl() function at all,
     155             :          * we'll just create the negative cache entry.
     156             :          */
     157     1325646 :         if (dentry && inode->i_op->get_acl) {
     158          22 :                 acl = inode->i_op->get_acl(idmap, dentry, type);
     159     1325624 :         } else if (inode->i_op->get_inode_acl) {
     160     1322732 :                 acl = inode->i_op->get_inode_acl(inode, type, false);
     161             :         } else {
     162        2892 :                 set_cached_acl(inode, type, NULL);
     163        2892 :                 return NULL;
     164             :         }
     165     1322628 :         if (IS_ERR(acl)) {
     166             :                 /*
     167             :                  * Remove our sentinel so that we don't block future attempts
     168             :                  * to cache the ACL.
     169             :                  */
     170         123 :                 cmpxchg(p, sentinel, ACL_NOT_CACHED);
     171         123 :                 return acl;
     172             :         }
     173             : 
     174             :         /*
     175             :          * Cache the result, but only if our sentinel is still in place.
     176             :          */
     177     1322505 :         posix_acl_dup(acl);
     178     1322461 :         if (unlikely(!try_cmpxchg(p, &sentinel, acl)))
     179      882473 :                 posix_acl_release(acl);
     180             :         return acl;
     181             : }
     182             : 
     183   207103575 : struct posix_acl *get_inode_acl(struct inode *inode, int type)
     184             : {
     185   207103575 :         return __get_acl(&nop_mnt_idmap, NULL, inode, type);
     186             : }
     187             : EXPORT_SYMBOL(get_inode_acl);
     188             : 
     189             : /*
     190             :  * Init a fresh posix_acl
     191             :  */
     192             : void
     193           0 : posix_acl_init(struct posix_acl *acl, int count)
     194             : {
     195    11874074 :         refcount_set(&acl->a_refcount, 1);
     196    11874074 :         acl->a_count = count;
     197    11874074 : }
     198             : EXPORT_SYMBOL(posix_acl_init);
     199             : 
     200             : /*
     201             :  * Allocate a new ACL with the specified number of entries.
     202             :  */
     203             : struct posix_acl *
     204    11855373 : posix_acl_alloc(int count, gfp_t flags)
     205             : {
     206    11855373 :         const size_t size = sizeof(struct posix_acl) +
     207             :                             count * sizeof(struct posix_acl_entry);
     208    11855373 :         struct posix_acl *acl = kmalloc(size, flags);
     209    11874074 :         if (acl)
     210    11874074 :                 posix_acl_init(acl, count);
     211    11874074 :         return acl;
     212             : }
     213             : EXPORT_SYMBOL(posix_acl_alloc);
     214             : 
     215             : /*
     216             :  * Clone an ACL.
     217             :  */
     218             : struct posix_acl *
     219      210438 : posix_acl_clone(const struct posix_acl *acl, gfp_t flags)
     220             : {
     221      210438 :         struct posix_acl *clone = NULL;
     222             : 
     223      210438 :         if (acl) {
     224      210438 :                 int size = sizeof(struct posix_acl) + acl->a_count *
     225             :                            sizeof(struct posix_acl_entry);
     226      210438 :                 clone = kmemdup(acl, size, flags);
     227      210438 :                 if (clone)
     228      210438 :                         refcount_set(&clone->a_refcount, 1);
     229             :         }
     230      210438 :         return clone;
     231             : }
     232             : EXPORT_SYMBOL_GPL(posix_acl_clone);
     233             : 
     234             : /*
     235             :  * Check if an acl is valid. Returns 0 if it is, or -E... otherwise.
     236             :  */
     237             : int
     238    11803819 : posix_acl_valid(struct user_namespace *user_ns, const struct posix_acl *acl)
     239             : {
     240    11803819 :         const struct posix_acl_entry *pa, *pe;
     241    11803819 :         int state = ACL_USER_OBJ;
     242    11803819 :         int needs_mask = 0;
     243             : 
     244    47289430 :         FOREACH_ACL_ENTRY(pa, acl, pe) {
     245    35519916 :                 if (pa->e_perm & ~(ACL_READ|ACL_WRITE|ACL_EXECUTE))
     246             :                         return -EINVAL;
     247    35519916 :                 switch (pa->e_tag) {
     248    11760960 :                         case ACL_USER_OBJ:
     249    11760960 :                                 if (state == ACL_USER_OBJ) {
     250             :                                         state = ACL_USER;
     251             :                                         break;
     252             :                                 }
     253             :                                 return -EINVAL;
     254             : 
     255      181327 :                         case ACL_USER:
     256      181327 :                                 if (state != ACL_USER)
     257             :                                         return -EINVAL;
     258      181327 :                                 if (!kuid_has_mapping(user_ns, pa->e_uid))
     259             :                                         return -EINVAL;
     260             :                                 needs_mask = 1;
     261             :                                 break;
     262             : 
     263    11766018 :                         case ACL_GROUP_OBJ:
     264    11766018 :                                 if (state == ACL_USER) {
     265             :                                         state = ACL_GROUP;
     266             :                                         break;
     267             :                                 }
     268             :                                 return -EINVAL;
     269             : 
     270          65 :                         case ACL_GROUP:
     271          65 :                                 if (state != ACL_GROUP)
     272             :                                         return -EINVAL;
     273          65 :                                 if (!kgid_has_mapping(user_ns, pa->e_gid))
     274             :                                         return -EINVAL;
     275             :                                 needs_mask = 1;
     276             :                                 break;
     277             : 
     278         474 :                         case ACL_MASK:
     279         474 :                                 if (state != ACL_GROUP)
     280             :                                         return -EINVAL;
     281             :                                 state = ACL_OTHER;
     282             :                                 break;
     283             : 
     284    11776767 :                         case ACL_OTHER:
     285    11776767 :                                 if (state == ACL_OTHER ||
     286    11776293 :                                     (state == ACL_GROUP && !needs_mask)) {
     287             :                                         state = 0;
     288             :                                         break;
     289             :                                 }
     290             :                                 return -EINVAL;
     291             : 
     292             :                         default:
     293             :                                 return -EINVAL;
     294             :                 }
     295             :         }
     296    11769514 :         if (state == 0)
     297    11769514 :                 return 0;
     298             :         return -EINVAL;
     299             : }
     300             : EXPORT_SYMBOL(posix_acl_valid);
     301             : 
     302             : /*
     303             :  * Returns 0 if the acl can be exactly represented in the traditional
     304             :  * file mode permission bits, or else 1. Returns -E... on error.
     305             :  */
     306             : int
     307    11806558 : posix_acl_equiv_mode(const struct posix_acl *acl, umode_t *mode_p)
     308             : {
     309    11806558 :         const struct posix_acl_entry *pa, *pe;
     310    11806558 :         umode_t mode = 0;
     311    11806558 :         int not_equiv = 0;
     312             : 
     313             :         /*
     314             :          * A null ACL can always be presented as mode bits.
     315             :          */
     316    11806558 :         if (!acl)
     317             :                 return 0;
     318             : 
     319    47260971 :         FOREACH_ACL_ENTRY(pa, acl, pe) {
     320    35485168 :                 switch (pa->e_tag) {
     321    11795660 :                         case ACL_USER_OBJ:
     322    11795660 :                                 mode |= (pa->e_perm & S_IRWXO) << 6;
     323    11795660 :                                 break;
     324    11761143 :                         case ACL_GROUP_OBJ:
     325    11761143 :                                 mode |= (pa->e_perm & S_IRWXO) << 3;
     326    11761143 :                                 break;
     327    11776308 :                         case ACL_OTHER:
     328    11776308 :                                 mode |= pa->e_perm & S_IRWXO;
     329    11776308 :                                 break;
     330         337 :                         case ACL_MASK:
     331         337 :                                 mode = (mode & ~S_IRWXG) |
     332         337 :                                        ((pa->e_perm & S_IRWXO) << 3);
     333         337 :                                 not_equiv = 1;
     334         337 :                                 break;
     335             :                         case ACL_USER:
     336             :                         case ACL_GROUP:
     337             :                                 not_equiv = 1;
     338             :                                 break;
     339             :                         default:
     340             :                                 return -EINVAL;
     341             :                 }
     342             :         }
     343    11775803 :         if (mode_p)
     344    11775803 :                 *mode_p = (*mode_p & ~S_IRWXUGO) | mode;
     345             :         return not_equiv;
     346             : }
     347             : EXPORT_SYMBOL(posix_acl_equiv_mode);
     348             : 
     349             : /*
     350             :  * Create an ACL representing the file mode permission bits of an inode.
     351             :  */
     352             : struct posix_acl *
     353           0 : posix_acl_from_mode(umode_t mode, gfp_t flags)
     354             : {
     355           0 :         struct posix_acl *acl = posix_acl_alloc(3, flags);
     356           0 :         if (!acl)
     357             :                 return ERR_PTR(-ENOMEM);
     358             : 
     359           0 :         acl->a_entries[0].e_tag  = ACL_USER_OBJ;
     360           0 :         acl->a_entries[0].e_perm = (mode & S_IRWXU) >> 6;
     361             : 
     362           0 :         acl->a_entries[1].e_tag  = ACL_GROUP_OBJ;
     363           0 :         acl->a_entries[1].e_perm = (mode & S_IRWXG) >> 3;
     364             : 
     365           0 :         acl->a_entries[2].e_tag  = ACL_OTHER;
     366           0 :         acl->a_entries[2].e_perm = (mode & S_IRWXO);
     367           0 :         return acl;
     368             : }
     369             : EXPORT_SYMBOL(posix_acl_from_mode);
     370             : 
     371             : /*
     372             :  * Return 0 if current is granted want access to the inode
     373             :  * by the acl. Returns -E... otherwise.
     374             :  */
     375             : int
     376        1766 : posix_acl_permission(struct mnt_idmap *idmap, struct inode *inode,
     377             :                      const struct posix_acl *acl, int want)
     378             : {
     379        1766 :         const struct posix_acl_entry *pa, *pe, *mask_obj;
     380        1766 :         struct user_namespace *fs_userns = i_user_ns(inode);
     381        1766 :         int found = 0;
     382        1766 :         vfsuid_t vfsuid;
     383        1766 :         vfsgid_t vfsgid;
     384             : 
     385        1766 :         want &= MAY_READ | MAY_WRITE | MAY_EXEC;
     386             : 
     387        6210 :         FOREACH_ACL_ENTRY(pa, acl, pe) {
     388        6210 :                 switch(pa->e_tag) {
     389             :                         case ACL_USER_OBJ:
     390             :                                 /* (May have been checked already) */
     391        1766 :                                 vfsuid = i_uid_into_vfsuid(idmap, inode);
     392        3519 :                                 if (vfsuid_eq_kuid(vfsuid, current_fsuid()))
     393           0 :                                         goto check_perm;
     394             :                                 break;
     395        1688 :                         case ACL_USER:
     396        1688 :                                 vfsuid = make_vfsuid(idmap, fs_userns,
     397             :                                                      pa->e_uid);
     398        3376 :                                 if (vfsuid_eq_kuid(vfsuid, current_fsuid()))
     399         830 :                                         goto mask;
     400             :                                 break;
     401             :                         case ACL_GROUP_OBJ:
     402         936 :                                 vfsgid = i_gid_into_vfsgid(idmap, inode);
     403         936 :                                 if (vfsgid_in_group_p(vfsgid)) {
     404         132 :                                         found = 1;
     405         132 :                                         if ((pa->e_perm & want) == want)
     406           0 :                                                 goto mask;
     407             :                                 }
     408             :                                 break;
     409          78 :                         case ACL_GROUP:
     410          78 :                                 vfsgid = make_vfsgid(idmap, fs_userns,
     411             :                                                      pa->e_gid);
     412          78 :                                 if (vfsgid_in_group_p(vfsgid)) {
     413          65 :                                         found = 1;
     414          65 :                                         if ((pa->e_perm & want) == want)
     415          65 :                                                 goto mask;
     416             :                                 }
     417             :                                 break;
     418             :                         case ACL_MASK:
     419             :                                 break;
     420         871 :                         case ACL_OTHER:
     421         871 :                                 if (found)
     422             :                                         return -EACCES;
     423             :                                 else
     424         804 :                                         goto check_perm;
     425             :                         default:
     426             :                                 return -EIO;
     427             :                 }
     428             :         }
     429             :         return -EIO;
     430             : 
     431         895 : mask:
     432        1725 :         for (mask_obj = pa+1; mask_obj != pe; mask_obj++) {
     433        1725 :                 if (mask_obj->e_tag == ACL_MASK) {
     434         895 :                         if ((pa->e_perm & mask_obj->e_perm & want) == want)
     435             :                                 return 0;
     436          26 :                         return -EACCES;
     437             :                 }
     438             :         }
     439             : 
     440           0 : check_perm:
     441         804 :         if ((pa->e_perm & want) == want)
     442         778 :                 return 0;
     443             :         return -EACCES;
     444             : }
     445             : 
     446             : /*
     447             :  * Modify acl when creating a new inode. The caller must ensure the acl is
     448             :  * only referenced once.
     449             :  *
     450             :  * mode_p initially must contain the mode parameter to the open() / creat()
     451             :  * system calls. All permissions that are not granted by the acl are removed.
     452             :  * The permissions in the acl are changed to reflect the mode_p parameter.
     453             :  */
     454      210438 : static int posix_acl_create_masq(struct posix_acl *acl, umode_t *mode_p)
     455             : {
     456      210438 :         struct posix_acl_entry *pa, *pe;
     457      210438 :         struct posix_acl_entry *group_obj = NULL, *mask_obj = NULL;
     458      210438 :         umode_t mode = *mode_p;
     459      210438 :         int not_equiv = 0;
     460             : 
     461             :         /* assert(atomic_read(acl->a_refcount) == 1); */
     462             : 
     463     1262134 :         FOREACH_ACL_ENTRY(pa, acl, pe) {
     464     1051696 :                 switch(pa->e_tag) {
     465      210438 :                         case ACL_USER_OBJ:
     466      210438 :                                 pa->e_perm &= (mode >> 6) | ~S_IRWXO;
     467      210438 :                                 mode &= (pa->e_perm << 6) | ~S_IRWXU;
     468      210438 :                                 break;
     469             : 
     470             :                         case ACL_USER:
     471             :                         case ACL_GROUP:
     472             :                                 not_equiv = 1;
     473             :                                 break;
     474             : 
     475      210438 :                         case ACL_GROUP_OBJ:
     476      210438 :                                 group_obj = pa;
     477      210438 :                                 break;
     478             : 
     479      210438 :                         case ACL_OTHER:
     480      210438 :                                 pa->e_perm &= mode | ~S_IRWXO;
     481      210438 :                                 mode &= pa->e_perm | ~S_IRWXO;
     482      210438 :                                 break;
     483             : 
     484      210386 :                         case ACL_MASK:
     485      210386 :                                 mask_obj = pa;
     486      210386 :                                 not_equiv = 1;
     487      210386 :                                 break;
     488             : 
     489             :                         default:
     490             :                                 return -EIO;
     491             :                 }
     492             :         }
     493             : 
     494      210438 :         if (mask_obj) {
     495      210386 :                 mask_obj->e_perm &= (mode >> 3) | ~S_IRWXO;
     496      210386 :                 mode &= (mask_obj->e_perm << 3) | ~S_IRWXG;
     497             :         } else {
     498          52 :                 if (!group_obj)
     499             :                         return -EIO;
     500          52 :                 group_obj->e_perm &= (mode >> 3) | ~S_IRWXO;
     501          52 :                 mode &= (group_obj->e_perm << 3) | ~S_IRWXG;
     502             :         }
     503             : 
     504      210438 :         *mode_p = (*mode_p & ~S_IRWXUGO) | mode;
     505      210438 :         return not_equiv;
     506             : }
     507             : 
     508             : /*
     509             :  * Modify the ACL for the chmod syscall.
     510             :  */
     511           0 : static int __posix_acl_chmod_masq(struct posix_acl *acl, umode_t mode)
     512             : {
     513           0 :         struct posix_acl_entry *group_obj = NULL, *mask_obj = NULL;
     514           0 :         struct posix_acl_entry *pa, *pe;
     515             : 
     516             :         /* assert(atomic_read(acl->a_refcount) == 1); */
     517             : 
     518           0 :         FOREACH_ACL_ENTRY(pa, acl, pe) {
     519           0 :                 switch(pa->e_tag) {
     520           0 :                         case ACL_USER_OBJ:
     521           0 :                                 pa->e_perm = (mode & S_IRWXU) >> 6;
     522           0 :                                 break;
     523             : 
     524             :                         case ACL_USER:
     525             :                         case ACL_GROUP:
     526             :                                 break;
     527             : 
     528           0 :                         case ACL_GROUP_OBJ:
     529           0 :                                 group_obj = pa;
     530           0 :                                 break;
     531             : 
     532           0 :                         case ACL_MASK:
     533           0 :                                 mask_obj = pa;
     534           0 :                                 break;
     535             : 
     536           0 :                         case ACL_OTHER:
     537           0 :                                 pa->e_perm = (mode & S_IRWXO);
     538           0 :                                 break;
     539             : 
     540             :                         default:
     541             :                                 return -EIO;
     542             :                 }
     543             :         }
     544             : 
     545           0 :         if (mask_obj) {
     546           0 :                 mask_obj->e_perm = (mode & S_IRWXG) >> 3;
     547             :         } else {
     548           0 :                 if (!group_obj)
     549             :                         return -EIO;
     550           0 :                 group_obj->e_perm = (mode & S_IRWXG) >> 3;
     551             :         }
     552             : 
     553             :         return 0;
     554             : }
     555             : 
     556             : int
     557           0 : __posix_acl_create(struct posix_acl **acl, gfp_t gfp, umode_t *mode_p)
     558             : {
     559           0 :         struct posix_acl *clone = posix_acl_clone(*acl, gfp);
     560           0 :         int err = -ENOMEM;
     561           0 :         if (clone) {
     562           0 :                 err = posix_acl_create_masq(clone, mode_p);
     563           0 :                 if (err < 0) {
     564           0 :                         posix_acl_release(clone);
     565           0 :                         clone = NULL;
     566             :                 }
     567             :         }
     568           0 :         posix_acl_release(*acl);
     569           0 :         *acl = clone;
     570           0 :         return err;
     571             : }
     572             : EXPORT_SYMBOL(__posix_acl_create);
     573             : 
     574             : int
     575           0 : __posix_acl_chmod(struct posix_acl **acl, gfp_t gfp, umode_t mode)
     576             : {
     577           0 :         struct posix_acl *clone = posix_acl_clone(*acl, gfp);
     578           0 :         int err = -ENOMEM;
     579           0 :         if (clone) {
     580           0 :                 err = __posix_acl_chmod_masq(clone, mode);
     581           0 :                 if (err) {
     582           0 :                         posix_acl_release(clone);
     583           0 :                         clone = NULL;
     584             :                 }
     585             :         }
     586           0 :         posix_acl_release(*acl);
     587           0 :         *acl = clone;
     588           0 :         return err;
     589             : }
     590             : EXPORT_SYMBOL(__posix_acl_chmod);
     591             : 
     592             : /**
     593             :  * posix_acl_chmod - chmod a posix acl
     594             :  *
     595             :  * @idmap:      idmap of the mount @inode was found from
     596             :  * @dentry:     dentry to check permissions on
     597             :  * @mode:       the new mode of @inode
     598             :  *
     599             :  * If the dentry has been found through an idmapped mount the idmap of
     600             :  * the vfsmount must be passed through @idmap. This function will then
     601             :  * take care to map the inode according to @idmap before checking
     602             :  * permissions. On non-idmapped mounts or if permission checking is to be
     603             :  * performed on the raw inode simply passs @nop_mnt_idmap.
     604             :  */
     605             : int
     606     1206721 :  posix_acl_chmod(struct mnt_idmap *idmap, struct dentry *dentry,
     607             :                     umode_t mode)
     608             : {
     609     1206721 :         struct inode *inode = d_inode(dentry);
     610     1206721 :         struct posix_acl *acl;
     611     1206721 :         int ret = 0;
     612             : 
     613     1206721 :         if (!IS_POSIXACL(inode))
     614             :                 return 0;
     615     1206715 :         if (!inode->i_op->set_acl)
     616             :                 return -EOPNOTSUPP;
     617             : 
     618     1206715 :         acl = get_inode_acl(inode, ACL_TYPE_ACCESS);
     619     1206515 :         if (IS_ERR_OR_NULL(acl)) {
     620     1206592 :                 if (acl == ERR_PTR(-EOPNOTSUPP))
     621             :                         return 0;
     622     1206592 :                 return PTR_ERR(acl);
     623             :         }
     624             : 
     625           0 :         ret = __posix_acl_chmod(&acl, GFP_KERNEL, mode);
     626           0 :         if (ret)
     627             :                 return ret;
     628           0 :         ret = inode->i_op->set_acl(idmap, dentry, acl, ACL_TYPE_ACCESS);
     629           0 :         posix_acl_release(acl);
     630           0 :         return ret;
     631             : }
     632             : EXPORT_SYMBOL(posix_acl_chmod);
     633             : 
     634             : int
     635    64536930 : posix_acl_create(struct inode *dir, umode_t *mode,
     636             :                 struct posix_acl **default_acl, struct posix_acl **acl)
     637             : {
     638    64536930 :         struct posix_acl *p;
     639    64536930 :         struct posix_acl *clone;
     640    64536930 :         int ret;
     641             : 
     642    64536930 :         *acl = NULL;
     643    64536930 :         *default_acl = NULL;
     644             : 
     645    64536930 :         if (S_ISLNK(*mode) || !IS_POSIXACL(dir))
     646             :                 return 0;
     647             : 
     648    64269232 :         p = get_inode_acl(dir, ACL_TYPE_DEFAULT);
     649    63975273 :         if (!p || p == ERR_PTR(-EOPNOTSUPP)) {
     650    63764835 :                 *mode &= ~current_umask();
     651    63377951 :                 return 0;
     652             :         }
     653      210438 :         if (IS_ERR(p))
     654           0 :                 return PTR_ERR(p);
     655             : 
     656      210438 :         ret = -ENOMEM;
     657      210438 :         clone = posix_acl_clone(p, GFP_NOFS);
     658      210438 :         if (!clone)
     659           0 :                 goto err_release;
     660             : 
     661      210438 :         ret = posix_acl_create_masq(clone, mode);
     662      210438 :         if (ret < 0)
     663           0 :                 goto err_release_clone;
     664             : 
     665      210438 :         if (ret == 0)
     666          52 :                 posix_acl_release(clone);
     667             :         else
     668      210386 :                 *acl = clone;
     669             : 
     670      210438 :         if (!S_ISDIR(*mode))
     671      190214 :                 posix_acl_release(p);
     672             :         else
     673       20224 :                 *default_acl = p;
     674             : 
     675             :         return 0;
     676             : 
     677             : err_release_clone:
     678           0 :         posix_acl_release(clone);
     679           0 : err_release:
     680           0 :         posix_acl_release(p);
     681           0 :         return ret;
     682             : }
     683             : EXPORT_SYMBOL_GPL(posix_acl_create);
     684             : 
     685             : /**
     686             :  * posix_acl_update_mode  -  update mode in set_acl
     687             :  * @idmap:      idmap of the mount @inode was found from
     688             :  * @inode:      target inode
     689             :  * @mode_p:     mode (pointer) for update
     690             :  * @acl:        acl pointer
     691             :  *
     692             :  * Update the file mode when setting an ACL: compute the new file permission
     693             :  * bits based on the ACL.  In addition, if the ACL is equivalent to the new
     694             :  * file mode, set *@acl to NULL to indicate that no ACL should be set.
     695             :  *
     696             :  * As with chmod, clear the setgid bit if the caller is not in the owning group
     697             :  * or capable of CAP_FSETID (see inode_change_ok).
     698             :  *
     699             :  * If the inode has been found through an idmapped mount the idmap of
     700             :  * the vfsmount must be passed through @idmap. This function will then
     701             :  * take care to map the inode according to @idmap before checking
     702             :  * permissions. On non-idmapped mounts or if permission checking is to be
     703             :  * performed on the raw inode simply passs @nop_mnt_idmap.
     704             :  *
     705             :  * Called from set_acl inode operations.
     706             :  */
     707    11803515 : int posix_acl_update_mode(struct mnt_idmap *idmap,
     708             :                           struct inode *inode, umode_t *mode_p,
     709             :                           struct posix_acl **acl)
     710             : {
     711    11803515 :         umode_t mode = inode->i_mode;
     712    11803515 :         int error;
     713             : 
     714    11803515 :         error = posix_acl_equiv_mode(*acl, &mode);
     715    11766113 :         if (error < 0)
     716             :                 return error;
     717    11766113 :         if (error == 0)
     718    11767125 :                 *acl = NULL;
     719    23469005 :         if (!vfsgid_in_group_p(i_gid_into_vfsgid(idmap, inode)) &&
     720    11719444 :             !capable_wrt_inode_uidgid(idmap, inode, CAP_FSETID))
     721          26 :                 mode &= ~S_ISGID;
     722    11803456 :         *mode_p = mode;
     723    11803456 :         return 0;
     724             : }
     725             : EXPORT_SYMBOL(posix_acl_update_mode);
     726             : 
     727             : /*
     728             :  * Fix up the uids and gids in posix acl extended attributes in place.
     729             :  */
     730    11851457 : static int posix_acl_fix_xattr_common(const void *value, size_t size)
     731             : {
     732    11851457 :         const struct posix_acl_xattr_header *header = value;
     733    11851457 :         int count;
     734             : 
     735    11851457 :         if (!header)
     736             :                 return -EINVAL;
     737    11851457 :         if (size < sizeof(struct posix_acl_xattr_header))
     738             :                 return -EINVAL;
     739    11851457 :         if (header->a_version != cpu_to_le32(POSIX_ACL_XATTR_VERSION))
     740             :                 return -EOPNOTSUPP;
     741             : 
     742    11851457 :         count = posix_acl_xattr_count(size);
     743    11851457 :         if (count < 0)
     744             :                 return -EINVAL;
     745    11851457 :         if (count == 0)
     746           0 :                 return 0;
     747             : 
     748             :         return count;
     749             : }
     750             : 
     751             : /**
     752             :  * posix_acl_from_xattr - convert POSIX ACLs from backing store to VFS format
     753             :  * @userns: the filesystem's idmapping
     754             :  * @value: the uapi representation of POSIX ACLs
     755             :  * @size: the size of @void
     756             :  *
     757             :  * Filesystems that store POSIX ACLs in the unaltered uapi format should use
     758             :  * posix_acl_from_xattr() when reading them from the backing store and
     759             :  * converting them into the struct posix_acl VFS format. The helper is
     760             :  * specifically intended to be called from the acl inode operation.
     761             :  *
     762             :  * The posix_acl_from_xattr() function will map the raw {g,u}id values stored
     763             :  * in ACL_{GROUP,USER} entries into idmapping in @userns.
     764             :  *
     765             :  * Note that posix_acl_from_xattr() does not take idmapped mounts into account.
     766             :  * If it did it calling it from the get acl inode operation would return POSIX
     767             :  * ACLs mapped according to an idmapped mount which would mean that the value
     768             :  * couldn't be cached for the filesystem. Idmapped mounts are taken into
     769             :  * account on the fly during permission checking or right at the VFS -
     770             :  * userspace boundary before reporting them to the user.
     771             :  *
     772             :  * Return: Allocated struct posix_acl on success, NULL for a valid header but
     773             :  *         without actual POSIX ACL entries, or ERR_PTR() encoded error code.
     774             :  */
     775    11838072 : struct posix_acl *posix_acl_from_xattr(struct user_namespace *userns,
     776             :                                        const void *value, size_t size)
     777             : {
     778    11838072 :         const struct posix_acl_xattr_header *header = value;
     779    11838072 :         const struct posix_acl_xattr_entry *entry = (const void *)(header + 1), *end;
     780    11838072 :         int count;
     781    11838072 :         struct posix_acl *acl;
     782    11838072 :         struct posix_acl_entry *acl_e;
     783             : 
     784    11838072 :         count = posix_acl_fix_xattr_common(value, size);
     785    11838072 :         if (count < 0)
     786           0 :                 return ERR_PTR(count);
     787    11838072 :         if (count == 0)
     788             :                 return NULL;
     789             :         
     790    11838072 :         acl = posix_acl_alloc(count, GFP_NOFS);
     791    11846892 :         if (!acl)
     792             :                 return ERR_PTR(-ENOMEM);
     793    11846892 :         acl_e = acl->a_entries;
     794             :         
     795    47510328 :         for (end = entry + count; entry != end; acl_e++, entry++) {
     796    35663436 :                 acl_e->e_tag  = le16_to_cpu(entry->e_tag);
     797    35663436 :                 acl_e->e_perm = le16_to_cpu(entry->e_perm);
     798             : 
     799    35663436 :                 switch(acl_e->e_tag) {
     800             :                         case ACL_USER_OBJ:
     801             :                         case ACL_GROUP_OBJ:
     802             :                         case ACL_MASK:
     803             :                         case ACL_OTHER:
     804             :                                 break;
     805             : 
     806      181382 :                         case ACL_USER:
     807      181382 :                                 acl_e->e_uid = make_kuid(userns,
     808      181382 :                                                 le32_to_cpu(entry->e_id));
     809      181382 :                                 if (!uid_valid(acl_e->e_uid))
     810           0 :                                         goto fail;
     811             :                                 break;
     812          67 :                         case ACL_GROUP:
     813          67 :                                 acl_e->e_gid = make_kgid(userns,
     814          67 :                                                 le32_to_cpu(entry->e_id));
     815          67 :                                 if (!gid_valid(acl_e->e_gid))
     816           0 :                                         goto fail;
     817             :                                 break;
     818             : 
     819           0 :                         default:
     820           0 :                                 goto fail;
     821             :                 }
     822             :         }
     823             :         return acl;
     824             : 
     825           0 : fail:
     826           0 :         posix_acl_release(acl);
     827           0 :         return ERR_PTR(-EINVAL);
     828             : }
     829             : EXPORT_SYMBOL (posix_acl_from_xattr);
     830             : 
     831             : /*
     832             :  * Convert from in-memory to extended attribute representation.
     833             :  */
     834             : int
     835       34701 : posix_acl_to_xattr(struct user_namespace *user_ns, const struct posix_acl *acl,
     836             :                    void *buffer, size_t size)
     837             : {
     838       34701 :         struct posix_acl_xattr_header *ext_acl = buffer;
     839       34701 :         struct posix_acl_xattr_entry *ext_entry;
     840       34701 :         int real_size, n;
     841             : 
     842       34701 :         real_size = posix_acl_xattr_size(acl->a_count);
     843       34701 :         if (!buffer)
     844             :                 return real_size;
     845       34701 :         if (real_size > size)
     846             :                 return -ERANGE;
     847             : 
     848       34701 :         ext_entry = (void *)(ext_acl + 1);
     849       34701 :         ext_acl->a_version = cpu_to_le32(POSIX_ACL_XATTR_VERSION);
     850             : 
     851      208157 :         for (n=0; n < acl->a_count; n++, ext_entry++) {
     852      173456 :                 const struct posix_acl_entry *acl_e = &acl->a_entries[n];
     853      173456 :                 ext_entry->e_tag  = cpu_to_le16(acl_e->e_tag);
     854      173456 :                 ext_entry->e_perm = cpu_to_le16(acl_e->e_perm);
     855      173456 :                 switch(acl_e->e_tag) {
     856       34651 :                 case ACL_USER:
     857       69302 :                         ext_entry->e_id =
     858       34651 :                                 cpu_to_le32(from_kuid(user_ns, acl_e->e_uid));
     859       34651 :                         break;
     860           5 :                 case ACL_GROUP:
     861          10 :                         ext_entry->e_id =
     862           5 :                                 cpu_to_le32(from_kgid(user_ns, acl_e->e_gid));
     863           5 :                         break;
     864      138800 :                 default:
     865      138800 :                         ext_entry->e_id = cpu_to_le32(ACL_UNDEFINED_ID);
     866      138800 :                         break;
     867             :                 }
     868             :         }
     869             :         return real_size;
     870             : }
     871             : EXPORT_SYMBOL (posix_acl_to_xattr);
     872             : 
     873             : /**
     874             :  * vfs_posix_acl_to_xattr - convert from kernel to userspace representation
     875             :  * @idmap: idmap of the mount
     876             :  * @inode: inode the posix acls are set on
     877             :  * @acl: the posix acls as represented by the vfs
     878             :  * @buffer: the buffer into which to convert @acl
     879             :  * @size: size of @buffer
     880             :  *
     881             :  * This converts @acl from the VFS representation in the filesystem idmapping
     882             :  * to the uapi form reportable to userspace. And mount and caller idmappings
     883             :  * are handled appropriately.
     884             :  *
     885             :  * Return: On success, the size of the stored uapi posix acls, on error a
     886             :  * negative errno.
     887             :  */
     888         842 : static ssize_t vfs_posix_acl_to_xattr(struct mnt_idmap *idmap,
     889             :                                       struct inode *inode,
     890             :                                       const struct posix_acl *acl, void *buffer,
     891             :                                       size_t size)
     892             : 
     893             : {
     894         842 :         struct posix_acl_xattr_header *ext_acl = buffer;
     895         842 :         struct posix_acl_xattr_entry *ext_entry;
     896         842 :         struct user_namespace *fs_userns, *caller_userns;
     897         842 :         ssize_t real_size, n;
     898         842 :         vfsuid_t vfsuid;
     899         842 :         vfsgid_t vfsgid;
     900             : 
     901         842 :         real_size = posix_acl_xattr_size(acl->a_count);
     902         842 :         if (!buffer)
     903             :                 return real_size;
     904         677 :         if (real_size > size)
     905             :                 return -ERANGE;
     906             : 
     907         512 :         ext_entry = (void *)(ext_acl + 1);
     908         512 :         ext_acl->a_version = cpu_to_le32(POSIX_ACL_XATTR_VERSION);
     909             : 
     910         512 :         fs_userns = i_user_ns(inode);
     911         512 :         caller_userns = current_user_ns();
     912      364814 :         for (n=0; n < acl->a_count; n++, ext_entry++) {
     913      364302 :                 const struct posix_acl_entry *acl_e = &acl->a_entries[n];
     914      364302 :                 ext_entry->e_tag  = cpu_to_le16(acl_e->e_tag);
     915      364302 :                 ext_entry->e_perm = cpu_to_le16(acl_e->e_perm);
     916      364302 :                 switch(acl_e->e_tag) {
     917      362189 :                 case ACL_USER:
     918      362189 :                         vfsuid = make_vfsuid(idmap, fs_userns, acl_e->e_uid);
     919      362189 :                         ext_entry->e_id = cpu_to_le32(from_kuid(
     920             :                                 caller_userns, vfsuid_into_kuid(vfsuid)));
     921      362189 :                         break;
     922         117 :                 case ACL_GROUP:
     923         117 :                         vfsgid = make_vfsgid(idmap, fs_userns, acl_e->e_gid);
     924         117 :                         ext_entry->e_id = cpu_to_le32(from_kgid(
     925             :                                 caller_userns, vfsgid_into_kgid(vfsgid)));
     926         117 :                         break;
     927        1996 :                 default:
     928        1996 :                         ext_entry->e_id = cpu_to_le32(ACL_UNDEFINED_ID);
     929        1996 :                         break;
     930             :                 }
     931             :         }
     932             :         return real_size;
     933             : }
     934             : 
     935             : int
     936    12009603 : set_posix_acl(struct mnt_idmap *idmap, struct dentry *dentry,
     937             :               int type, struct posix_acl *acl)
     938             : {
     939    12009603 :         struct inode *inode = d_inode(dentry);
     940             : 
     941    12009603 :         if (!IS_POSIXACL(inode))
     942             :                 return -EOPNOTSUPP;
     943    12009603 :         if (!inode->i_op->set_acl)
     944             :                 return -EOPNOTSUPP;
     945             : 
     946    12004525 :         if (type == ACL_TYPE_DEFAULT && !S_ISDIR(inode->i_mode))
     947           0 :                 return acl ? -EACCES : 0;
     948    12004525 :         if (!inode_owner_or_capable(idmap, inode))
     949             :                 return -EPERM;
     950             : 
     951    11944172 :         if (acl) {
     952    11773404 :                 int ret = posix_acl_valid(inode->i_sb->s_user_ns, acl);
     953    11746158 :                 if (ret)
     954             :                         return ret;
     955             :         }
     956    11916926 :         return inode->i_op->set_acl(idmap, dentry, acl, type);
     957             : }
     958             : EXPORT_SYMBOL(set_posix_acl);
     959             : 
     960    23559403 : int posix_acl_listxattr(struct inode *inode, char **buffer,
     961             :                         ssize_t *remaining_size)
     962             : {
     963    23559403 :         int err;
     964             : 
     965    23559403 :         if (!IS_POSIXACL(inode))
     966             :                 return 0;
     967             : 
     968    23559403 :         if (inode->i_acl) {
     969           0 :                 err = xattr_list_one(buffer, remaining_size,
     970             :                                      XATTR_NAME_POSIX_ACL_ACCESS);
     971           0 :                 if (err)
     972             :                         return err;
     973             :         }
     974             : 
     975    23559403 :         if (inode->i_default_acl) {
     976           0 :                 err = xattr_list_one(buffer, remaining_size,
     977             :                                      XATTR_NAME_POSIX_ACL_DEFAULT);
     978           0 :                 if (err)
     979           0 :                         return err;
     980             :         }
     981             : 
     982             :         return 0;
     983             : }
     984             : 
     985             : static bool
     986           1 : posix_acl_xattr_list(struct dentry *dentry)
     987             : {
     988           1 :         return IS_POSIXACL(d_backing_inode(dentry));
     989             : }
     990             : 
     991             : /*
     992             :  * nop_posix_acl_access - legacy xattr handler for access POSIX ACLs
     993             :  *
     994             :  * This is the legacy POSIX ACL access xattr handler. It is used by some
     995             :  * filesystems to implement their ->listxattr() inode operation. New code
     996             :  * should never use them.
     997             :  */
     998             : const struct xattr_handler nop_posix_acl_access = {
     999             :         .name = XATTR_NAME_POSIX_ACL_ACCESS,
    1000             :         .list = posix_acl_xattr_list,
    1001             : };
    1002             : EXPORT_SYMBOL_GPL(nop_posix_acl_access);
    1003             : 
    1004             : /*
    1005             :  * nop_posix_acl_default - legacy xattr handler for default POSIX ACLs
    1006             :  *
    1007             :  * This is the legacy POSIX ACL default xattr handler. It is used by some
    1008             :  * filesystems to implement their ->listxattr() inode operation. New code
    1009             :  * should never use them.
    1010             :  */
    1011             : const struct xattr_handler nop_posix_acl_default = {
    1012             :         .name = XATTR_NAME_POSIX_ACL_DEFAULT,
    1013             :         .list = posix_acl_xattr_list,
    1014             : };
    1015             : EXPORT_SYMBOL_GPL(nop_posix_acl_default);
    1016             : 
    1017       18680 : int simple_set_acl(struct mnt_idmap *idmap, struct dentry *dentry,
    1018             :                    struct posix_acl *acl, int type)
    1019             : {
    1020       18680 :         int error;
    1021       18680 :         struct inode *inode = d_inode(dentry);
    1022             : 
    1023       18680 :         if (type == ACL_TYPE_ACCESS) {
    1024       18680 :                 error = posix_acl_update_mode(idmap, inode,
    1025             :                                 &inode->i_mode, &acl);
    1026       18680 :                 if (error)
    1027             :                         return error;
    1028             :         }
    1029             : 
    1030       18680 :         inode->i_ctime = current_time(inode);
    1031       18680 :         if (IS_I_VERSION(inode))
    1032       18658 :                 inode_inc_iversion(inode);
    1033       18680 :         set_cached_acl(inode, type, acl);
    1034       18680 :         return 0;
    1035             : }
    1036             : 
    1037     1858379 : int simple_acl_create(struct inode *dir, struct inode *inode)
    1038             : {
    1039     1858379 :         struct posix_acl *default_acl, *acl;
    1040     1858379 :         int error;
    1041             : 
    1042     1858379 :         error = posix_acl_create(dir, &inode->i_mode, &default_acl, &acl);
    1043     1858377 :         if (error)
    1044             :                 return error;
    1045             : 
    1046     1858377 :         set_cached_acl(inode, ACL_TYPE_DEFAULT, default_acl);
    1047     1858379 :         set_cached_acl(inode, ACL_TYPE_ACCESS, acl);
    1048             : 
    1049     1858379 :         if (default_acl)
    1050           0 :                 posix_acl_release(default_acl);
    1051     1858379 :         if (acl)
    1052          73 :                 posix_acl_release(acl);
    1053             :         return 0;
    1054             : }
    1055             : 
    1056    11776153 : static int vfs_set_acl_idmapped_mnt(struct mnt_idmap *idmap,
    1057             :                                     struct user_namespace *fs_userns,
    1058             :                                     struct posix_acl *acl)
    1059             : {
    1060    47278599 :         for (int n = 0; n < acl->a_count; n++) {
    1061    35477668 :                 struct posix_acl_entry *acl_e = &acl->a_entries[n];
    1062             : 
    1063    35477668 :                 switch (acl_e->e_tag) {
    1064      181379 :                 case ACL_USER:
    1065      181379 :                         acl_e->e_uid = from_vfsuid(idmap, fs_userns,
    1066      181379 :                                                    VFSUIDT_INIT(acl_e->e_uid));
    1067      181379 :                         break;
    1068          65 :                 case ACL_GROUP:
    1069          65 :                         acl_e->e_gid = from_vfsgid(idmap, fs_userns,
    1070          65 :                                                    VFSGIDT_INIT(acl_e->e_gid));
    1071          65 :                         break;
    1072             :                 }
    1073             :         }
    1074             : 
    1075    11800931 :         return 0;
    1076             : }
    1077             : 
    1078             : /**
    1079             :  * vfs_set_acl - set posix acls
    1080             :  * @idmap: idmap of the mount
    1081             :  * @dentry: the dentry based on which to set the posix acls
    1082             :  * @acl_name: the name of the posix acl
    1083             :  * @kacl: the posix acls in the appropriate VFS format
    1084             :  *
    1085             :  * This function sets @kacl. The caller must all posix_acl_release() on @kacl
    1086             :  * afterwards.
    1087             :  *
    1088             :  * Return: On success 0, on error negative errno.
    1089             :  */
    1090    11827685 : int vfs_set_acl(struct mnt_idmap *idmap, struct dentry *dentry,
    1091             :                 const char *acl_name, struct posix_acl *kacl)
    1092             : {
    1093    11827685 :         int acl_type;
    1094    11827685 :         int error;
    1095    11827685 :         struct inode *inode = d_inode(dentry);
    1096    11827685 :         struct inode *delegated_inode = NULL;
    1097             : 
    1098    11827685 :         acl_type = posix_acl_type(acl_name);
    1099    11827685 :         if (acl_type < 0)
    1100             :                 return -EINVAL;
    1101             : 
    1102    11827685 :         if (kacl) {
    1103             :                 /*
    1104             :                  * If we're on an idmapped mount translate from mount specific
    1105             :                  * vfs{g,u}id_t into global filesystem k{g,u}id_t.
    1106             :                  * Afterwards we can cache the POSIX ACLs filesystem wide and -
    1107             :                  * if this is a filesystem with a backing store - ultimately
    1108             :                  * translate them to backing store values.
    1109             :                  */
    1110    11827685 :                 error = vfs_set_acl_idmapped_mnt(idmap, i_user_ns(inode), kacl);
    1111    11793870 :                 if (error)
    1112             :                         return error;
    1113             :         }
    1114             : 
    1115    11793870 : retry_deleg:
    1116    11793870 :         inode_lock(inode);
    1117             : 
    1118             :         /*
    1119             :          * We only care about restrictions the inode struct itself places upon
    1120             :          * us otherwise POSIX ACLs aren't subject to any VFS restrictions.
    1121             :          */
    1122    11844045 :         error = may_write_xattr(idmap, inode);
    1123    11823620 :         if (error)
    1124         104 :                 goto out_inode_unlock;
    1125             : 
    1126    11823516 :         error = security_inode_set_acl(idmap, dentry, acl_name, kacl);
    1127    11823516 :         if (error)
    1128             :                 goto out_inode_unlock;
    1129             : 
    1130    11823516 :         error = try_break_deleg(inode, &delegated_inode);
    1131    11889856 :         if (error)
    1132           0 :                 goto out_inode_unlock;
    1133             : 
    1134    11889856 :         if (likely(!is_bad_inode(inode)))
    1135    11874209 :                 error = set_posix_acl(idmap, dentry, acl_type, kacl);
    1136             :         else
    1137             :                 error = -EIO;
    1138    11896792 :         if (!error) {
    1139    11891677 :                 fsnotify_xattr(dentry);
    1140             :                 evm_inode_post_set_acl(dentry, acl_name, kacl);
    1141             :         }
    1142             : 
    1143        5115 : out_inode_unlock:
    1144    11876299 :         inode_unlock(inode);
    1145             : 
    1146    11848552 :         if (delegated_inode) {
    1147           0 :                 error = break_deleg_wait(&delegated_inode);
    1148           0 :                 if (!error)
    1149           0 :                         goto retry_deleg;
    1150             :         }
    1151             : 
    1152             :         return error;
    1153             : }
    1154             : EXPORT_SYMBOL_GPL(vfs_set_acl);
    1155             : 
    1156             : /**
    1157             :  * vfs_get_acl - get posix acls
    1158             :  * @idmap: idmap of the mount
    1159             :  * @dentry: the dentry based on which to retrieve the posix acls
    1160             :  * @acl_name: the name of the posix acl
    1161             :  *
    1162             :  * This function retrieves @kacl from the filesystem. The caller must all
    1163             :  * posix_acl_release() on @kacl.
    1164             :  *
    1165             :  * Return: On success POSIX ACLs in VFS format, on error negative errno.
    1166             :  */
    1167    12050016 : struct posix_acl *vfs_get_acl(struct mnt_idmap *idmap,
    1168             :                               struct dentry *dentry, const char *acl_name)
    1169             : {
    1170    12050016 :         struct inode *inode = d_inode(dentry);
    1171    12050016 :         struct posix_acl *acl;
    1172    12050016 :         int acl_type, error;
    1173             : 
    1174    12050016 :         acl_type = posix_acl_type(acl_name);
    1175    12050016 :         if (acl_type < 0)
    1176             :                 return ERR_PTR(-EINVAL);
    1177             : 
    1178             :         /*
    1179             :          * The VFS has no restrictions on reading POSIX ACLs so calling
    1180             :          * something like xattr_permission() isn't needed. Only LSMs get a say.
    1181             :          */
    1182    12050016 :         error = security_inode_get_acl(idmap, dentry, acl_name);
    1183    12050016 :         if (error)
    1184             :                 return ERR_PTR(error);
    1185             : 
    1186    12050016 :         if (!IS_POSIXACL(inode))
    1187             :                 return ERR_PTR(-EOPNOTSUPP);
    1188    12044938 :         if (S_ISLNK(inode->i_mode))
    1189             :                 return ERR_PTR(-EOPNOTSUPP);
    1190             : 
    1191    12044938 :         acl = __get_acl(idmap, dentry, inode, acl_type);
    1192    12028270 :         if (IS_ERR(acl))
    1193             :                 return acl;
    1194    12028248 :         if (!acl)
    1195    12051545 :                 return ERR_PTR(-ENODATA);
    1196             : 
    1197             :         return acl;
    1198             : }
    1199             : EXPORT_SYMBOL_GPL(vfs_get_acl);
    1200             : 
    1201             : /**
    1202             :  * vfs_remove_acl - remove posix acls
    1203             :  * @idmap: idmap of the mount
    1204             :  * @dentry: the dentry based on which to retrieve the posix acls
    1205             :  * @acl_name: the name of the posix acl
    1206             :  *
    1207             :  * This function removes posix acls.
    1208             :  *
    1209             :  * Return: On success 0, on error negative errno.
    1210             :  */
    1211      170741 : int vfs_remove_acl(struct mnt_idmap *idmap, struct dentry *dentry,
    1212             :                    const char *acl_name)
    1213             : {
    1214      170741 :         int acl_type;
    1215      170741 :         int error;
    1216      170741 :         struct inode *inode = d_inode(dentry);
    1217      170741 :         struct inode *delegated_inode = NULL;
    1218             : 
    1219      170741 :         acl_type = posix_acl_type(acl_name);
    1220      170741 :         if (acl_type < 0)
    1221             :                 return -EINVAL;
    1222             : 
    1223      170741 : retry_deleg:
    1224      170741 :         inode_lock(inode);
    1225             : 
    1226             :         /*
    1227             :          * We only care about restrictions the inode struct itself places upon
    1228             :          * us otherwise POSIX ACLs aren't subject to any VFS restrictions.
    1229             :          */
    1230      170751 :         error = may_write_xattr(idmap, inode);
    1231      170762 :         if (error)
    1232           0 :                 goto out_inode_unlock;
    1233             : 
    1234      170762 :         error = security_inode_remove_acl(idmap, dentry, acl_name);
    1235      170762 :         if (error)
    1236             :                 goto out_inode_unlock;
    1237             : 
    1238      170762 :         error = try_break_deleg(inode, &delegated_inode);
    1239      170767 :         if (error)
    1240           0 :                 goto out_inode_unlock;
    1241             : 
    1242      170767 :         if (likely(!is_bad_inode(inode)))
    1243      170763 :                 error = set_posix_acl(idmap, dentry, acl_type, NULL);
    1244             :         else
    1245             :                 error = -EIO;
    1246      170767 :         if (!error) {
    1247      170767 :                 fsnotify_xattr(dentry);
    1248             :                 evm_inode_post_remove_acl(idmap, dentry, acl_name);
    1249             :         }
    1250             : 
    1251           0 : out_inode_unlock:
    1252      170767 :         inode_unlock(inode);
    1253             : 
    1254      170766 :         if (delegated_inode) {
    1255           0 :                 error = break_deleg_wait(&delegated_inode);
    1256           0 :                 if (!error)
    1257           0 :                         goto retry_deleg;
    1258             :         }
    1259             : 
    1260             :         return error;
    1261             : }
    1262             : EXPORT_SYMBOL_GPL(vfs_remove_acl);
    1263             : 
    1264    11851530 : int do_set_acl(struct mnt_idmap *idmap, struct dentry *dentry,
    1265             :                const char *acl_name, const void *kvalue, size_t size)
    1266             : {
    1267    11851530 :         int error;
    1268    11851530 :         struct posix_acl *acl = NULL;
    1269             : 
    1270    11851530 :         if (size) {
    1271             :                 /*
    1272             :                  * Note that posix_acl_from_xattr() uses GFP_NOFS when it
    1273             :                  * probably doesn't need to here.
    1274             :                  */
    1275    11833799 :                 acl = posix_acl_from_xattr(current_user_ns(), kvalue, size);
    1276    11828602 :                 if (IS_ERR(acl))
    1277           0 :                         return PTR_ERR(acl);
    1278             :         }
    1279             : 
    1280    11846333 :         error = vfs_set_acl(idmap, dentry, acl_name, acl);
    1281    11879740 :         posix_acl_release(acl);
    1282    11879740 :         return error;
    1283             : }
    1284             : 
    1285    12096648 : ssize_t do_get_acl(struct mnt_idmap *idmap, struct dentry *dentry,
    1286             :                    const char *acl_name, void *kvalue, size_t size)
    1287             : {
    1288    12096648 :         ssize_t error;
    1289    12096648 :         struct posix_acl *acl;
    1290             : 
    1291    12096648 :         acl = vfs_get_acl(idmap, dentry, acl_name);
    1292    12020793 :         if (IS_ERR(acl))
    1293    12019951 :                 return PTR_ERR(acl);
    1294             : 
    1295         842 :         error = vfs_posix_acl_to_xattr(idmap, d_inode(dentry),
    1296             :                                        acl, kvalue, size);
    1297         842 :         posix_acl_release(acl);
    1298         842 :         return error;
    1299             : }

Generated by: LCOV version 1.14