LCOV - code coverage report
Current view: top level - fs - attr.c (source / functions) Hit Total Coverage
Test: combined.info Lines: 98 127 77.2 %
Date: 2022-04-01 14:35:51 Functions: 6 6 100.0 %
Branches: 98 152 64.5 %

           Branch data     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/security.h>
      18                 :            : #include <linux/evm.h>
      19                 :            : #include <linux/ima.h>
      20                 :            : 
      21                 :       5196 : static bool chown_ok(const struct inode *inode, kuid_t uid)
      22                 :            : {
      23   [ +  -  +  + ]:       5196 :         if (uid_eq(current_fsuid(), inode->i_uid) &&
      24                 :            :             uid_eq(uid, inode->i_uid))
      25                 :            :                 return true;
      26         [ -  + ]:         42 :         if (capable_wrt_inode_uidgid(inode, CAP_CHOWN))
      27                 :            :                 return true;
      28   [ #  #  #  # ]:          0 :         if (uid_eq(inode->i_uid, INVALID_UID) &&
      29                 :          0 :             ns_capable(inode->i_sb->s_user_ns, CAP_CHOWN))
      30                 :          0 :                 return true;
      31                 :            :         return false;
      32                 :            : }
      33                 :            : 
      34                 :       5196 : static bool chgrp_ok(const struct inode *inode, kgid_t gid)
      35                 :            : {
      36   [ +  -  +  + ]:      10392 :         if (uid_eq(current_fsuid(), inode->i_uid) &&
      37         [ +  - ]:       7569 :             (in_group_p(gid) || gid_eq(gid, inode->i_gid)))
      38                 :            :                 return true;
      39         [ -  + ]:       2373 :         if (capable_wrt_inode_uidgid(inode, CAP_CHOWN))
      40                 :            :                 return true;
      41   [ #  #  #  # ]:          0 :         if (gid_eq(inode->i_gid, INVALID_GID) &&
      42                 :          0 :             ns_capable(inode->i_sb->s_user_ns, CAP_CHOWN))
      43                 :          0 :                 return true;
      44                 :            :         return false;
      45                 :            : }
      46                 :            : 
      47                 :            : /**
      48                 :            :  * setattr_prepare - check if attribute changes to a dentry are allowed
      49                 :            :  * @dentry:     dentry to check
      50                 :            :  * @attr:       attributes to change
      51                 :            :  *
      52                 :            :  * Check if we are allowed to change the attributes contained in @attr
      53                 :            :  * in the given dentry.  This includes the normal unix access permission
      54                 :            :  * checks, as well as checks for rlimits and others. The function also clears
      55                 :            :  * SGID bit from mode if user is not allowed to set it. Also file capabilities
      56                 :            :  * and IMA extended attributes are cleared if ATTR_KILL_PRIV is set.
      57                 :            :  *
      58                 :            :  * Should be called as the first thing in ->setattr implementations,
      59                 :            :  * possibly after taking additional locks.
      60                 :            :  */
      61                 :      18116 : int setattr_prepare(struct dentry *dentry, struct iattr *attr)
      62                 :            : {
      63         [ +  + ]:      18116 :         struct inode *inode = d_inode(dentry);
      64                 :      18116 :         unsigned int ia_valid = attr->ia_valid;
      65                 :            : 
      66                 :            :         /*
      67                 :            :          * First check size constraints.  These can't be overriden using
      68                 :            :          * ATTR_FORCE.
      69                 :            :          */
      70         [ +  + ]:      18116 :         if (ia_valid & ATTR_SIZE) {
      71                 :        257 :                 int error = inode_newsize_ok(inode, attr->ia_size);
      72         [ +  - ]:        257 :                 if (error)
      73                 :            :                         return error;
      74                 :            :         }
      75                 :            : 
      76                 :            :         /* If force is set do it anyway. */
      77         [ -  + ]:      18116 :         if (ia_valid & ATTR_FORCE)
      78                 :          0 :                 goto kill_priv;
      79                 :            : 
      80                 :            :         /* Make sure a caller can chown. */
      81   [ +  +  +  - ]:      18116 :         if ((ia_valid & ATTR_UID) && !chown_ok(inode, attr->ia_uid))
      82                 :            :                 return -EPERM;
      83                 :            : 
      84                 :            :         /* Make sure caller can chgrp. */
      85   [ +  +  +  - ]:      18116 :         if ((ia_valid & ATTR_GID) && !chgrp_ok(inode, attr->ia_gid))
      86                 :            :                 return -EPERM;
      87                 :            : 
      88                 :            :         /* Make sure a caller can chmod. */
      89         [ +  + ]:      18116 :         if (ia_valid & ATTR_MODE) {
      90         [ +  - ]:       9405 :                 if (!inode_owner_or_capable(inode))
      91                 :            :                         return -EPERM;
      92                 :            :                 /* Also check the setgid bit! */
      93   [ +  +  -  + ]:       9405 :                 if (!in_group_p((ia_valid & ATTR_GID) ? attr->ia_gid :
      94         [ #  # ]:          0 :                                 inode->i_gid) &&
      95                 :          0 :                     !capable_wrt_inode_uidgid(inode, CAP_FSETID))
      96                 :          0 :                         attr->ia_mode &= ~S_ISGID;
      97                 :            :         }
      98                 :            : 
      99                 :            :         /* Check for setting the inode time. */
     100         [ +  + ]:      18116 :         if (ia_valid & (ATTR_MTIME_SET | ATTR_ATIME_SET | ATTR_TIMES_SET)) {
     101         [ +  - ]:        168 :                 if (!inode_owner_or_capable(inode))
     102                 :            :                         return -EPERM;
     103                 :            :         }
     104                 :            : 
     105                 :      18116 : kill_priv:
     106                 :            :         /* User has permission for the change */
     107         [ -  + ]:      18116 :         if (ia_valid & ATTR_KILL_PRIV) {
     108                 :          0 :                 int error;
     109                 :            : 
     110                 :          0 :                 error = security_inode_killpriv(dentry);
     111         [ #  # ]:          0 :                 if (error)
     112                 :          0 :                         return error;
     113                 :            :         }
     114                 :            : 
     115                 :            :         return 0;
     116                 :            : }
     117                 :            : EXPORT_SYMBOL(setattr_prepare);
     118                 :            : 
     119                 :            : /**
     120                 :            :  * inode_newsize_ok - may this inode be truncated to a given size
     121                 :            :  * @inode:      the inode to be truncated
     122                 :            :  * @offset:     the new size to assign to the inode
     123                 :            :  *
     124                 :            :  * inode_newsize_ok must be called with i_mutex held.
     125                 :            :  *
     126                 :            :  * inode_newsize_ok will check filesystem limits and ulimits to check that the
     127                 :            :  * new inode size is within limits. inode_newsize_ok will also send SIGXFSZ
     128                 :            :  * when necessary. Caller must not proceed with inode size change if failure is
     129                 :            :  * returned. @inode must be a file (not directory), with appropriate
     130                 :            :  * permissions to allow truncate (inode_newsize_ok does NOT check these
     131                 :            :  * conditions).
     132                 :            :  *
     133                 :            :  * Return: 0 on success, -ve errno on failure
     134                 :            :  */
     135                 :        299 : int inode_newsize_ok(const struct inode *inode, loff_t offset)
     136                 :            : {
     137         [ +  + ]:        299 :         if (inode->i_size < offset) {
     138                 :         42 :                 unsigned long limit;
     139                 :            : 
     140         [ -  + ]:         42 :                 limit = rlimit(RLIMIT_FSIZE);
     141         [ -  + ]:         42 :                 if (limit != RLIM_INFINITY && offset > limit)
     142                 :          0 :                         goto out_sig;
     143         [ -  + ]:         42 :                 if (offset > inode->i_sb->s_maxbytes)
     144                 :          0 :                         goto out_big;
     145                 :            :         } else {
     146                 :            :                 /*
     147                 :            :                  * truncation of in-use swapfiles is disallowed - it would
     148                 :            :                  * cause subsequent swapout to scribble on the now-freed
     149                 :            :                  * blocks.
     150                 :            :                  */
     151         [ -  + ]:        257 :                 if (IS_SWAPFILE(inode))
     152                 :          0 :                         return -ETXTBSY;
     153                 :            :         }
     154                 :            : 
     155                 :            :         return 0;
     156                 :            : out_sig:
     157                 :          0 :         send_sig(SIGXFSZ, current, 0);
     158                 :            : out_big:
     159                 :            :         return -EFBIG;
     160                 :            : }
     161                 :            : EXPORT_SYMBOL(inode_newsize_ok);
     162                 :            : 
     163                 :            : /**
     164                 :            :  * setattr_copy - copy simple metadata updates into the generic inode
     165                 :            :  * @inode:      the inode to be updated
     166                 :            :  * @attr:       the new attributes
     167                 :            :  *
     168                 :            :  * setattr_copy must be called with i_mutex held.
     169                 :            :  *
     170                 :            :  * setattr_copy updates the inode's metadata with that specified
     171                 :            :  * in attr. Noticeably missing is inode size update, which is more complex
     172                 :            :  * as it requires pagecache updates.
     173                 :            :  *
     174                 :            :  * The inode is not marked as dirty after this operation. The rationale is
     175                 :            :  * that for "simple" filesystems, the struct inode is the inode storage.
     176                 :            :  * The caller is free to mark the inode dirty afterwards if needed.
     177                 :            :  */
     178                 :      18116 : void setattr_copy(struct inode *inode, const struct iattr *attr)
     179                 :            : {
     180                 :      18116 :         unsigned int ia_valid = attr->ia_valid;
     181                 :            : 
     182         [ +  + ]:      18116 :         if (ia_valid & ATTR_UID)
     183                 :       5196 :                 inode->i_uid = attr->ia_uid;
     184         [ +  + ]:      18116 :         if (ia_valid & ATTR_GID)
     185                 :       5196 :                 inode->i_gid = attr->ia_gid;
     186         [ +  + ]:      18116 :         if (ia_valid & ATTR_ATIME)
     187                 :       5850 :                 inode->i_atime = attr->ia_atime;
     188         [ +  + ]:      18116 :         if (ia_valid & ATTR_MTIME)
     189                 :       6107 :                 inode->i_mtime = attr->ia_mtime;
     190         [ +  + ]:      18116 :         if (ia_valid & ATTR_CTIME)
     191                 :      15524 :                 inode->i_ctime = attr->ia_ctime;
     192         [ +  + ]:      18116 :         if (ia_valid & ATTR_MODE) {
     193                 :       9405 :                 umode_t mode = attr->ia_mode;
     194                 :            : 
     195   [ -  +  -  - ]:       9405 :                 if (!in_group_p(inode->i_gid) &&
     196                 :          0 :                     !capable_wrt_inode_uidgid(inode, CAP_FSETID))
     197                 :          0 :                         mode &= ~S_ISGID;
     198                 :       9405 :                 inode->i_mode = mode;
     199                 :            :         }
     200                 :      18116 : }
     201                 :            : EXPORT_SYMBOL(setattr_copy);
     202                 :            : 
     203                 :            : /**
     204                 :            :  * notify_change - modify attributes of a filesytem object
     205                 :            :  * @dentry:     object affected
     206                 :            :  * @attr:       new attributes
     207                 :            :  * @delegated_inode: returns inode, if the inode is delegated
     208                 :            :  *
     209                 :            :  * The caller must hold the i_mutex on the affected object.
     210                 :            :  *
     211                 :            :  * If notify_change discovers a delegation in need of breaking,
     212                 :            :  * it will return -EWOULDBLOCK and return a reference to the inode in
     213                 :            :  * delegated_inode.  The caller should then break the delegation and
     214                 :            :  * retry.  Because breaking a delegation may take a long time, the
     215                 :            :  * caller should drop the i_mutex before doing so.
     216                 :            :  *
     217                 :            :  * Alternatively, a caller may pass NULL for delegated_inode.  This may
     218                 :            :  * be appropriate for callers that expect the underlying filesystem not
     219                 :            :  * to be NFS exported.  Also, passing NULL is fine for callers holding
     220                 :            :  * the file open for write, as there can be no conflicting delegation in
     221                 :            :  * that case.
     222                 :            :  */
     223                 :      18116 : int notify_change(struct dentry * dentry, struct iattr * attr, struct inode **delegated_inode)
     224                 :            : {
     225                 :      18116 :         struct inode *inode = dentry->d_inode;
     226                 :      18116 :         umode_t mode = inode->i_mode;
     227                 :      18116 :         int error;
     228                 :      18116 :         struct timespec64 now;
     229                 :      18116 :         unsigned int ia_valid = attr->ia_valid;
     230                 :            : 
     231         [ -  + ]:      18116 :         WARN_ON_ONCE(!inode_is_locked(inode));
     232                 :            : 
     233         [ +  + ]:      18116 :         if (ia_valid & (ATTR_MODE | ATTR_UID | ATTR_GID | ATTR_TIMES_SET)) {
     234         [ +  - ]:      12177 :                 if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
     235                 :            :                         return -EPERM;
     236                 :            :         }
     237                 :            : 
     238                 :            :         /*
     239                 :            :          * If utimes(2) and friends are called with times == NULL (or both
     240                 :            :          * times are UTIME_NOW), then we need to check for write permission
     241                 :            :          */
     242         [ +  + ]:      18116 :         if (ia_valid & ATTR_TOUCH) {
     243         [ +  - ]:       5682 :                 if (IS_IMMUTABLE(inode))
     244                 :            :                         return -EPERM;
     245                 :            : 
     246         [ -  + ]:       5682 :                 if (!inode_owner_or_capable(inode)) {
     247                 :          0 :                         error = inode_permission(inode, MAY_WRITE);
     248         [ #  # ]:          0 :                         if (error)
     249                 :            :                                 return error;
     250                 :            :                 }
     251                 :            :         }
     252                 :            : 
     253         [ +  + ]:      18116 :         if ((ia_valid & ATTR_MODE)) {
     254                 :       9405 :                 umode_t amode = attr->ia_mode;
     255                 :            :                 /* Flag setting protected by i_mutex */
     256   [ +  -  +  + ]:      18810 :                 if (is_sxid(amode))
     257                 :         21 :                         inode->i_flags &= ~S_NOSEC;
     258                 :            :         }
     259                 :            : 
     260                 :      18116 :         now = current_time(inode);
     261                 :            : 
     262                 :      18116 :         attr->ia_ctime = now;
     263         [ +  + ]:      18116 :         if (!(ia_valid & ATTR_ATIME_SET))
     264                 :      17948 :                 attr->ia_atime = now;
     265                 :            :         else
     266                 :        168 :                 attr->ia_atime = timestamp_truncate(attr->ia_atime, inode);
     267         [ +  + ]:      18116 :         if (!(ia_valid & ATTR_MTIME_SET))
     268                 :      17948 :                 attr->ia_mtime = now;
     269                 :            :         else
     270                 :        168 :                 attr->ia_mtime = timestamp_truncate(attr->ia_mtime, inode);
     271                 :            : 
     272         [ +  + ]:      18116 :         if (ia_valid & ATTR_KILL_PRIV) {
     273                 :       2499 :                 error = security_inode_need_killpriv(dentry);
     274         [ +  - ]:       2499 :                 if (error < 0)
     275                 :            :                         return error;
     276         [ +  - ]:       2499 :                 if (error == 0)
     277                 :       2499 :                         ia_valid = attr->ia_valid &= ~ATTR_KILL_PRIV;
     278                 :            :         }
     279                 :            : 
     280                 :            :         /*
     281                 :            :          * We now pass ATTR_KILL_S*ID to the lower level setattr function so
     282                 :            :          * that the function has the ability to reinterpret a mode change
     283                 :            :          * that's due to these bits. This adds an implicit restriction that
     284                 :            :          * no function will ever call notify_change with both ATTR_MODE and
     285                 :            :          * ATTR_KILL_S*ID set.
     286                 :            :          */
     287         [ +  + ]:      18116 :         if ((ia_valid & (ATTR_KILL_SUID|ATTR_KILL_SGID)) &&
     288         [ -  + ]:       2499 :             (ia_valid & ATTR_MODE))
     289                 :          0 :                 BUG();
     290                 :            : 
     291         [ +  + ]:      18116 :         if (ia_valid & ATTR_KILL_SUID) {
     292         [ -  + ]:       2499 :                 if (mode & S_ISUID) {
     293                 :          0 :                         ia_valid = attr->ia_valid |= ATTR_MODE;
     294                 :          0 :                         attr->ia_mode = (inode->i_mode & ~S_ISUID);
     295                 :            :                 }
     296                 :            :         }
     297         [ +  + ]:      18116 :         if (ia_valid & ATTR_KILL_SGID) {
     298         [ -  + ]:       2499 :                 if ((mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP)) {
     299         [ #  # ]:          0 :                         if (!(ia_valid & ATTR_MODE)) {
     300                 :          0 :                                 ia_valid = attr->ia_valid |= ATTR_MODE;
     301                 :          0 :                                 attr->ia_mode = inode->i_mode;
     302                 :            :                         }
     303                 :          0 :                         attr->ia_mode &= ~S_ISGID;
     304                 :            :                 }
     305                 :            :         }
     306         [ +  - ]:      18116 :         if (!(attr->ia_valid & ~(ATTR_KILL_SUID | ATTR_KILL_SGID)))
     307                 :            :                 return 0;
     308                 :            : 
     309                 :            :         /*
     310                 :            :          * Verify that uid/gid changes are valid in the target
     311                 :            :          * namespace of the superblock.
     312                 :            :          */
     313   [ +  +  +  - ]:      18116 :         if (ia_valid & ATTR_UID &&
     314                 :            :             !kuid_has_mapping(inode->i_sb->s_user_ns, attr->ia_uid))
     315                 :            :                 return -EOVERFLOW;
     316   [ +  +  +  - ]:      18116 :         if (ia_valid & ATTR_GID &&
     317                 :            :             !kgid_has_mapping(inode->i_sb->s_user_ns, attr->ia_gid))
     318                 :            :                 return -EOVERFLOW;
     319                 :            : 
     320                 :            :         /* Don't allow modifications of files with invalid uids or
     321                 :            :          * gids unless those uids & gids are being made valid.
     322                 :            :          */
     323   [ +  +  +  - ]:      18116 :         if (!(ia_valid & ATTR_UID) && !uid_valid(inode->i_uid))
     324                 :            :                 return -EOVERFLOW;
     325   [ +  +  +  - ]:      18116 :         if (!(ia_valid & ATTR_GID) && !gid_valid(inode->i_gid))
     326                 :            :                 return -EOVERFLOW;
     327                 :            : 
     328                 :      18116 :         error = security_inode_setattr(dentry, attr);
     329         [ +  - ]:      18116 :         if (error)
     330                 :            :                 return error;
     331                 :      18116 :         error = try_break_deleg(inode, delegated_inode);
     332         [ +  - ]:      18116 :         if (error)
     333                 :            :                 return error;
     334                 :            : 
     335         [ +  + ]:      18116 :         if (inode->i_op->setattr)
     336                 :      17927 :                 error = inode->i_op->setattr(dentry, attr);
     337                 :            :         else
     338                 :        189 :                 error = simple_setattr(dentry, attr);
     339                 :            : 
     340         [ +  - ]:      18116 :         if (!error) {
     341                 :      18116 :                 fsnotify_change(dentry, ia_valid);
     342                 :      18116 :                 ima_inode_post_setattr(dentry);
     343                 :      18116 :                 evm_inode_post_setattr(dentry, ia_valid);
     344                 :            :         }
     345                 :            : 
     346                 :            :         return error;
     347                 :            : }
     348                 :            : EXPORT_SYMBOL(notify_change);

Generated by: LCOV version 1.14