LCOV - code coverage report
Current view: top level - fs - attr.c (source / functions) Hit Total Coverage
Test: fstests of 6.5.0-rc3-djwx @ Mon Jul 31 20:08:22 PDT 2023 Lines: 150 155 96.8 %
Date: 2023-07-31 20:08:22 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    21151925 : int setattr_should_drop_sgid(struct mnt_idmap *idmap,
      38             :                              const struct inode *inode)
      39             : {
      40    21151925 :         umode_t mode = inode->i_mode;
      41             : 
      42    21151925 :         if (!(mode & S_ISGID))
      43             :                 return 0;
      44         979 :         if (mode & S_IXGRP)
      45             :                 return ATTR_KILL_SGID;
      46         387 :         if (!in_group_or_capable(idmap, inode, i_gid_into_vfsgid(idmap, inode)))
      47         128 :                 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     4687365 : int setattr_should_drop_suidgid(struct mnt_idmap *idmap,
      68             :                                 struct inode *inode)
      69             : {
      70     4687365 :         umode_t mode = inode->i_mode;
      71     4687365 :         int kill = 0;
      72             : 
      73             :         /* suid always must be killed */
      74     4687365 :         if (unlikely(mode & S_ISUID))
      75         616 :                 kill = ATTR_KILL_SUID;
      76             : 
      77     4687365 :         kill |= setattr_should_drop_sgid(idmap, inode);
      78             : 
      79     4685728 :         if (unlikely(kill && !capable(CAP_FSETID) && S_ISREG(mode)))
      80         540 :                 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    17428144 : static bool chown_ok(struct mnt_idmap *idmap,
      99             :                      const struct inode *inode, vfsuid_t ia_vfsuid)
     100             : {
     101    17428144 :         vfsuid_t vfsuid = i_uid_into_vfsuid(idmap, inode);
     102    50370028 :         if (vfsuid_eq_kuid(vfsuid, current_fsuid()) &&
     103             :             vfsuid_eq(ia_vfsuid, vfsuid))
     104             :                 return true;
     105    16670398 :         if (capable_wrt_inode_uidgid(idmap, inode, CAP_CHOWN))
     106             :                 return true;
     107         312 :         if (!vfsuid_valid(vfsuid) &&
     108          13 :             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    17345807 : static bool chgrp_ok(struct mnt_idmap *idmap,
     126             :                      const struct inode *inode, vfsgid_t ia_vfsgid)
     127             : {
     128    17345807 :         vfsgid_t vfsgid = i_gid_into_vfsgid(idmap, inode);
     129    17360981 :         vfsuid_t vfsuid = i_uid_into_vfsuid(idmap, inode);
     130    34731237 :         if (vfsuid_eq_kuid(vfsuid, current_fsuid())) {
     131    30867058 :                 if (vfsgid_eq(ia_vfsgid, vfsgid))
     132             :                         return true;
     133    14674315 :                 if (vfsgid_in_group_p(ia_vfsgid))
     134             :                         return true;
     135             :         }
     136    16598505 :         if (capable_wrt_inode_uidgid(idmap, inode, CAP_CHOWN))
     137             :                 return true;
     138          75 :         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    51001263 : int setattr_prepare(struct mnt_idmap *idmap, struct dentry *dentry,
     166             :                     struct iattr *attr)
     167             : {
     168    51001263 :         struct inode *inode = d_inode(dentry);
     169    51001263 :         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    51001263 :         if (ia_valid & ATTR_SIZE) {
     176    16822161 :                 int error = inode_newsize_ok(inode, attr->ia_size);
     177    16822469 :                 if (error)
     178             :                         return error;
     179             :         }
     180             : 
     181             :         /* If force is set do it anyway. */
     182    51001467 :         if (ia_valid & ATTR_FORCE)
     183         609 :                 goto kill_priv;
     184             : 
     185             :         /* Make sure a caller can chown. */
     186    68334515 :         if ((ia_valid & ATTR_UID) &&
     187    17459840 :             !chown_ok(idmap, inode, attr->ia_vfsuid))
     188             :                 return -EPERM;
     189             : 
     190             :         /* Make sure caller can chgrp. */
     191    68227363 :         if ((ia_valid & ATTR_GID) &&
     192    17338561 :             !chgrp_ok(idmap, inode, attr->ia_vfsgid))
     193             :                 return -EPERM;
     194             : 
     195             :         /* Make sure a caller can chmod. */
     196    50888727 :         if (ia_valid & ATTR_MODE) {
     197     1208386 :                 vfsgid_t vfsgid;
     198             : 
     199     1208386 :                 if (!inode_owner_or_capable(idmap, inode))
     200          39 :                         return -EPERM;
     201             : 
     202     1208300 :                 if (ia_valid & ATTR_GID)
     203        5222 :                         vfsgid = attr->ia_vfsgid;
     204             :                 else
     205     1203078 :                         vfsgid = i_gid_into_vfsgid(idmap, inode);
     206             : 
     207             :                 /* Also check the setgid bit! */
     208     1208301 :                 if (!in_group_or_capable(idmap, inode, vfsgid))
     209          52 :                         attr->ia_mode &= ~S_ISGID;
     210             :         }
     211             : 
     212             :         /* Check for setting the inode time. */
     213    50888577 :         if (ia_valid & (ATTR_MTIME_SET | ATTR_ATIME_SET | ATTR_TIMES_SET)) {
     214    12010665 :                 if (!inode_owner_or_capable(idmap, inode))
     215             :                         return -EPERM;
     216             :         }
     217             : 
     218    50919342 : kill_priv:
     219             :         /* User has permission for the change */
     220    50919951 :         if (ia_valid & ATTR_KILL_PRIV) {
     221          85 :                 int error;
     222             : 
     223          85 :                 error = security_inode_killpriv(idmap, dentry);
     224          85 :                 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    22392626 : int inode_newsize_ok(const struct inode *inode, loff_t offset)
     249             : {
     250    22392626 :         if (offset < 0)
     251             :                 return -EINVAL;
     252    22392626 :         if (inode->i_size < offset) {
     253    14536014 :                 unsigned long limit;
     254             : 
     255    14536014 :                 limit = rlimit(RLIMIT_FSIZE);
     256    14536014 :                 if (limit != RLIM_INFINITY && offset > limit)
     257          25 :                         goto out_sig;
     258    14535989 :                 if (offset > inode->i_sb->s_maxbytes)
     259          66 :                         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     7856612 :                 if (IS_SWAPFILE(inode))
     267          25 :                         return -ETXTBSY;
     268             :         }
     269             : 
     270             :         return 0;
     271             : out_sig:
     272          25 :         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    50911891 : void setattr_copy(struct mnt_idmap *idmap, struct inode *inode,
     304             :                   const struct iattr *attr)
     305             : {
     306    50911891 :         unsigned int ia_valid = attr->ia_valid;
     307             : 
     308    50911891 :         i_uid_update(idmap, attr, inode);
     309    50898621 :         i_gid_update(idmap, attr, inode);
     310    50901425 :         if (ia_valid & ATTR_ATIME)
     311    15408113 :                 inode->i_atime = attr->ia_atime;
     312    50901425 :         if (ia_valid & ATTR_MTIME)
     313    32155802 :                 inode->i_mtime = attr->ia_mtime;
     314    50901425 :         if (ia_valid & ATTR_CTIME)
     315    50536804 :                 inode->i_ctime = attr->ia_ctime;
     316    50901425 :         if (ia_valid & ATTR_MODE) {
     317     1207987 :                 umode_t mode = attr->ia_mode;
     318     1207987 :                 if (!in_group_or_capable(idmap, inode,
     319             :                                          i_gid_into_vfsgid(idmap, inode)))
     320         436 :                         mode &= ~S_ISGID;
     321     1207996 :                 inode->i_mode = mode;
     322             :         }
     323    50901434 : }
     324             : EXPORT_SYMBOL(setattr_copy);
     325             : 
     326    42613967 : int may_setattr(struct mnt_idmap *idmap, struct inode *inode,
     327             :                 unsigned int ia_valid)
     328             : {
     329    42613967 :         int error;
     330             : 
     331    42613967 :         if (ia_valid & (ATTR_MODE | ATTR_UID | ATTR_GID | ATTR_TIMES_SET)) {
     332    30555273 :                 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    42613759 :         if (ia_valid & ATTR_TOUCH) {
     341     3485825 :                 if (IS_IMMUTABLE(inode))
     342             :                         return -EPERM;
     343             : 
     344     3485773 :                 if (!inode_owner_or_capable(idmap, inode)) {
     345          65 :                         error = inode_permission(idmap, inode, MAY_WRITE);
     346          65 :                         if (error)
     347          26 :                                 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    42639864 : int notify_change(struct mnt_idmap *idmap, struct dentry *dentry,
     382             :                   struct iattr *attr, struct inode **delegated_inode)
     383             : {
     384    42639864 :         struct inode *inode = dentry->d_inode;
     385    42639864 :         umode_t mode = inode->i_mode;
     386    42639864 :         int error;
     387    42639864 :         struct timespec64 now;
     388    42639864 :         unsigned int ia_valid = attr->ia_valid;
     389             : 
     390    42639864 :         WARN_ON_ONCE(!inode_is_locked(inode));
     391             : 
     392    42639864 :         error = may_setattr(idmap, inode, ia_valid);
     393    42591359 :         if (error)
     394             :                 return error;
     395             : 
     396    42591073 :         if ((ia_valid & ATTR_MODE)) {
     397     1213359 :                 umode_t amode = attr->ia_mode;
     398             :                 /* Flag setting protected by i_mutex */
     399     1213359 :                 if (is_sxid(amode))
     400        1681 :                         inode->i_flags &= ~S_NOSEC;
     401             :         }
     402             : 
     403    42591073 :         now = current_time(inode);
     404             : 
     405    42651026 :         attr->ia_ctime = now;
     406    42651026 :         if (!(ia_valid & ATTR_ATIME_SET))
     407    30622257 :                 attr->ia_atime = now;
     408             :         else
     409    12028769 :                 attr->ia_atime = timestamp_truncate(attr->ia_atime, inode);
     410    42646635 :         if (!(ia_valid & ATTR_MTIME_SET))
     411    30588694 :                 attr->ia_mtime = now;
     412             :         else
     413    12057941 :                 attr->ia_mtime = timestamp_truncate(attr->ia_mtime, inode);
     414             : 
     415    42650318 :         if (ia_valid & ATTR_KILL_PRIV) {
     416    16500540 :                 error = security_inode_need_killpriv(dentry);
     417    16463842 :                 if (error < 0)
     418             :                         return error;
     419    16463842 :                 if (error == 0)
     420    16465011 :                         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    42613620 :         if ((ia_valid & (ATTR_KILL_SUID|ATTR_KILL_SGID)) &&
     431    16434804 :             (ia_valid & ATTR_MODE))
     432           0 :                 BUG();
     433             : 
     434    42613620 :         if (ia_valid & ATTR_KILL_SUID) {
     435    16435830 :                 if (mode & S_ISUID) {
     436         464 :                         ia_valid = attr->ia_valid |= ATTR_MODE;
     437         464 :                         attr->ia_mode = (inode->i_mode & ~S_ISUID);
     438             :                 }
     439             :         }
     440    42613620 :         if (ia_valid & ATTR_KILL_SGID) {
     441         566 :                 if (mode & S_ISGID) {
     442         566 :                         if (!(ia_valid & ATTR_MODE)) {
     443         180 :                                 ia_valid = attr->ia_valid |= ATTR_MODE;
     444         180 :                                 attr->ia_mode = inode->i_mode;
     445             :                         }
     446         566 :                         attr->ia_mode &= ~S_ISGID;
     447             :                 }
     448             :         }
     449    42613620 :         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    42613620 :         if (ia_valid & ATTR_UID &&
     457    17360380 :             !vfsuid_has_fsmapping(idmap, inode->i_sb->s_user_ns,
     458             :                                   attr->ia_vfsuid))
     459             :                 return -EOVERFLOW;
     460    42668234 :         if (ia_valid & ATTR_GID &&
     461    17431904 :             !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    67831298 :         if (!(ia_valid & ATTR_UID) &&
     469             :             !vfsuid_valid(i_uid_into_vfsuid(idmap, inode)))
     470             :                 return -EOVERFLOW;
     471    67797125 :         if (!(ia_valid & ATTR_GID) &&
     472             :             !vfsgid_valid(i_gid_into_vfsgid(idmap, inode)))
     473             :                 return -EOVERFLOW;
     474             : 
     475    42617332 :         error = security_inode_setattr(idmap, dentry, attr);
     476    42617332 :         if (error)
     477             :                 return error;
     478    42617332 :         error = try_break_deleg(inode, delegated_inode);
     479    42718794 :         if (error)
     480             :                 return error;
     481             : 
     482    42718794 :         if (inode->i_op->setattr)
     483    42718764 :                 error = inode->i_op->setattr(idmap, dentry, attr);
     484             :         else
     485          30 :                 error = simple_setattr(idmap, dentry, attr);
     486             : 
     487    42728603 :         if (!error) {
     488    42686083 :                 fsnotify_change(dentry, ia_valid);
     489    42686083 :                 ima_inode_post_setattr(idmap, dentry);
     490    42686083 :                 evm_inode_post_setattr(dentry, ia_valid);
     491             :         }
     492             : 
     493             :         return error;
     494             : }
     495             : EXPORT_SYMBOL(notify_change);

Generated by: LCOV version 1.14