LCOV - code coverage report
Current view: top level - fs - attr.c (source / functions) Hit Total Coverage
Test: fstests of 6.5.0-rc3-djwa @ Mon Jul 31 20:08:17 PDT 2023 Lines: 149 155 96.1 %
Date: 2023-07-31 20:08:17 Functions: 9 9 100.0 %

          Line data    Source code
       1             : // SPDX-License-Identifier: GPL-2.0
       2             : /*
       3             :  *  linux/fs/attr.c
       4             :  *
       5             :  *  Copyright (C) 1991, 1992  Linus Torvalds
       6             :  *  changes by Thomas Schoebel-Theuer
       7             :  */
       8             : 
       9             : #include <linux/export.h>
      10             : #include <linux/time.h>
      11             : #include <linux/mm.h>
      12             : #include <linux/string.h>
      13             : #include <linux/sched/signal.h>
      14             : #include <linux/capability.h>
      15             : #include <linux/fsnotify.h>
      16             : #include <linux/fcntl.h>
      17             : #include <linux/filelock.h>
      18             : #include <linux/security.h>
      19             : #include <linux/evm.h>
      20             : #include <linux/ima.h>
      21             : 
      22             : #include "internal.h"
      23             : 
      24             : /**
      25             :  * setattr_should_drop_sgid - determine whether the setgid bit needs to be
      26             :  *                            removed
      27             :  * @idmap:      idmap of the mount @inode was found from
      28             :  * @inode:      inode to check
      29             :  *
      30             :  * This function determines whether the setgid bit needs to be removed.
      31             :  * We retain backwards compatibility and require setgid bit to be removed
      32             :  * unconditionally if S_IXGRP is set. Otherwise we have the exact same
      33             :  * requirements as setattr_prepare() and setattr_copy().
      34             :  *
      35             :  * Return: ATTR_KILL_SGID if setgid bit needs to be removed, 0 otherwise.
      36             :  */
      37     5631098 : int setattr_should_drop_sgid(struct mnt_idmap *idmap,
      38             :                              const struct inode *inode)
      39             : {
      40     5631098 :         umode_t mode = inode->i_mode;
      41             : 
      42     5631098 :         if (!(mode & S_ISGID))
      43             :                 return 0;
      44         168 :         if (mode & S_IXGRP)
      45             :                 return ATTR_KILL_SGID;
      46          68 :         if (!in_group_or_capable(idmap, inode, i_gid_into_vfsgid(idmap, inode)))
      47          24 :                 return ATTR_KILL_SGID;
      48             :         return 0;
      49             : }
      50             : EXPORT_SYMBOL(setattr_should_drop_sgid);
      51             : 
      52             : /**
      53             :  * setattr_should_drop_suidgid - determine whether the set{g,u}id bit needs to
      54             :  *                               be dropped
      55             :  * @idmap:      idmap of the mount @inode was found from
      56             :  * @inode:      inode to check
      57             :  *
      58             :  * This function determines whether the set{g,u}id bits need to be removed.
      59             :  * If the setuid bit needs to be removed ATTR_KILL_SUID is returned. If the
      60             :  * setgid bit needs to be removed ATTR_KILL_SGID is returned. If both
      61             :  * set{g,u}id bits need to be removed the corresponding mask of both flags is
      62             :  * returned.
      63             :  *
      64             :  * Return: A mask of ATTR_KILL_S{G,U}ID indicating which - if any - setid bits
      65             :  * to remove, 0 otherwise.
      66             :  */
      67     1454377 : int setattr_should_drop_suidgid(struct mnt_idmap *idmap,
      68             :                                 struct inode *inode)
      69             : {
      70     1454377 :         umode_t mode = inode->i_mode;
      71     1454377 :         int kill = 0;
      72             : 
      73             :         /* suid always must be killed */
      74     1454377 :         if (unlikely(mode & S_ISUID))
      75         112 :                 kill = ATTR_KILL_SUID;
      76             : 
      77     1454377 :         kill |= setattr_should_drop_sgid(idmap, inode);
      78             : 
      79     1454374 :         if (unlikely(kill && !capable(CAP_FSETID) && S_ISREG(mode)))
      80          92 :                 return kill;
      81             : 
      82             :         return 0;
      83             : }
      84             : EXPORT_SYMBOL(setattr_should_drop_suidgid);
      85             : 
      86             : /**
      87             :  * chown_ok - verify permissions to chown inode
      88             :  * @idmap:      idmap of the mount @inode was found from
      89             :  * @inode:      inode to check permissions on
      90             :  * @ia_vfsuid:  uid to chown @inode to
      91             :  *
      92             :  * If the inode has been found through an idmapped mount the idmap of
      93             :  * the vfsmount must be passed through @idmap. This function will then
      94             :  * take care to map the inode according to @idmap before checking
      95             :  * permissions. On non-idmapped mounts or if permission checking is to be
      96             :  * performed on the raw inode simply pass @nop_mnt_idmap.
      97             :  */
      98     4642059 : static bool chown_ok(struct mnt_idmap *idmap,
      99             :                      const struct inode *inode, vfsuid_t ia_vfsuid)
     100             : {
     101     4642059 :         vfsuid_t vfsuid = i_uid_into_vfsuid(idmap, inode);
     102    13054723 :         if (vfsuid_eq_kuid(vfsuid, current_fsuid()) &&
     103             :             vfsuid_eq(ia_vfsuid, vfsuid))
     104             :                 return true;
     105     4426934 :         if (capable_wrt_inode_uidgid(idmap, inode, CAP_CHOWN))
     106             :                 return true;
     107          36 :         if (!vfsuid_valid(vfsuid) &&
     108           2 :             ns_capable(inode->i_sb->s_user_ns, CAP_CHOWN))
     109           0 :                 return true;
     110             :         return false;
     111             : }
     112             : 
     113             : /**
     114             :  * chgrp_ok - verify permissions to chgrp inode
     115             :  * @idmap:      idmap of the mount @inode was found from
     116             :  * @inode:      inode to check permissions on
     117             :  * @ia_vfsgid:  gid to chown @inode to
     118             :  *
     119             :  * If the inode has been found through an idmapped mount the idmap of
     120             :  * the vfsmount must be passed through @idmap. This function will then
     121             :  * take care to map the inode according to @idmap before checking
     122             :  * permissions. On non-idmapped mounts or if permission checking is to be
     123             :  * performed on the raw inode simply pass @nop_mnt_idmap.
     124             :  */
     125     4641808 : static bool chgrp_ok(struct mnt_idmap *idmap,
     126             :                      const struct inode *inode, vfsgid_t ia_vfsgid)
     127             : {
     128     4641808 :         vfsgid_t vfsgid = i_gid_into_vfsgid(idmap, inode);
     129     4641813 :         vfsuid_t vfsuid = i_uid_into_vfsuid(idmap, inode);
     130     9283619 :         if (vfsuid_eq_kuid(vfsuid, current_fsuid())) {
     131     7541082 :                 if (vfsgid_eq(ia_vfsgid, vfsgid))
     132             :                         return true;
     133     3556471 :                 if (vfsgid_in_group_p(ia_vfsgid))
     134             :                         return true;
     135             :         }
     136     4425831 :         if (capable_wrt_inode_uidgid(idmap, inode, CAP_CHOWN))
     137             :                 return true;
     138          10 :         if (!vfsgid_valid(vfsgid) &&
     139           0 :             ns_capable(inode->i_sb->s_user_ns, CAP_CHOWN))
     140           0 :                 return true;
     141             :         return false;
     142             : }
     143             : 
     144             : /**
     145             :  * setattr_prepare - check if attribute changes to a dentry are allowed
     146             :  * @idmap:      idmap of the mount the inode was found from
     147             :  * @dentry:     dentry to check
     148             :  * @attr:       attributes to change
     149             :  *
     150             :  * Check if we are allowed to change the attributes contained in @attr
     151             :  * in the given dentry.  This includes the normal unix access permission
     152             :  * checks, as well as checks for rlimits and others. The function also clears
     153             :  * SGID bit from mode if user is not allowed to set it. Also file capabilities
     154             :  * and IMA extended attributes are cleared if ATTR_KILL_PRIV is set.
     155             :  *
     156             :  * If the inode has been found through an idmapped mount the idmap of
     157             :  * the vfsmount must be passed through @idmap. This function will then
     158             :  * take care to map the inode according to @idmap before checking
     159             :  * permissions. On non-idmapped mounts or if permission checking is to be
     160             :  * performed on the raw inode simply passs @nop_mnt_idmap.
     161             :  *
     162             :  * Should be called as the first thing in ->setattr implementations,
     163             :  * possibly after taking additional locks.
     164             :  */
     165    12606230 : int setattr_prepare(struct mnt_idmap *idmap, struct dentry *dentry,
     166             :                     struct iattr *attr)
     167             : {
     168    12606230 :         struct inode *inode = d_inode(dentry);
     169    12606230 :         unsigned int ia_valid = attr->ia_valid;
     170             : 
     171             :         /*
     172             :          * First check size constraints.  These can't be overriden using
     173             :          * ATTR_FORCE.
     174             :          */
     175    12606230 :         if (ia_valid & ATTR_SIZE) {
     176     5153131 :                 int error = inode_newsize_ok(inode, attr->ia_size);
     177     5153135 :                 if (error)
     178             :                         return error;
     179             :         }
     180             : 
     181             :         /* If force is set do it anyway. */
     182    12606228 :         if (ia_valid & ATTR_FORCE)
     183         106 :                 goto kill_priv;
     184             : 
     185             :         /* Make sure a caller can chown. */
     186    17248147 :         if ((ia_valid & ATTR_UID) &&
     187     4642056 :             !chown_ok(idmap, inode, attr->ia_vfsuid))
     188             :                 return -EPERM;
     189             : 
     190             :         /* Make sure caller can chgrp. */
     191    17247852 :         if ((ia_valid & ATTR_GID) &&
     192     4641803 :             !chgrp_ok(idmap, inode, attr->ia_vfsgid))
     193             :                 return -EPERM;
     194             : 
     195             :         /* Make sure a caller can chmod. */
     196    12606039 :         if (ia_valid & ATTR_MODE) {
     197      207335 :                 vfsgid_t vfsgid;
     198             : 
     199      207335 :                 if (!inode_owner_or_capable(idmap, inode))
     200           6 :                         return -EPERM;
     201             : 
     202      207329 :                 if (ia_valid & ATTR_GID)
     203         610 :                         vfsgid = attr->ia_vfsgid;
     204             :                 else
     205      206719 :                         vfsgid = i_gid_into_vfsgid(idmap, inode);
     206             : 
     207             :                 /* Also check the setgid bit! */
     208      207329 :                 if (!in_group_or_capable(idmap, inode, vfsgid))
     209           8 :                         attr->ia_mode &= ~S_ISGID;
     210             :         }
     211             : 
     212             :         /* Check for setting the inode time. */
     213    12606033 :         if (ia_valid & (ATTR_MTIME_SET | ATTR_ATIME_SET | ATTR_TIMES_SET)) {
     214     1895314 :                 if (!inode_owner_or_capable(idmap, inode))
     215             :                         return -EPERM;
     216             :         }
     217             : 
     218    12606026 : kill_priv:
     219             :         /* User has permission for the change */
     220    12606132 :         if (ia_valid & ATTR_KILL_PRIV) {
     221          14 :                 int error;
     222             : 
     223          14 :                 error = security_inode_killpriv(idmap, dentry);
     224          14 :                 if (error)
     225           0 :                         return error;
     226             :         }
     227             : 
     228             :         return 0;
     229             : }
     230             : EXPORT_SYMBOL(setattr_prepare);
     231             : 
     232             : /**
     233             :  * inode_newsize_ok - may this inode be truncated to a given size
     234             :  * @inode:      the inode to be truncated
     235             :  * @offset:     the new size to assign to the inode
     236             :  *
     237             :  * inode_newsize_ok must be called with i_mutex held.
     238             :  *
     239             :  * inode_newsize_ok will check filesystem limits and ulimits to check that the
     240             :  * new inode size is within limits. inode_newsize_ok will also send SIGXFSZ
     241             :  * when necessary. Caller must not proceed with inode size change if failure is
     242             :  * returned. @inode must be a file (not directory), with appropriate
     243             :  * permissions to allow truncate (inode_newsize_ok does NOT check these
     244             :  * conditions).
     245             :  *
     246             :  * Return: 0 on success, -ve errno on failure
     247             :  */
     248     6305012 : int inode_newsize_ok(const struct inode *inode, loff_t offset)
     249             : {
     250     6305012 :         if (offset < 0)
     251             :                 return -EINVAL;
     252     6305012 :         if (inode->i_size < offset) {
     253     3658284 :                 unsigned long limit;
     254             : 
     255     3658284 :                 limit = rlimit(RLIMIT_FSIZE);
     256     3658284 :                 if (limit != RLIM_INFINITY && offset > limit)
     257           4 :                         goto out_sig;
     258     3658280 :                 if (offset > inode->i_sb->s_maxbytes)
     259           0 :                         goto out_big;
     260             :         } else {
     261             :                 /*
     262             :                  * truncation of in-use swapfiles is disallowed - it would
     263             :                  * cause subsequent swapout to scribble on the now-freed
     264             :                  * blocks.
     265             :                  */
     266     2646728 :                 if (IS_SWAPFILE(inode))
     267           4 :                         return -ETXTBSY;
     268             :         }
     269             : 
     270             :         return 0;
     271             : out_sig:
     272           4 :         send_sig(SIGXFSZ, current, 0);
     273             : out_big:
     274             :         return -EFBIG;
     275             : }
     276             : EXPORT_SYMBOL(inode_newsize_ok);
     277             : 
     278             : /**
     279             :  * setattr_copy - copy simple metadata updates into the generic inode
     280             :  * @idmap:      idmap of the mount the inode was found from
     281             :  * @inode:      the inode to be updated
     282             :  * @attr:       the new attributes
     283             :  *
     284             :  * setattr_copy must be called with i_mutex held.
     285             :  *
     286             :  * setattr_copy updates the inode's metadata with that specified
     287             :  * in attr on idmapped mounts. Necessary permission checks to determine
     288             :  * whether or not the S_ISGID property needs to be removed are performed with
     289             :  * the correct idmapped mount permission helpers.
     290             :  * Noticeably missing is inode size update, which is more complex
     291             :  * as it requires pagecache updates.
     292             :  *
     293             :  * If the inode has been found through an idmapped mount the idmap of
     294             :  * the vfsmount must be passed through @idmap. This function will then
     295             :  * take care to map the inode according to @idmap before checking
     296             :  * permissions. On non-idmapped mounts or if permission checking is to be
     297             :  * performed on the raw inode simply pass @nop_mnt_idmap.
     298             :  *
     299             :  * The inode is not marked as dirty after this operation. The rationale is
     300             :  * that for "simple" filesystems, the struct inode is the inode storage.
     301             :  * The caller is free to mark the inode dirty afterwards if needed.
     302             :  */
     303    12552338 : void setattr_copy(struct mnt_idmap *idmap, struct inode *inode,
     304             :                   const struct iattr *attr)
     305             : {
     306    12552338 :         unsigned int ia_valid = attr->ia_valid;
     307             : 
     308    12552338 :         i_uid_update(idmap, attr, inode);
     309    12552301 :         i_gid_update(idmap, attr, inode);
     310    12552300 :         if (ia_valid & ATTR_ATIME)
     311     2580739 :                 inode->i_atime = attr->ia_atime;
     312    12552300 :         if (ia_valid & ATTR_MTIME)
     313     7736184 :                 inode->i_mtime = attr->ia_mtime;
     314    12552300 :         if (ia_valid & ATTR_CTIME)
     315    12477733 :                 inode->i_ctime = attr->ia_ctime;
     316    12552300 :         if (ia_valid & ATTR_MODE) {
     317      207271 :                 umode_t mode = attr->ia_mode;
     318      207271 :                 if (!in_group_or_capable(idmap, inode,
     319             :                                          i_gid_into_vfsgid(idmap, inode)))
     320          80 :                         mode &= ~S_ISGID;
     321      207270 :                 inode->i_mode = mode;
     322             :         }
     323    12552299 : }
     324             : EXPORT_SYMBOL(setattr_copy);
     325             : 
     326    10681597 : int may_setattr(struct mnt_idmap *idmap, struct inode *inode,
     327             :                 unsigned int ia_valid)
     328             : {
     329    10681597 :         int error;
     330             : 
     331    10681597 :         if (ia_valid & (ATTR_MODE | ATTR_UID | ATTR_GID | ATTR_TIMES_SET)) {
     332     6718678 :                 if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
     333             :                         return -EPERM;
     334             :         }
     335             : 
     336             :         /*
     337             :          * If utimes(2) and friends are called with times == NULL (or both
     338             :          * times are UTIME_NOW), then we need to check for write permission
     339             :          */
     340    10681565 :         if (ia_valid & ATTR_TOUCH) {
     341      708543 :                 if (IS_IMMUTABLE(inode))
     342             :                         return -EPERM;
     343             : 
     344      708535 :                 if (!inode_owner_or_capable(idmap, inode)) {
     345          10 :                         error = inode_permission(idmap, inode, MAY_WRITE);
     346          10 :                         if (error)
     347           4 :                                 return error;
     348             :                 }
     349             :         }
     350             :         return 0;
     351             : }
     352             : EXPORT_SYMBOL(may_setattr);
     353             : 
     354             : /**
     355             :  * notify_change - modify attributes of a filesytem object
     356             :  * @idmap:      idmap of the mount the inode was found from
     357             :  * @dentry:     object affected
     358             :  * @attr:       new attributes
     359             :  * @delegated_inode: returns inode, if the inode is delegated
     360             :  *
     361             :  * The caller must hold the i_mutex on the affected object.
     362             :  *
     363             :  * If notify_change discovers a delegation in need of breaking,
     364             :  * it will return -EWOULDBLOCK and return a reference to the inode in
     365             :  * delegated_inode.  The caller should then break the delegation and
     366             :  * retry.  Because breaking a delegation may take a long time, the
     367             :  * caller should drop the i_mutex before doing so.
     368             :  *
     369             :  * Alternatively, a caller may pass NULL for delegated_inode.  This may
     370             :  * be appropriate for callers that expect the underlying filesystem not
     371             :  * to be NFS exported.  Also, passing NULL is fine for callers holding
     372             :  * the file open for write, as there can be no conflicting delegation in
     373             :  * that case.
     374             :  *
     375             :  * If the inode has been found through an idmapped mount the idmap of
     376             :  * the vfsmount must be passed through @idmap. This function will then
     377             :  * take care to map the inode according to @idmap before checking
     378             :  * permissions. On non-idmapped mounts or if permission checking is to be
     379             :  * performed on the raw inode simply pass @nop_mnt_idmap.
     380             :  */
     381    10681568 : int notify_change(struct mnt_idmap *idmap, struct dentry *dentry,
     382             :                   struct iattr *attr, struct inode **delegated_inode)
     383             : {
     384    10681568 :         struct inode *inode = dentry->d_inode;
     385    10681568 :         umode_t mode = inode->i_mode;
     386    10681568 :         int error;
     387    10681568 :         struct timespec64 now;
     388    10681568 :         unsigned int ia_valid = attr->ia_valid;
     389             : 
     390    10681568 :         WARN_ON_ONCE(!inode_is_locked(inode));
     391             : 
     392    10681568 :         error = may_setattr(idmap, inode, ia_valid);
     393    10681560 :         if (error)
     394             :                 return error;
     395             : 
     396    10681516 :         if ((ia_valid & ATTR_MODE)) {
     397      208658 :                 umode_t amode = attr->ia_mode;
     398             :                 /* Flag setting protected by i_mutex */
     399      208658 :                 if (is_sxid(amode))
     400         274 :                         inode->i_flags &= ~S_NOSEC;
     401             :         }
     402             : 
     403    10681516 :         now = current_time(inode);
     404             : 
     405    10681583 :         attr->ia_ctime = now;
     406    10681583 :         if (!(ia_valid & ATTR_ATIME_SET))
     407     8788108 :                 attr->ia_atime = now;
     408             :         else
     409     1893475 :                 attr->ia_atime = timestamp_truncate(attr->ia_atime, inode);
     410    10681584 :         if (!(ia_valid & ATTR_MTIME_SET))
     411     8783014 :                 attr->ia_mtime = now;
     412             :         else
     413     1898570 :                 attr->ia_mtime = timestamp_truncate(attr->ia_mtime, inode);
     414             : 
     415    10681582 :         if (ia_valid & ATTR_KILL_PRIV) {
     416     4174153 :                 error = security_inode_need_killpriv(dentry);
     417     4174162 :                 if (error < 0)
     418             :                         return error;
     419     4174162 :                 if (error == 0)
     420     4174149 :                         ia_valid = attr->ia_valid &= ~ATTR_KILL_PRIV;
     421             :         }
     422             : 
     423             :         /*
     424             :          * We now pass ATTR_KILL_S*ID to the lower level setattr function so
     425             :          * that the function has the ability to reinterpret a mode change
     426             :          * that's due to these bits. This adds an implicit restriction that
     427             :          * no function will ever call notify_change with both ATTR_MODE and
     428             :          * ATTR_KILL_S*ID set.
     429             :          */
     430    10681591 :         if ((ia_valid & (ATTR_KILL_SUID|ATTR_KILL_SGID)) &&
     431     4174245 :             (ia_valid & ATTR_MODE))
     432           0 :                 BUG();
     433             : 
     434    10681591 :         if (ia_valid & ATTR_KILL_SUID) {
     435     4174215 :                 if (mode & S_ISUID) {
     436          80 :                         ia_valid = attr->ia_valid |= ATTR_MODE;
     437          80 :                         attr->ia_mode = (inode->i_mode & ~S_ISUID);
     438             :                 }
     439             :         }
     440    10681591 :         if (ia_valid & ATTR_KILL_SGID) {
     441          96 :                 if (mode & S_ISGID) {
     442          96 :                         if (!(ia_valid & ATTR_MODE)) {
     443          28 :                                 ia_valid = attr->ia_valid |= ATTR_MODE;
     444          28 :                                 attr->ia_mode = inode->i_mode;
     445             :                         }
     446          96 :                         attr->ia_mode &= ~S_ISGID;
     447             :                 }
     448             :         }
     449    10681591 :         if (!(attr->ia_valid & ~(ATTR_KILL_SUID | ATTR_KILL_SGID)))
     450             :                 return 0;
     451             : 
     452             :         /*
     453             :          * Verify that uid/gid changes are valid in the target
     454             :          * namespace of the superblock.
     455             :          */
     456    10681591 :         if (ia_valid & ATTR_UID &&
     457     4644438 :             !vfsuid_has_fsmapping(idmap, inode->i_sb->s_user_ns,
     458             :                                   attr->ia_vfsuid))
     459             :                 return -EOVERFLOW;
     460    10681573 :         if (ia_valid & ATTR_GID &&
     461     4644200 :             !vfsgid_has_fsmapping(idmap, inode->i_sb->s_user_ns,
     462             :                                   attr->ia_vfsgid))
     463             :                 return -EOVERFLOW;
     464             : 
     465             :         /* Don't allow modifications of files with invalid uids or
     466             :          * gids unless those uids & gids are being made valid.
     467             :          */
     468    16718744 :         if (!(ia_valid & ATTR_UID) &&
     469             :             !vfsuid_valid(i_uid_into_vfsuid(idmap, inode)))
     470             :                 return -EOVERFLOW;
     471    16718948 :         if (!(ia_valid & ATTR_GID) &&
     472             :             !vfsgid_valid(i_gid_into_vfsgid(idmap, inode)))
     473             :                 return -EOVERFLOW;
     474             : 
     475    10681567 :         error = security_inode_setattr(idmap, dentry, attr);
     476    10681567 :         if (error)
     477             :                 return error;
     478    10681567 :         error = try_break_deleg(inode, delegated_inode);
     479    10681529 :         if (error)
     480             :                 return error;
     481             : 
     482    10681529 :         if (inode->i_op->setattr)
     483    10681521 :                 error = inode->i_op->setattr(idmap, dentry, attr);
     484             :         else
     485           8 :                 error = simple_setattr(idmap, dentry, attr);
     486             : 
     487    10681525 :         if (!error) {
     488    10644260 :                 fsnotify_change(dentry, ia_valid);
     489    10644260 :                 ima_inode_post_setattr(idmap, dentry);
     490    10644260 :                 evm_inode_post_setattr(dentry, ia_valid);
     491             :         }
     492             : 
     493             :         return error;
     494             : }
     495             : EXPORT_SYMBOL(notify_change);

Generated by: LCOV version 1.14