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/module.h> 9 #include <linux/time.h> 10 #include <linux/mm.h> 11 #include <linux/string.h> 12 #include <linux/smp_lock.h> 13 #include <linux/fsnotify.h> 14 #include <linux/fcntl.h> 15 #include <linux/quotaops.h> 16 #include <linux/security.h> 17 #include <linux/time.h> 18 19 /* Taken over from the old code... */ 20 21 /* POSIX UID/GID verification for setting inode attributes. */ 22 int inode_change_ok(struct inode *inode, struct iattr *attr) 23 { 24 int retval = -EPERM; 25 unsigned int ia_valid = attr->ia_valid; 26 27 /* If force is set do it anyway. */ 28 if (ia_valid & ATTR_FORCE) 29 goto fine; 30 31 /* Make sure a caller can chown. */ 32 if ((ia_valid & ATTR_UID) && 33 (current->fsuid != inode->i_uid || 34 attr->ia_uid != inode->i_uid) && !capable(CAP_CHOWN)) 35 goto error; 36 37 /* Make sure caller can chgrp. */ 38 if ((ia_valid & ATTR_GID) && 39 (current->fsuid != inode->i_uid || 40 (!in_group_p(attr->ia_gid) && attr->ia_gid != inode->i_gid)) && 41 !capable(CAP_CHOWN)) 42 goto error; 43 44 /* Make sure a caller can chmod. */ 45 if (ia_valid & ATTR_MODE) { 46 if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER)) 47 goto error; 48 /* Also check the setgid bit! */ 49 if (!in_group_p((ia_valid & ATTR_GID) ? attr->ia_gid : 50 inode->i_gid) && !capable(CAP_FSETID)) 51 attr->ia_mode &= ~S_ISGID; 52 } 53 54 /* Check for setting the inode time. */ 55 if (ia_valid & (ATTR_MTIME_SET | ATTR_ATIME_SET)) { 56 if (current->fsuid != inode->i_uid && !capable(CAP_FOWNER)) 57 goto error; 58 } 59 fine: 60 retval = 0; 61 error: 62 return retval; 63 } 64 65 EXPORT_SYMBOL(inode_change_ok); 66 67 int inode_setattr(struct inode * inode, struct iattr * attr) 68 { 69 unsigned int ia_valid = attr->ia_valid; 70 int error = 0; 71 72 if (ia_valid & ATTR_SIZE) { 73 if (attr->ia_size != i_size_read(inode)) { 74 error = vmtruncate(inode, attr->ia_size); 75 if (error || (ia_valid == ATTR_SIZE)) 76 goto out; 77 } else { 78 /* 79 * We skipped the truncate but must still update 80 * timestamps 81 */ 82 ia_valid |= ATTR_MTIME|ATTR_CTIME; 83 } 84 } 85 86 if (ia_valid & ATTR_UID) 87 inode->i_uid = attr->ia_uid; 88 if (ia_valid & ATTR_GID) 89 inode->i_gid = attr->ia_gid; 90 if (ia_valid & ATTR_ATIME) 91 inode->i_atime = timespec_trunc(attr->ia_atime, 92 inode->i_sb->s_time_gran); 93 if (ia_valid & ATTR_MTIME) 94 inode->i_mtime = timespec_trunc(attr->ia_mtime, 95 inode->i_sb->s_time_gran); 96 if (ia_valid & ATTR_CTIME) 97 inode->i_ctime = timespec_trunc(attr->ia_ctime, 98 inode->i_sb->s_time_gran); 99 if (ia_valid & ATTR_MODE) { 100 umode_t mode = attr->ia_mode; 101 102 if (!in_group_p(inode->i_gid) && !capable(CAP_FSETID)) 103 mode &= ~S_ISGID; 104 inode->i_mode = mode; 105 } 106 mark_inode_dirty(inode); 107 out: 108 return error; 109 } 110 EXPORT_SYMBOL(inode_setattr); 111 112 int notify_change(struct dentry * dentry, struct iattr * attr) 113 { 114 struct inode *inode = dentry->d_inode; 115 mode_t mode; 116 int error; 117 struct timespec now; 118 unsigned int ia_valid = attr->ia_valid; 119 120 if (!inode) 121 BUG(); 122 123 mode = inode->i_mode; 124 now = current_fs_time(inode->i_sb); 125 126 attr->ia_ctime = now; 127 if (!(ia_valid & ATTR_ATIME_SET)) 128 attr->ia_atime = now; 129 if (!(ia_valid & ATTR_MTIME_SET)) 130 attr->ia_mtime = now; 131 if (ia_valid & ATTR_KILL_SUID) { 132 attr->ia_valid &= ~ATTR_KILL_SUID; 133 if (mode & S_ISUID) { 134 if (!(ia_valid & ATTR_MODE)) { 135 ia_valid = attr->ia_valid |= ATTR_MODE; 136 attr->ia_mode = inode->i_mode; 137 } 138 attr->ia_mode &= ~S_ISUID; 139 } 140 } 141 if (ia_valid & ATTR_KILL_SGID) { 142 attr->ia_valid &= ~ ATTR_KILL_SGID; 143 if ((mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP)) { 144 if (!(ia_valid & ATTR_MODE)) { 145 ia_valid = attr->ia_valid |= ATTR_MODE; 146 attr->ia_mode = inode->i_mode; 147 } 148 attr->ia_mode &= ~S_ISGID; 149 } 150 } 151 if (!attr->ia_valid) 152 return 0; 153 154 if (ia_valid & ATTR_SIZE) 155 down_write(&dentry->d_inode->i_alloc_sem); 156 157 if (inode->i_op && inode->i_op->setattr) { 158 error = security_inode_setattr(dentry, attr); 159 if (!error) 160 error = inode->i_op->setattr(dentry, attr); 161 } else { 162 error = inode_change_ok(inode, attr); 163 if (!error) 164 error = security_inode_setattr(dentry, attr); 165 if (!error) { 166 if ((ia_valid & ATTR_UID && attr->ia_uid != inode->i_uid) || 167 (ia_valid & ATTR_GID && attr->ia_gid != inode->i_gid)) 168 error = DQUOT_TRANSFER(inode, attr) ? -EDQUOT : 0; 169 if (!error) 170 error = inode_setattr(inode, attr); 171 } 172 } 173 174 if (ia_valid & ATTR_SIZE) 175 up_write(&dentry->d_inode->i_alloc_sem); 176 177 if (!error) 178 fsnotify_change(dentry, ia_valid); 179 180 return error; 181 } 182 183 EXPORT_SYMBOL(notify_change); 184