LCOV - code coverage report
Current view: top level - fs - attr.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 88 98 89.8 %
Date: 2014-02-18 Functions: 4 4 100.0 %
Branches: 98 118 83.1 %

           Branch data     Line data    Source code
       1                 :            : /*
       2                 :            :  *  linux/fs/attr.c
       3                 :            :  *
       4                 :            :  *  Copyright (C) 1991, 1992  Linus Torvalds
       5                 :            :  *  changes by Thomas Schoebel-Theuer
       6                 :            :  */
       7                 :            : 
       8                 :            : #include <linux/export.h>
       9                 :            : #include <linux/time.h>
      10                 :            : #include <linux/mm.h>
      11                 :            : #include <linux/string.h>
      12                 :            : #include <linux/capability.h>
      13                 :            : #include <linux/fsnotify.h>
      14                 :            : #include <linux/fcntl.h>
      15                 :            : #include <linux/security.h>
      16                 :            : #include <linux/evm.h>
      17                 :            : #include <linux/ima.h>
      18                 :            : 
      19                 :            : /**
      20                 :            :  * inode_change_ok - check if attribute changes to an inode are allowed
      21                 :            :  * @inode:      inode to check
      22                 :            :  * @attr:       attributes to change
      23                 :            :  *
      24                 :            :  * Check if we are allowed to change the attributes contained in @attr
      25                 :            :  * in the given inode.  This includes the normal unix access permission
      26                 :            :  * checks, as well as checks for rlimits and others.
      27                 :            :  *
      28                 :            :  * Should be called as the first thing in ->setattr implementations,
      29                 :            :  * possibly after taking additional locks.
      30                 :            :  */
      31                 :          0 : int inode_change_ok(const struct inode *inode, struct iattr *attr)
      32                 :            : {
      33                 :      62305 :         unsigned int ia_valid = attr->ia_valid;
      34                 :            : 
      35                 :            :         /*
      36                 :            :          * First check size constraints.  These can't be overriden using
      37                 :            :          * ATTR_FORCE.
      38                 :            :          */
      39         [ +  + ]:      62305 :         if (ia_valid & ATTR_SIZE) {
      40                 :      39507 :                 int error = inode_newsize_ok(inode, attr->ia_size);
      41         [ +  + ]:      39509 :                 if (error)
      42                 :            :                         return error;
      43                 :            :         }
      44                 :            : 
      45                 :            :         /* If force is set do it anyway. */
      46         [ +  - ]:      62303 :         if (ia_valid & ATTR_FORCE)
      47                 :            :                 return 0;
      48                 :            : 
      49                 :            :         /* Make sure a caller can chown. */
      50 [ +  + ][ +  + ]:      62303 :         if ((ia_valid & ATTR_UID) &&
      51         [ +  + ]:       2888 :             (!uid_eq(current_fsuid(), inode->i_uid) ||
      52         [ +  + ]:        144 :              !uid_eq(attr->ia_uid, inode->i_uid)) &&
      53                 :        142 :             !inode_capable(inode, CAP_CHOWN))
      54                 :            :                 return -EPERM;
      55                 :            : 
      56                 :            :         /* Make sure caller can chgrp. */
      57 [ +  + ][ +  + ]:      62301 :         if ((ia_valid & ATTR_GID) &&
      58         [ +  + ]:       3628 :             (!uid_eq(current_fsuid(), inode->i_uid) ||
      59   [ +  +  +  - ]:       4287 :             (!in_group_p(attr->ia_gid) && !gid_eq(attr->ia_gid, inode->i_gid))) &&
      60                 :        344 :             !inode_capable(inode, CAP_CHOWN))
      61                 :            :                 return -EPERM;
      62                 :            : 
      63                 :            :         /* Make sure a caller can chmod. */
      64         [ +  + ]:      62301 :         if (ia_valid & ATTR_MODE) {
      65         [ +  - ]:      17158 :                 if (!inode_owner_or_capable(inode))
      66                 :            :                         return -EPERM;
      67                 :            :                 /* Also check the setgid bit! */
      68 [ +  + ][ +  + ]:      17158 :                 if (!in_group_p((ia_valid & ATTR_GID) ? attr->ia_gid :
      69         [ +  + ]:        244 :                                 inode->i_gid) &&
      70                 :        244 :                     !inode_capable(inode, CAP_FSETID))
      71                 :          2 :                         attr->ia_mode &= ~S_ISGID;
      72                 :            :         }
      73                 :            : 
      74                 :            :         /* Check for setting the inode time. */
      75         [ +  + ]:      62301 :         if (ia_valid & (ATTR_MTIME_SET | ATTR_ATIME_SET | ATTR_TIMES_SET)) {
      76         [ +  + ]:        861 :                 if (!inode_owner_or_capable(inode))
      77                 :            :                         return -EPERM;
      78                 :            :         }
      79                 :            : 
      80                 :            :         return 0;
      81                 :            : }
      82                 :            : EXPORT_SYMBOL(inode_change_ok);
      83                 :            : 
      84                 :            : /**
      85                 :            :  * inode_newsize_ok - may this inode be truncated to a given size
      86                 :            :  * @inode:      the inode to be truncated
      87                 :            :  * @offset:     the new size to assign to the inode
      88                 :            :  * @Returns:    0 on success, -ve errno on failure
      89                 :            :  *
      90                 :            :  * inode_newsize_ok must be called with i_mutex held.
      91                 :            :  *
      92                 :            :  * inode_newsize_ok will check filesystem limits and ulimits to check that the
      93                 :            :  * new inode size is within limits. inode_newsize_ok will also send SIGXFSZ
      94                 :            :  * when necessary. Caller must not proceed with inode size change if failure is
      95                 :            :  * returned. @inode must be a file (not directory), with appropriate
      96                 :            :  * permissions to allow truncate (inode_newsize_ok does NOT check these
      97                 :            :  * conditions).
      98                 :            :  */
      99                 :          0 : int inode_newsize_ok(const struct inode *inode, loff_t offset)
     100                 :            : {
     101         [ +  + ]:      39524 :         if (inode->i_size < offset) {
     102                 :            :                 unsigned long limit;
     103                 :            : 
     104                 :            :                 limit = rlimit(RLIMIT_FSIZE);
     105 [ -  + ][ #  # ]:       1966 :                 if (limit != RLIM_INFINITY && offset > limit)
     106                 :            :                         goto out_sig;
     107         [ +  - ]:       1966 :                 if (offset > inode->i_sb->s_maxbytes)
     108                 :            :                         goto out_big;
     109                 :            :         } else {
     110                 :            :                 /*
     111                 :            :                  * truncation of in-use swapfiles is disallowed - it would
     112                 :            :                  * cause subsequent swapout to scribble on the now-freed
     113                 :            :                  * blocks.
     114                 :            :                  */
     115         [ +  + ]:      37558 :                 if (IS_SWAPFILE(inode))
     116                 :            :                         return -ETXTBSY;
     117                 :            :         }
     118                 :            : 
     119                 :            :         return 0;
     120                 :            : out_sig:
     121                 :          0 :         send_sig(SIGXFSZ, current, 0);
     122                 :            : out_big:
     123                 :            :         return -EFBIG;
     124                 :            : }
     125                 :            : EXPORT_SYMBOL(inode_newsize_ok);
     126                 :            : 
     127                 :            : /**
     128                 :            :  * setattr_copy - copy simple metadata updates into the generic inode
     129                 :            :  * @inode:      the inode to be updated
     130                 :            :  * @attr:       the new attributes
     131                 :            :  *
     132                 :            :  * setattr_copy must be called with i_mutex held.
     133                 :            :  *
     134                 :            :  * setattr_copy updates the inode's metadata with that specified
     135                 :            :  * in attr. Noticeably missing is inode size update, which is more complex
     136                 :            :  * as it requires pagecache updates.
     137                 :            :  *
     138                 :            :  * The inode is not marked as dirty after this operation. The rationale is
     139                 :            :  * that for "simple" filesystems, the struct inode is the inode storage.
     140                 :            :  * The caller is free to mark the inode dirty afterwards if needed.
     141                 :            :  */
     142                 :          0 : void setattr_copy(struct inode *inode, const struct iattr *attr)
     143                 :            : {
     144                 :      62289 :         unsigned int ia_valid = attr->ia_valid;
     145                 :            : 
     146         [ +  + ]:      62289 :         if (ia_valid & ATTR_UID)
     147                 :       2938 :                 inode->i_uid = attr->ia_uid;
     148         [ +  + ]:      62289 :         if (ia_valid & ATTR_GID)
     149                 :       3658 :                 inode->i_gid = attr->ia_gid;
     150         [ +  + ]:      62289 :         if (ia_valid & ATTR_ATIME)
     151                 :       2042 :                 inode->i_atime = timespec_trunc(attr->ia_atime,
     152                 :       2042 :                                                 inode->i_sb->s_time_gran);
     153         [ +  + ]:     124578 :         if (ia_valid & ATTR_MTIME)
     154                 :      39851 :                 inode->i_mtime = timespec_trunc(attr->ia_mtime,
     155                 :      39851 :                                                 inode->i_sb->s_time_gran);
     156         [ +  + ]:      62289 :         if (ia_valid & ATTR_CTIME)
     157                 :      60473 :                 inode->i_ctime = timespec_trunc(attr->ia_ctime,
     158                 :      60473 :                                                 inode->i_sb->s_time_gran);
     159         [ +  + ]:      62289 :         if (ia_valid & ATTR_MODE) {
     160                 :      17158 :                 umode_t mode = attr->ia_mode;
     161                 :            : 
     162   [ +  +  +  + ]:      17402 :                 if (!in_group_p(inode->i_gid) &&
     163                 :        244 :                     !inode_capable(inode, CAP_FSETID))
     164                 :          2 :                         mode &= ~S_ISGID;
     165                 :      17158 :                 inode->i_mode = mode;
     166                 :            :         }
     167                 :      62289 : }
     168                 :            : EXPORT_SYMBOL(setattr_copy);
     169                 :            : 
     170                 :            : /**
     171                 :            :  * notify_change - modify attributes of a filesytem object
     172                 :            :  * @dentry:     object affected
     173                 :            :  * @iattr:      new attributes
     174                 :            :  * @delegated_inode: returns inode, if the inode is delegated
     175                 :            :  *
     176                 :            :  * The caller must hold the i_mutex on the affected object.
     177                 :            :  *
     178                 :            :  * If notify_change discovers a delegation in need of breaking,
     179                 :            :  * it will return -EWOULDBLOCK and return a reference to the inode in
     180                 :            :  * delegated_inode.  The caller should then break the delegation and
     181                 :            :  * retry.  Because breaking a delegation may take a long time, the
     182                 :            :  * caller should drop the i_mutex before doing so.
     183                 :            :  *
     184                 :            :  * Alternatively, a caller may pass NULL for delegated_inode.  This may
     185                 :            :  * be appropriate for callers that expect the underlying filesystem not
     186                 :            :  * to be NFS exported.  Also, passing NULL is fine for callers holding
     187                 :            :  * the file open for write, as there can be no conflicting delegation in
     188                 :            :  * that case.
     189                 :            :  */
     190                 :          0 : int notify_change(struct dentry * dentry, struct iattr * attr, struct inode **delegated_inode)
     191                 :            : {
     192                 :      62323 :         struct inode *inode = dentry->d_inode;
     193                 :      62323 :         umode_t mode = inode->i_mode;
     194                 :            :         int error;
     195                 :            :         struct timespec now;
     196                 :      62323 :         unsigned int ia_valid = attr->ia_valid;
     197                 :            : 
     198 [ -  + ][ #  # ]:      62323 :         WARN_ON_ONCE(!mutex_is_locked(&inode->i_mutex));
                 [ -  + ]
     199                 :            : 
     200         [ +  + ]:      62326 :         if (ia_valid & (ATTR_MODE | ATTR_UID | ATTR_GID | ATTR_TIMES_SET)) {
     201         [ +  + ]:      21616 :                 if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
     202                 :            :                         return -EPERM;
     203                 :            :         }
     204                 :            : 
     205 [ +  + ][ -  + ]:      62305 :         if ((ia_valid & ATTR_SIZE) && IS_I_VERSION(inode)) {
     206         [ #  # ]:          0 :                 if (attr->ia_size != inode->i_size)
     207                 :            :                         inode_inc_iversion(inode);
     208                 :            :         }
     209                 :            : 
     210         [ +  + ]:      62305 :         if ((ia_valid & ATTR_MODE)) {
     211                 :      17148 :                 umode_t amode = attr->ia_mode;
     212                 :            :                 /* Flag setting protected by i_mutex */
     213         [ +  + ]:      17148 :                 if (is_sxid(amode))
     214                 :         32 :                         inode->i_flags &= ~S_NOSEC;
     215                 :            :         }
     216                 :            : 
     217                 :      62305 :         now = current_fs_time(inode->i_sb);
     218                 :            : 
     219                 :      62305 :         attr->ia_ctime = now;
     220         [ +  + ]:      62305 :         if (!(ia_valid & ATTR_ATIME_SET))
     221                 :      61454 :                 attr->ia_atime = now;
     222         [ +  + ]:      62305 :         if (!(ia_valid & ATTR_MTIME_SET))
     223                 :      61453 :                 attr->ia_mtime = now;
     224         [ +  + ]:      62305 :         if (ia_valid & ATTR_KILL_PRIV) {
     225                 :       2791 :                 attr->ia_valid &= ~ATTR_KILL_PRIV;
     226                 :       2791 :                 ia_valid &= ~ATTR_KILL_PRIV;
     227                 :       2791 :                 error = security_inode_need_killpriv(dentry);
     228         [ -  + ]:       2791 :                 if (error > 0)
     229                 :          0 :                         error = security_inode_killpriv(dentry);
     230         [ +  - ]:       2790 :                 if (error)
     231                 :            :                         return error;
     232                 :            :         }
     233                 :            : 
     234                 :            :         /*
     235                 :            :          * We now pass ATTR_KILL_S*ID to the lower level setattr function so
     236                 :            :          * that the function has the ability to reinterpret a mode change
     237                 :            :          * that's due to these bits. This adds an implicit restriction that
     238                 :            :          * no function will ever call notify_change with both ATTR_MODE and
     239                 :            :          * ATTR_KILL_S*ID set.
     240                 :            :          */
     241 [ +  + ][ -  + ]:      62304 :         if ((ia_valid & (ATTR_KILL_SUID|ATTR_KILL_SGID)) &&
     242                 :       2791 :             (ia_valid & ATTR_MODE))
     243                 :          0 :                 BUG();
     244                 :            : 
     245         [ +  + ]:      62304 :         if (ia_valid & ATTR_KILL_SUID) {
     246         [ +  + ]:       2791 :                 if (mode & S_ISUID) {
     247                 :         10 :                         ia_valid = attr->ia_valid |= ATTR_MODE;
     248                 :         10 :                         attr->ia_mode = (inode->i_mode & ~S_ISUID);
     249                 :            :                 }
     250                 :            :         }
     251         [ +  + ]:      62304 :         if (ia_valid & ATTR_KILL_SGID) {
     252         [ +  + ]:       2791 :                 if ((mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP)) {
     253         [ -  + ]:          8 :                         if (!(ia_valid & ATTR_MODE)) {
     254                 :          0 :                                 ia_valid = attr->ia_valid |= ATTR_MODE;
     255                 :          0 :                                 attr->ia_mode = inode->i_mode;
     256                 :            :                         }
     257                 :          8 :                         attr->ia_mode &= ~S_ISGID;
     258                 :            :                 }
     259                 :            :         }
     260         [ +  - ]:      62304 :         if (!(attr->ia_valid & ~(ATTR_KILL_SUID | ATTR_KILL_SGID)))
     261                 :            :                 return 0;
     262                 :            : 
     263                 :      62304 :         error = security_inode_setattr(dentry, attr);
     264         [ +  + ]:      62300 :         if (error)
     265                 :            :                 return error;
     266                 :            :         error = try_break_deleg(inode, delegated_inode);
     267         [ +  - ]:      62305 :         if (error)
     268                 :            :                 return error;
     269                 :            : 
     270         [ +  + ]:      62305 :         if (inode->i_op->setattr)
     271                 :      62113 :                 error = inode->i_op->setattr(dentry, attr);
     272                 :            :         else
     273                 :        192 :                 error = simple_setattr(dentry, attr);
     274                 :            : 
     275         [ +  + ]:     124628 :         if (!error) {
     276                 :            :                 fsnotify_change(dentry, ia_valid);
     277                 :            :                 ima_inode_post_setattr(dentry);
     278                 :            :                 evm_inode_post_setattr(dentry, ia_valid);
     279                 :            :         }
     280                 :            : 
     281                 :      62305 :         return error;
     282                 :            : }
     283                 :            : EXPORT_SYMBOL(notify_change);

Generated by: LCOV version 1.9