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

Generated by: LCOV version 1.14