LCOV - code coverage report
Current view: top level - fs - attr.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 0 141 0.0 %
Date: 2023-08-24 13:40:31 Functions: 0 9 0.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           0 : int setattr_should_drop_sgid(struct mnt_idmap *idmap,
      38             :                              const struct inode *inode)
      39             : {
      40           0 :         umode_t mode = inode->i_mode;
      41             : 
      42           0 :         if (!(mode & S_ISGID))
      43             :                 return 0;
      44           0 :         if (mode & S_IXGRP)
      45             :                 return ATTR_KILL_SGID;
      46           0 :         if (!in_group_or_capable(idmap, inode, i_gid_into_vfsgid(idmap, inode)))
      47             :                 return ATTR_KILL_SGID;
      48           0 :         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           0 : int setattr_should_drop_suidgid(struct mnt_idmap *idmap,
      68             :                                 struct inode *inode)
      69             : {
      70           0 :         umode_t mode = inode->i_mode;
      71           0 :         int kill = 0;
      72             : 
      73             :         /* suid always must be killed */
      74           0 :         if (unlikely(mode & S_ISUID))
      75           0 :                 kill = ATTR_KILL_SUID;
      76             : 
      77           0 :         kill |= setattr_should_drop_sgid(idmap, inode);
      78             : 
      79           0 :         if (unlikely(kill && !capable(CAP_FSETID) && S_ISREG(mode)))
      80             :                 return kill;
      81             : 
      82           0 :         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           0 : static bool chown_ok(struct mnt_idmap *idmap,
      99             :                      const struct inode *inode, vfsuid_t ia_vfsuid)
     100             : {
     101           0 :         vfsuid_t vfsuid = i_uid_into_vfsuid(idmap, inode);
     102           0 :         if (vfsuid_eq_kuid(vfsuid, current_fsuid()) &&
     103           0 :             vfsuid_eq(ia_vfsuid, vfsuid))
     104             :                 return true;
     105           0 :         if (capable_wrt_inode_uidgid(idmap, inode, CAP_CHOWN))
     106             :                 return true;
     107           0 :         if (!vfsuid_valid(vfsuid) &&
     108           0 :             ns_capable(inode->i_sb->s_user_ns, CAP_CHOWN))
     109             :                 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           0 : static bool chgrp_ok(struct mnt_idmap *idmap,
     126             :                      const struct inode *inode, vfsgid_t ia_vfsgid)
     127             : {
     128           0 :         vfsgid_t vfsgid = i_gid_into_vfsgid(idmap, inode);
     129           0 :         vfsuid_t vfsuid = i_uid_into_vfsuid(idmap, inode);
     130           0 :         if (vfsuid_eq_kuid(vfsuid, current_fsuid())) {
     131           0 :                 if (vfsgid_eq(ia_vfsgid, vfsgid))
     132             :                         return true;
     133           0 :                 if (vfsgid_in_group_p(ia_vfsgid))
     134             :                         return true;
     135             :         }
     136           0 :         if (capable_wrt_inode_uidgid(idmap, inode, CAP_CHOWN))
     137             :                 return true;
     138           0 :         if (!vfsgid_valid(vfsgid) &&
     139           0 :             ns_capable(inode->i_sb->s_user_ns, CAP_CHOWN))
     140             :                 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           0 : int setattr_prepare(struct mnt_idmap *idmap, struct dentry *dentry,
     166             :                     struct iattr *attr)
     167             : {
     168           0 :         struct inode *inode = d_inode(dentry);
     169           0 :         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           0 :         if (ia_valid & ATTR_SIZE) {
     176           0 :                 int error = inode_newsize_ok(inode, attr->ia_size);
     177           0 :                 if (error)
     178             :                         return error;
     179             :         }
     180             : 
     181             :         /* If force is set do it anyway. */
     182           0 :         if (ia_valid & ATTR_FORCE)
     183             :                 goto kill_priv;
     184             : 
     185             :         /* Make sure a caller can chown. */
     186           0 :         if ((ia_valid & ATTR_UID) &&
     187           0 :             !chown_ok(idmap, inode, attr->ia_vfsuid))
     188             :                 return -EPERM;
     189             : 
     190             :         /* Make sure caller can chgrp. */
     191           0 :         if ((ia_valid & ATTR_GID) &&
     192           0 :             !chgrp_ok(idmap, inode, attr->ia_vfsgid))
     193             :                 return -EPERM;
     194             : 
     195             :         /* Make sure a caller can chmod. */
     196           0 :         if (ia_valid & ATTR_MODE) {
     197             :                 vfsgid_t vfsgid;
     198             : 
     199           0 :                 if (!inode_owner_or_capable(idmap, inode))
     200           0 :                         return -EPERM;
     201             : 
     202           0 :                 if (ia_valid & ATTR_GID)
     203           0 :                         vfsgid = attr->ia_vfsgid;
     204             :                 else
     205             :                         vfsgid = i_gid_into_vfsgid(idmap, inode);
     206             : 
     207             :                 /* Also check the setgid bit! */
     208           0 :                 if (!in_group_or_capable(idmap, inode, vfsgid))
     209           0 :                         attr->ia_mode &= ~S_ISGID;
     210             :         }
     211             : 
     212             :         /* Check for setting the inode time. */
     213           0 :         if (ia_valid & (ATTR_MTIME_SET | ATTR_ATIME_SET | ATTR_TIMES_SET)) {
     214           0 :                 if (!inode_owner_or_capable(idmap, inode))
     215             :                         return -EPERM;
     216             :         }
     217             : 
     218             : kill_priv:
     219             :         /* User has permission for the change */
     220           0 :         if (ia_valid & ATTR_KILL_PRIV) {
     221             :                 int error;
     222             : 
     223           0 :                 error = security_inode_killpriv(idmap, dentry);
     224           0 :                 if (error)
     225             :                         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           0 : int inode_newsize_ok(const struct inode *inode, loff_t offset)
     249             : {
     250           0 :         if (offset < 0)
     251             :                 return -EINVAL;
     252           0 :         if (inode->i_size < offset) {
     253             :                 unsigned long limit;
     254             : 
     255           0 :                 limit = rlimit(RLIMIT_FSIZE);
     256           0 :                 if (limit != RLIM_INFINITY && offset > limit)
     257             :                         goto out_sig;
     258           0 :                 if (offset > inode->i_sb->s_maxbytes)
     259             :                         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           0 :                 if (IS_SWAPFILE(inode))
     267             :                         return -ETXTBSY;
     268             :         }
     269             : 
     270             :         return 0;
     271             : out_sig:
     272           0 :         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           0 : void setattr_copy(struct mnt_idmap *idmap, struct inode *inode,
     304             :                   const struct iattr *attr)
     305             : {
     306           0 :         unsigned int ia_valid = attr->ia_valid;
     307             : 
     308           0 :         i_uid_update(idmap, attr, inode);
     309           0 :         i_gid_update(idmap, attr, inode);
     310           0 :         if (ia_valid & ATTR_ATIME)
     311           0 :                 inode->i_atime = attr->ia_atime;
     312           0 :         if (ia_valid & ATTR_MTIME)
     313           0 :                 inode->i_mtime = attr->ia_mtime;
     314           0 :         if (ia_valid & ATTR_CTIME)
     315           0 :                 inode->i_ctime = attr->ia_ctime;
     316           0 :         if (ia_valid & ATTR_MODE) {
     317           0 :                 umode_t mode = attr->ia_mode;
     318           0 :                 if (!in_group_or_capable(idmap, inode,
     319             :                                          i_gid_into_vfsgid(idmap, inode)))
     320           0 :                         mode &= ~S_ISGID;
     321           0 :                 inode->i_mode = mode;
     322             :         }
     323           0 : }
     324             : EXPORT_SYMBOL(setattr_copy);
     325             : 
     326           0 : int may_setattr(struct mnt_idmap *idmap, struct inode *inode,
     327             :                 unsigned int ia_valid)
     328             : {
     329             :         int error;
     330             : 
     331           0 :         if (ia_valid & (ATTR_MODE | ATTR_UID | ATTR_GID | ATTR_TIMES_SET)) {
     332           0 :                 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           0 :         if (ia_valid & ATTR_TOUCH) {
     341           0 :                 if (IS_IMMUTABLE(inode))
     342             :                         return -EPERM;
     343             : 
     344           0 :                 if (!inode_owner_or_capable(idmap, inode)) {
     345           0 :                         error = inode_permission(idmap, inode, MAY_WRITE);
     346           0 :                         if (error)
     347             :                                 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           0 : int notify_change(struct mnt_idmap *idmap, struct dentry *dentry,
     382             :                   struct iattr *attr, struct inode **delegated_inode)
     383             : {
     384           0 :         struct inode *inode = dentry->d_inode;
     385           0 :         umode_t mode = inode->i_mode;
     386             :         int error;
     387             :         struct timespec64 now;
     388           0 :         unsigned int ia_valid = attr->ia_valid;
     389             : 
     390           0 :         WARN_ON_ONCE(!inode_is_locked(inode));
     391             : 
     392           0 :         error = may_setattr(idmap, inode, ia_valid);
     393           0 :         if (error)
     394             :                 return error;
     395             : 
     396           0 :         if ((ia_valid & ATTR_MODE)) {
     397           0 :                 umode_t amode = attr->ia_mode;
     398             :                 /* Flag setting protected by i_mutex */
     399           0 :                 if (is_sxid(amode))
     400           0 :                         inode->i_flags &= ~S_NOSEC;
     401             :         }
     402             : 
     403           0 :         now = current_time(inode);
     404             : 
     405           0 :         attr->ia_ctime = now;
     406           0 :         if (!(ia_valid & ATTR_ATIME_SET))
     407           0 :                 attr->ia_atime = now;
     408             :         else
     409           0 :                 attr->ia_atime = timestamp_truncate(attr->ia_atime, inode);
     410           0 :         if (!(ia_valid & ATTR_MTIME_SET))
     411           0 :                 attr->ia_mtime = now;
     412             :         else
     413           0 :                 attr->ia_mtime = timestamp_truncate(attr->ia_mtime, inode);
     414             : 
     415           0 :         if (ia_valid & ATTR_KILL_PRIV) {
     416           0 :                 error = security_inode_need_killpriv(dentry);
     417           0 :                 if (error < 0)
     418             :                         return error;
     419           0 :                 if (error == 0)
     420           0 :                         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           0 :         if ((ia_valid & (ATTR_KILL_SUID|ATTR_KILL_SGID)) &&
     431           0 :             (ia_valid & ATTR_MODE))
     432           0 :                 BUG();
     433             : 
     434           0 :         if (ia_valid & ATTR_KILL_SUID) {
     435           0 :                 if (mode & S_ISUID) {
     436           0 :                         ia_valid = attr->ia_valid |= ATTR_MODE;
     437           0 :                         attr->ia_mode = (inode->i_mode & ~S_ISUID);
     438             :                 }
     439             :         }
     440           0 :         if (ia_valid & ATTR_KILL_SGID) {
     441           0 :                 if (mode & S_ISGID) {
     442           0 :                         if (!(ia_valid & ATTR_MODE)) {
     443           0 :                                 ia_valid = attr->ia_valid |= ATTR_MODE;
     444           0 :                                 attr->ia_mode = inode->i_mode;
     445             :                         }
     446           0 :                         attr->ia_mode &= ~S_ISGID;
     447             :                 }
     448             :         }
     449           0 :         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           0 :         if (ia_valid & ATTR_UID &&
     457           0 :             !vfsuid_has_fsmapping(idmap, inode->i_sb->s_user_ns,
     458             :                                   attr->ia_vfsuid))
     459             :                 return -EOVERFLOW;
     460           0 :         if (ia_valid & ATTR_GID &&
     461           0 :             !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           0 :         if (!(ia_valid & ATTR_UID) &&
     469           0 :             !vfsuid_valid(i_uid_into_vfsuid(idmap, inode)))
     470             :                 return -EOVERFLOW;
     471           0 :         if (!(ia_valid & ATTR_GID) &&
     472           0 :             !vfsgid_valid(i_gid_into_vfsgid(idmap, inode)))
     473             :                 return -EOVERFLOW;
     474             : 
     475           0 :         error = security_inode_setattr(idmap, dentry, attr);
     476             :         if (error)
     477             :                 return error;
     478           0 :         error = try_break_deleg(inode, delegated_inode);
     479           0 :         if (error)
     480             :                 return error;
     481             : 
     482           0 :         if (inode->i_op->setattr)
     483           0 :                 error = inode->i_op->setattr(idmap, dentry, attr);
     484             :         else
     485           0 :                 error = simple_setattr(idmap, dentry, attr);
     486             : 
     487           0 :         if (!error) {
     488           0 :                 fsnotify_change(dentry, ia_valid);
     489           0 :                 ima_inode_post_setattr(idmap, dentry);
     490           0 :                 evm_inode_post_setattr(dentry, ia_valid);
     491             :         }
     492             : 
     493             :         return error;
     494             : }
     495             : EXPORT_SYMBOL(notify_change);

Generated by: LCOV version 1.14