LCOV - code coverage report
Current view: top level - fs - posix_acl.c (source / functions) Hit Total Coverage
Test: fstests of 6.5.0-rc3-achx @ Mon Jul 31 20:08:12 PDT 2023 Lines: 457 559 81.8 %
Date: 2023-07-31 20:08:12 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  8578736591 :         switch (type) {
      38  8482602161 :         case ACL_TYPE_ACCESS:
      39  8482602161 :                 return &inode->i_acl;
      40    96134430 :         case ACL_TYPE_DEFAULT:
      41    96134430 :                 return &inode->i_default_acl;
      42           0 :         default:
      43   342287859 :                 BUG();
      44             :         }
      45             : }
      46             : 
      47   342287859 : struct posix_acl *get_cached_acl(struct inode *inode, int type)
      48             : {
      49   342287859 :         struct posix_acl **p = acl_by_type(inode, type);
      50   342287859 :         struct posix_acl *acl;
      51             : 
      52   342287859 :         for (;;) {
      53   342287859 :                 rcu_read_lock();
      54   342163052 :                 acl = rcu_dereference(*p);
      55   342379895 :                 if (!acl || is_uncached_acl(acl) ||
      56      216843 :                     refcount_inc_not_zero(&acl->a_refcount))
      57             :                         break;
      58           0 :                 rcu_read_unlock();
      59           0 :                 cpu_relax();
      60             :         }
      61   342163052 :         rcu_read_unlock();
      62   342267898 :         return acl;
      63             : }
      64             : EXPORT_SYMBOL(get_cached_acl);
      65             : 
      66  8203678695 : struct posix_acl *get_cached_acl_rcu(struct inode *inode, int type)
      67             : {
      68  8203678695 :         struct posix_acl *acl = rcu_dereference(*acl_by_type(inode, type));
      69             : 
      70  8203678695 :         if (acl == ACL_DONT_CACHE) {
      71     1711335 :                 struct posix_acl *ret;
      72             : 
      73     1711335 :                 ret = inode->i_op->get_inode_acl(inode, type, LOOKUP_RCU);
      74     1711348 :                 if (!IS_ERR(ret))
      75     1710863 :                         acl = ret;
      76             :         }
      77             : 
      78  8203678708 :         return acl;
      79             : }
      80             : EXPORT_SYMBOL(get_cached_acl_rcu);
      81             : 
      82    15771192 : void set_cached_acl(struct inode *inode, int type, struct posix_acl *acl)
      83             : {
      84    15771192 :         struct posix_acl **p = acl_by_type(inode, type);
      85    15771192 :         struct posix_acl *old;
      86             : 
      87    15995700 :         old = xchg(p, posix_acl_dup(acl));
      88    15881814 :         if (!is_uncached_acl(old))
      89     6427738 :                 posix_acl_release(old);
      90    15881728 : }
      91             : EXPORT_SYMBOL(set_cached_acl);
      92             : 
      93     4365224 : static void __forget_cached_acl(struct posix_acl **p)
      94             : {
      95     4365224 :         struct posix_acl *old;
      96             : 
      97     4365224 :         old = xchg(p, ACL_NOT_CACHED);
      98     4365296 :         if (!is_uncached_acl(old))
      99       31106 :                 posix_acl_release(old);
     100     4365296 : }
     101             : 
     102     4365237 : void forget_cached_acl(struct inode *inode, int type)
     103             : {
     104     8730474 :         __forget_cached_acl(acl_by_type(inode, type));
     105     4365302 : }
     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   342482062 : static struct posix_acl *__get_acl(struct mnt_idmap *idmap,
     116             :                                    struct dentry *dentry, struct inode *inode,
     117             :                                    int type)
     118             : {
     119   342482062 :         struct posix_acl *sentinel;
     120   342482062 :         struct posix_acl **p;
     121   342482062 :         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   342482062 :         acl = get_cached_acl(inode, type);
     130   342112749 :         if (!is_uncached_acl(acl))
     131             :                 return acl;
     132             : 
     133    12633608 :         if (!IS_POSIXACL(inode))
     134             :                 return NULL;
     135             : 
     136    12633608 :         sentinel = uncached_acl_sentinel(current);
     137    12633608 :         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    12633608 :         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    12634603 :         if (dentry && inode->i_op->get_acl) {
     158          22 :                 acl = inode->i_op->get_acl(idmap, dentry, type);
     159    12634581 :         } else if (inode->i_op->get_inode_acl) {
     160    12631474 :                 acl = inode->i_op->get_inode_acl(inode, type, false);
     161             :         } else {
     162        3107 :                 set_cached_acl(inode, type, NULL);
     163        3107 :                 return NULL;
     164             :         }
     165    12630605 :         if (IS_ERR(acl)) {
     166             :                 /*
     167             :                  * Remove our sentinel so that we don't block future attempts
     168             :                  * to cache the ACL.
     169             :                  */
     170         236 :                 cmpxchg(p, sentinel, ACL_NOT_CACHED);
     171         236 :                 return acl;
     172             :         }
     173             : 
     174             :         /*
     175             :          * Cache the result, but only if our sentinel is still in place.
     176             :          */
     177    12630369 :         posix_acl_dup(acl);
     178    12629892 :         if (unlikely(!try_cmpxchg(p, &sentinel, acl)))
     179      960293 :                 posix_acl_release(acl);
     180             :         return acl;
     181             : }
     182             : 
     183   247956847 : struct posix_acl *get_inode_acl(struct inode *inode, int type)
     184             : {
     185   247956847 :         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    11880974 :         refcount_set(&acl->a_refcount, 1);
     196    11880974 :         acl->a_count = count;
     197    11880974 : }
     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    11822035 : posix_acl_alloc(int count, gfp_t flags)
     205             : {
     206    11822035 :         const size_t size = sizeof(struct posix_acl) +
     207             :                             count * sizeof(struct posix_acl_entry);
     208    11822035 :         struct posix_acl *acl = kmalloc(size, flags);
     209    11880974 :         if (acl)
     210    11880974 :                 posix_acl_init(acl, count);
     211    11880974 :         return acl;
     212             : }
     213             : EXPORT_SYMBOL(posix_acl_alloc);
     214             : 
     215             : /*
     216             :  * Clone an ACL.
     217             :  */
     218             : struct posix_acl *
     219      212290 : posix_acl_clone(const struct posix_acl *acl, gfp_t flags)
     220             : {
     221      212290 :         struct posix_acl *clone = NULL;
     222             : 
     223      212290 :         if (acl) {
     224      212290 :                 int size = sizeof(struct posix_acl) + acl->a_count *
     225             :                            sizeof(struct posix_acl_entry);
     226      212290 :                 clone = kmemdup(acl, size, flags);
     227      212290 :                 if (clone)
     228      212290 :                         refcount_set(&clone->a_refcount, 1);
     229             :         }
     230      212290 :         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    11774584 : posix_acl_valid(struct user_namespace *user_ns, const struct posix_acl *acl)
     239             : {
     240    11774584 :         const struct posix_acl_entry *pa, *pe;
     241    11774584 :         int state = ACL_USER_OBJ;
     242    11774584 :         int needs_mask = 0;
     243             : 
     244    47162745 :         FOREACH_ACL_ENTRY(pa, acl, pe) {
     245    35435739 :                 if (pa->e_perm & ~(ACL_READ|ACL_WRITE|ACL_EXECUTE))
     246             :                         return -EINVAL;
     247    35435739 :                 switch (pa->e_tag) {
     248    11738341 :                         case ACL_USER_OBJ:
     249    11738341 :                                 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    11742057 :                         case ACL_GROUP_OBJ:
     264    11742057 :                                 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    11725897 :                         case ACL_OTHER:
     285    11725897 :                                 if (state == ACL_OTHER ||
     286    11725423 :                                     (state == ACL_GROUP && !needs_mask)) {
     287             :                                         state = 0;
     288             :                                         break;
     289             :                                 }
     290             :                                 return -EINVAL;
     291             : 
     292             :                         default:
     293             :                                 return -EINVAL;
     294             :                 }
     295             :         }
     296    11727006 :         if (state == 0)
     297    11727006 :                 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    11789711 : posix_acl_equiv_mode(const struct posix_acl *acl, umode_t *mode_p)
     308             : {
     309    11789711 :         const struct posix_acl_entry *pa, *pe;
     310    11789711 :         umode_t mode = 0;
     311    11789711 :         int not_equiv = 0;
     312             : 
     313             :         /*
     314             :          * A null ACL can always be presented as mode bits.
     315             :          */
     316    11789711 :         if (!acl)
     317             :                 return 0;
     318             : 
     319    47118794 :         FOREACH_ACL_ENTRY(pa, acl, pe) {
     320    35352064 :                 switch (pa->e_tag) {
     321    11748007 :                         case ACL_USER_OBJ:
     322    11748007 :                                 mode |= (pa->e_perm & S_IRWXO) << 6;
     323    11748007 :                                 break;
     324    11729268 :                         case ACL_GROUP_OBJ:
     325    11729268 :                                 mode |= (pa->e_perm & S_IRWXO) << 3;
     326    11729268 :                                 break;
     327    11730506 :                         case ACL_OTHER:
     328    11730506 :                                 mode |= pa->e_perm & S_IRWXO;
     329    11730506 :                                 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    11766730 :         if (mode_p)
     344    11766730 :                 *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        1282 : posix_acl_permission(struct mnt_idmap *idmap, struct inode *inode,
     377             :                      const struct posix_acl *acl, int want)
     378             : {
     379        1282 :         const struct posix_acl_entry *pa, *pe, *mask_obj;
     380        1282 :         struct user_namespace *fs_userns = i_user_ns(inode);
     381        1282 :         int found = 0;
     382        1282 :         vfsuid_t vfsuid;
     383        1282 :         vfsgid_t vfsgid;
     384             : 
     385        1282 :         want &= MAY_READ | MAY_WRITE | MAY_EXEC;
     386             : 
     387        3790 :         FOREACH_ACL_ENTRY(pa, acl, pe) {
     388        3790 :                 switch(pa->e_tag) {
     389             :                         case ACL_USER_OBJ:
     390             :                                 /* (May have been checked already) */
     391        1282 :                                 vfsuid = i_uid_into_vfsuid(idmap, inode);
     392        2551 :                                 if (vfsuid_eq_kuid(vfsuid, current_fsuid()))
     393           0 :                                         goto check_perm;
     394             :                                 break;
     395        1204 :                         case ACL_USER:
     396        1204 :                                 vfsuid = make_vfsuid(idmap, fs_userns,
     397             :                                                      pa->e_uid);
     398        2408 :                                 if (vfsuid_eq_kuid(vfsuid, current_fsuid()))
     399         830 :                                         goto mask;
     400             :                                 break;
     401             :                         case ACL_GROUP_OBJ:
     402         452 :                                 vfsgid = i_gid_into_vfsgid(idmap, inode);
     403         452 :                                 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         387 :                         case ACL_OTHER:
     421         387 :                                 if (found)
     422             :                                         return -EACCES;
     423             :                                 else
     424         320 :                                         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         320 :         if ((pa->e_perm & want) == want)
     442         294 :                 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      212290 : static int posix_acl_create_masq(struct posix_acl *acl, umode_t *mode_p)
     455             : {
     456      212290 :         struct posix_acl_entry *pa, *pe;
     457      212290 :         struct posix_acl_entry *group_obj = NULL, *mask_obj = NULL;
     458      212290 :         umode_t mode = *mode_p;
     459      212290 :         int not_equiv = 0;
     460             : 
     461             :         /* assert(atomic_read(acl->a_refcount) == 1); */
     462             : 
     463     1273246 :         FOREACH_ACL_ENTRY(pa, acl, pe) {
     464     1060956 :                 switch(pa->e_tag) {
     465      212290 :                         case ACL_USER_OBJ:
     466      212290 :                                 pa->e_perm &= (mode >> 6) | ~S_IRWXO;
     467      212290 :                                 mode &= (pa->e_perm << 6) | ~S_IRWXU;
     468      212290 :                                 break;
     469             : 
     470             :                         case ACL_USER:
     471             :                         case ACL_GROUP:
     472             :                                 not_equiv = 1;
     473             :                                 break;
     474             : 
     475      212290 :                         case ACL_GROUP_OBJ:
     476      212290 :                                 group_obj = pa;
     477      212290 :                                 break;
     478             : 
     479      212290 :                         case ACL_OTHER:
     480      212290 :                                 pa->e_perm &= mode | ~S_IRWXO;
     481      212290 :                                 mode &= pa->e_perm | ~S_IRWXO;
     482      212290 :                                 break;
     483             : 
     484      212238 :                         case ACL_MASK:
     485      212238 :                                 mask_obj = pa;
     486      212238 :                                 not_equiv = 1;
     487      212238 :                                 break;
     488             : 
     489             :                         default:
     490             :                                 return -EIO;
     491             :                 }
     492             :         }
     493             : 
     494      212290 :         if (mask_obj) {
     495      212238 :                 mask_obj->e_perm &= (mode >> 3) | ~S_IRWXO;
     496      212238 :                 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      212290 :         *mode_p = (*mode_p & ~S_IRWXUGO) | mode;
     505      212290 :         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     1614930 :  posix_acl_chmod(struct mnt_idmap *idmap, struct dentry *dentry,
     607             :                     umode_t mode)
     608             : {
     609     1614930 :         struct inode *inode = d_inode(dentry);
     610     1614930 :         struct posix_acl *acl;
     611     1614930 :         int ret = 0;
     612             : 
     613     1614930 :         if (!IS_POSIXACL(inode))
     614             :                 return 0;
     615     1614924 :         if (!inode->i_op->set_acl)
     616             :                 return -EOPNOTSUPP;
     617             : 
     618     1614924 :         acl = get_inode_acl(inode, ACL_TYPE_ACCESS);
     619     1613316 :         if (IS_ERR_OR_NULL(acl)) {
     620     1613220 :                 if (acl == ERR_PTR(-EOPNOTSUPP))
     621             :                         return 0;
     622     1613220 :                 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    81415749 : posix_acl_create(struct inode *dir, umode_t *mode,
     636             :                 struct posix_acl **default_acl, struct posix_acl **acl)
     637             : {
     638    81415749 :         struct posix_acl *p;
     639    81415749 :         struct posix_acl *clone;
     640    81415749 :         int ret;
     641             : 
     642    81415749 :         *acl = NULL;
     643    81415749 :         *default_acl = NULL;
     644             : 
     645    81415749 :         if (S_ISLNK(*mode) || !IS_POSIXACL(dir))
     646             :                 return 0;
     647             : 
     648    81185356 :         p = get_inode_acl(dir, ACL_TYPE_DEFAULT);
     649    80682989 :         if (!p || p == ERR_PTR(-EOPNOTSUPP)) {
     650    80470679 :                 *mode &= ~current_umask();
     651    80116894 :                 return 0;
     652             :         }
     653      212310 :         if (IS_ERR(p))
     654          20 :                 return PTR_ERR(p);
     655             : 
     656      212290 :         ret = -ENOMEM;
     657      212290 :         clone = posix_acl_clone(p, GFP_NOFS);
     658      212290 :         if (!clone)
     659           0 :                 goto err_release;
     660             : 
     661      212290 :         ret = posix_acl_create_masq(clone, mode);
     662      212290 :         if (ret < 0)
     663           0 :                 goto err_release_clone;
     664             : 
     665      212290 :         if (ret == 0)
     666          52 :                 posix_acl_release(clone);
     667             :         else
     668      212238 :                 *acl = clone;
     669             : 
     670      212290 :         if (!S_ISDIR(*mode))
     671      191993 :                 posix_acl_release(p);
     672             :         else
     673       20297 :                 *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    11783095 : int posix_acl_update_mode(struct mnt_idmap *idmap,
     708             :                           struct inode *inode, umode_t *mode_p,
     709             :                           struct posix_acl **acl)
     710             : {
     711    11783095 :         umode_t mode = inode->i_mode;
     712    11783095 :         int error;
     713             : 
     714    11783095 :         error = posix_acl_equiv_mode(*acl, &mode);
     715    11767726 :         if (error < 0)
     716             :                 return error;
     717    11767726 :         if (error == 0)
     718    11768409 :                 *acl = NULL;
     719    23470533 :         if (!vfsgid_in_group_p(i_gid_into_vfsgid(idmap, inode)) &&
     720    11707191 :             !capable_wrt_inode_uidgid(idmap, inode, CAP_FSETID))
     721          26 :                 mode &= ~S_ISGID;
     722    11802695 :         *mode_p = mode;
     723    11802695 :         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    11842876 : static int posix_acl_fix_xattr_common(const void *value, size_t size)
     731             : {
     732    11842876 :         const struct posix_acl_xattr_header *header = value;
     733    11842876 :         int count;
     734             : 
     735    11842876 :         if (!header)
     736             :                 return -EINVAL;
     737    11842876 :         if (size < sizeof(struct posix_acl_xattr_header))
     738             :                 return -EINVAL;
     739    11842876 :         if (header->a_version != cpu_to_le32(POSIX_ACL_XATTR_VERSION))
     740             :                 return -EOPNOTSUPP;
     741             : 
     742    11842876 :         count = posix_acl_xattr_count(size);
     743    11842876 :         if (count < 0)
     744             :                 return -EINVAL;
     745    11842876 :         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    11828758 : struct posix_acl *posix_acl_from_xattr(struct user_namespace *userns,
     776             :                                        const void *value, size_t size)
     777             : {
     778    11828758 :         const struct posix_acl_xattr_header *header = value;
     779    11828758 :         const struct posix_acl_xattr_entry *entry = (const void *)(header + 1), *end;
     780    11828758 :         int count;
     781    11828758 :         struct posix_acl *acl;
     782    11828758 :         struct posix_acl_entry *acl_e;
     783             : 
     784    11828758 :         count = posix_acl_fix_xattr_common(value, size);
     785    11828758 :         if (count < 0)
     786           0 :                 return ERR_PTR(count);
     787    11828758 :         if (count == 0)
     788             :                 return NULL;
     789             :         
     790    11828758 :         acl = posix_acl_alloc(count, GFP_NOFS);
     791    11844079 :         if (!acl)
     792             :                 return ERR_PTR(-ENOMEM);
     793    11844079 :         acl_e = acl->a_entries;
     794             :         
     795    47510756 :         for (end = entry + count; entry != end; acl_e++, entry++) {
     796    35666677 :                 acl_e->e_tag  = le16_to_cpu(entry->e_tag);
     797    35666677 :                 acl_e->e_perm = le16_to_cpu(entry->e_perm);
     798             : 
     799    35666677 :                 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    12016790 : set_posix_acl(struct mnt_idmap *idmap, struct dentry *dentry,
     937             :               int type, struct posix_acl *acl)
     938             : {
     939    12016790 :         struct inode *inode = d_inode(dentry);
     940             : 
     941    12016790 :         if (!IS_POSIXACL(inode))
     942             :                 return -EOPNOTSUPP;
     943    12016790 :         if (!inode->i_op->set_acl)
     944             :                 return -EOPNOTSUPP;
     945             : 
     946    12010976 :         if (type == ACL_TYPE_DEFAULT && !S_ISDIR(inode->i_mode))
     947           0 :                 return acl ? -EACCES : 0;
     948    12010976 :         if (!inode_owner_or_capable(idmap, inode))
     949             :                 return -EPERM;
     950             : 
     951    11960312 :         if (acl) {
     952    11742472 :                 int ret = posix_acl_valid(inode->i_sb->s_user_ns, acl);
     953    11713069 :                 if (ret)
     954             :                         return ret;
     955             :         }
     956    11930909 :         return inode->i_op->set_acl(idmap, dentry, acl, type);
     957             : }
     958             : EXPORT_SYMBOL(set_posix_acl);
     959             : 
     960    23547451 : int posix_acl_listxattr(struct inode *inode, char **buffer,
     961             :                         ssize_t *remaining_size)
     962             : {
     963    23547451 :         int err;
     964             : 
     965    23547451 :         if (!IS_POSIXACL(inode))
     966             :                 return 0;
     967             : 
     968    23547451 :         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    23547451 :         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       19568 : int simple_set_acl(struct mnt_idmap *idmap, struct dentry *dentry,
    1018             :                    struct posix_acl *acl, int type)
    1019             : {
    1020       19568 :         int error;
    1021       19568 :         struct inode *inode = d_inode(dentry);
    1022             : 
    1023       19568 :         if (type == ACL_TYPE_ACCESS) {
    1024       19568 :                 error = posix_acl_update_mode(idmap, inode,
    1025             :                                 &inode->i_mode, &acl);
    1026       19568 :                 if (error)
    1027             :                         return error;
    1028             :         }
    1029             : 
    1030       19568 :         inode->i_ctime = current_time(inode);
    1031       19568 :         if (IS_I_VERSION(inode))
    1032       19546 :                 inode_inc_iversion(inode);
    1033       19568 :         set_cached_acl(inode, type, acl);
    1034       19568 :         return 0;
    1035             : }
    1036             : 
    1037     1762107 : int simple_acl_create(struct inode *dir, struct inode *inode)
    1038             : {
    1039     1762107 :         struct posix_acl *default_acl, *acl;
    1040     1762107 :         int error;
    1041             : 
    1042     1762107 :         error = posix_acl_create(dir, &inode->i_mode, &default_acl, &acl);
    1043     1762105 :         if (error)
    1044             :                 return error;
    1045             : 
    1046     1762105 :         set_cached_acl(inode, ACL_TYPE_DEFAULT, default_acl);
    1047     1762104 :         set_cached_acl(inode, ACL_TYPE_ACCESS, acl);
    1048             : 
    1049     1762106 :         if (default_acl)
    1050           0 :                 posix_acl_release(default_acl);
    1051     1762106 :         if (acl)
    1052          84 :                 posix_acl_release(acl);
    1053             :         return 0;
    1054             : }
    1055             : 
    1056    11767112 : static int vfs_set_acl_idmapped_mnt(struct mnt_idmap *idmap,
    1057             :                                     struct user_namespace *fs_userns,
    1058             :                                     struct posix_acl *acl)
    1059             : {
    1060    47248295 :         for (int n = 0; n < acl->a_count; n++) {
    1061    35418469 :                 struct posix_acl_entry *acl_e = &acl->a_entries[n];
    1062             : 
    1063    35418469 :                 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    11829826 :         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    11827213 : int vfs_set_acl(struct mnt_idmap *idmap, struct dentry *dentry,
    1091             :                 const char *acl_name, struct posix_acl *kacl)
    1092             : {
    1093    11827213 :         int acl_type;
    1094    11827213 :         int error;
    1095    11827213 :         struct inode *inode = d_inode(dentry);
    1096    11827213 :         struct inode *delegated_inode = NULL;
    1097             : 
    1098    11827213 :         acl_type = posix_acl_type(acl_name);
    1099    11827213 :         if (acl_type < 0)
    1100             :                 return -EINVAL;
    1101             : 
    1102    11827213 :         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    11827213 :                 error = vfs_set_acl_idmapped_mnt(idmap, i_user_ns(inode), kacl);
    1111    11793836 :                 if (error)
    1112             :                         return error;
    1113             :         }
    1114             : 
    1115    11793836 : retry_deleg:
    1116    11793836 :         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    11827590 :         error = may_write_xattr(idmap, inode);
    1123    11792528 :         if (error)
    1124         104 :                 goto out_inode_unlock;
    1125             : 
    1126    11792424 :         error = security_inode_set_acl(idmap, dentry, acl_name, kacl);
    1127    11792424 :         if (error)
    1128             :                 goto out_inode_unlock;
    1129             : 
    1130    11792424 :         error = try_break_deleg(inode, &delegated_inode);
    1131    11888647 :         if (error)
    1132           0 :                 goto out_inode_unlock;
    1133             : 
    1134    11888647 :         if (likely(!is_bad_inode(inode)))
    1135    11842455 :                 error = set_posix_acl(idmap, dentry, acl_type, kacl);
    1136             :         else
    1137             :                 error = -EIO;
    1138    11869493 :         if (!error) {
    1139    11863642 :                 fsnotify_xattr(dentry);
    1140             :                 evm_inode_post_set_acl(dentry, acl_name, kacl);
    1141             :         }
    1142             : 
    1143        5851 : out_inode_unlock:
    1144    11843079 :         inode_unlock(inode);
    1145             : 
    1146    11803207 :         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    12029304 : struct posix_acl *vfs_get_acl(struct mnt_idmap *idmap,
    1168             :                               struct dentry *dentry, const char *acl_name)
    1169             : {
    1170    12029304 :         struct inode *inode = d_inode(dentry);
    1171    12029304 :         struct posix_acl *acl;
    1172    12029304 :         int acl_type, error;
    1173             : 
    1174    12029304 :         acl_type = posix_acl_type(acl_name);
    1175    12029304 :         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    12029304 :         error = security_inode_get_acl(idmap, dentry, acl_name);
    1183    12029304 :         if (error)
    1184             :                 return ERR_PTR(error);
    1185             : 
    1186    12029304 :         if (!IS_POSIXACL(inode))
    1187             :                 return ERR_PTR(-EOPNOTSUPP);
    1188    12023490 :         if (S_ISLNK(inode->i_mode))
    1189             :                 return ERR_PTR(-EOPNOTSUPP);
    1190             : 
    1191    12023490 :         acl = __get_acl(idmap, dentry, inode, acl_type);
    1192    11991890 :         if (IS_ERR(acl))
    1193             :                 return acl;
    1194    11991868 :         if (!acl)
    1195    12051877 :                 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      217666 : int vfs_remove_acl(struct mnt_idmap *idmap, struct dentry *dentry,
    1212             :                    const char *acl_name)
    1213             : {
    1214      217666 :         int acl_type;
    1215      217666 :         int error;
    1216      217666 :         struct inode *inode = d_inode(dentry);
    1217      217666 :         struct inode *delegated_inode = NULL;
    1218             : 
    1219      217666 :         acl_type = posix_acl_type(acl_name);
    1220      217666 :         if (acl_type < 0)
    1221             :                 return -EINVAL;
    1222             : 
    1223      217666 : retry_deleg:
    1224      217666 :         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      217712 :         error = may_write_xattr(idmap, inode);
    1231      217754 :         if (error)
    1232           0 :                 goto out_inode_unlock;
    1233             : 
    1234      217754 :         error = security_inode_remove_acl(idmap, dentry, acl_name);
    1235      217754 :         if (error)
    1236             :                 goto out_inode_unlock;
    1237             : 
    1238      217754 :         error = try_break_deleg(inode, &delegated_inode);
    1239      217820 :         if (error)
    1240           0 :                 goto out_inode_unlock;
    1241             : 
    1242      217820 :         if (likely(!is_bad_inode(inode)))
    1243      217811 :                 error = set_posix_acl(idmap, dentry, acl_type, NULL);
    1244             :         else
    1245             :                 error = -EIO;
    1246      217835 :         if (!error) {
    1247      217835 :                 fsnotify_xattr(dentry);
    1248             :                 evm_inode_post_remove_acl(idmap, dentry, acl_name);
    1249             :         }
    1250             : 
    1251           0 : out_inode_unlock:
    1252      217809 :         inode_unlock(inode);
    1253             : 
    1254      217808 :         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    11870880 : int do_set_acl(struct mnt_idmap *idmap, struct dentry *dentry,
    1265             :                const char *acl_name, const void *kvalue, size_t size)
    1266             : {
    1267    11870880 :         int error;
    1268    11870880 :         struct posix_acl *acl = NULL;
    1269             : 
    1270    11870880 :         if (size) {
    1271             :                 /*
    1272             :                  * Note that posix_acl_from_xattr() uses GFP_NOFS when it
    1273             :                  * probably doesn't need to here.
    1274             :                  */
    1275    11859530 :                 acl = posix_acl_from_xattr(current_user_ns(), kvalue, size);
    1276    11817153 :                 if (IS_ERR(acl))
    1277           0 :                         return PTR_ERR(acl);
    1278             :         }
    1279             : 
    1280    11828503 :         error = vfs_set_acl(idmap, dentry, acl_name, acl);
    1281    11856372 :         posix_acl_release(acl);
    1282    11856372 :         return error;
    1283             : }
    1284             : 
    1285    12058058 : ssize_t do_get_acl(struct mnt_idmap *idmap, struct dentry *dentry,
    1286             :                    const char *acl_name, void *kvalue, size_t size)
    1287             : {
    1288    12058058 :         ssize_t error;
    1289    12058058 :         struct posix_acl *acl;
    1290             : 
    1291    12058058 :         acl = vfs_get_acl(idmap, dentry, acl_name);
    1292    11995679 :         if (IS_ERR(acl))
    1293    11994837 :                 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