515 lines · c
1// SPDX-License-Identifier: GPL-2.02/*3 * linux/fs/attr.c4 *5 * Copyright (C) 1991, 1992 Linus Torvalds6 * changes by Thomas Schoebel-Theuer7 */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 20/**21 * setattr_should_drop_sgid - determine whether the setgid bit needs to be22 * removed23 * @idmap: idmap of the mount @inode was found from24 * @inode: inode to check25 *26 * This function determines whether the setgid bit needs to be removed.27 * We retain backwards compatibility and require setgid bit to be removed28 * unconditionally if S_IXGRP is set. Otherwise we have the exact same29 * requirements as setattr_prepare() and setattr_copy().30 *31 * Return: ATTR_KILL_SGID if setgid bit needs to be removed, 0 otherwise.32 */33int setattr_should_drop_sgid(struct mnt_idmap *idmap,34 const struct inode *inode)35{36 umode_t mode = inode->i_mode;37 38 if (!(mode & S_ISGID))39 return 0;40 if (mode & S_IXGRP)41 return ATTR_KILL_SGID;42 if (!in_group_or_capable(idmap, inode, i_gid_into_vfsgid(idmap, inode)))43 return ATTR_KILL_SGID;44 return 0;45}46EXPORT_SYMBOL(setattr_should_drop_sgid);47 48/**49 * setattr_should_drop_suidgid - determine whether the set{g,u}id bit needs to50 * be dropped51 * @idmap: idmap of the mount @inode was found from52 * @inode: inode to check53 *54 * This function determines whether the set{g,u}id bits need to be removed.55 * If the setuid bit needs to be removed ATTR_KILL_SUID is returned. If the56 * setgid bit needs to be removed ATTR_KILL_SGID is returned. If both57 * set{g,u}id bits need to be removed the corresponding mask of both flags is58 * returned.59 *60 * Return: A mask of ATTR_KILL_S{G,U}ID indicating which - if any - setid bits61 * to remove, 0 otherwise.62 */63int setattr_should_drop_suidgid(struct mnt_idmap *idmap,64 struct inode *inode)65{66 umode_t mode = inode->i_mode;67 int kill = 0;68 69 /* suid always must be killed */70 if (unlikely(mode & S_ISUID))71 kill = ATTR_KILL_SUID;72 73 kill |= setattr_should_drop_sgid(idmap, inode);74 75 if (unlikely(kill && !capable(CAP_FSETID) && S_ISREG(mode)))76 return kill;77 78 return 0;79}80EXPORT_SYMBOL(setattr_should_drop_suidgid);81 82/**83 * chown_ok - verify permissions to chown inode84 * @idmap: idmap of the mount @inode was found from85 * @inode: inode to check permissions on86 * @ia_vfsuid: uid to chown @inode to87 *88 * If the inode has been found through an idmapped mount the idmap of89 * the vfsmount must be passed through @idmap. This function will then90 * take care to map the inode according to @idmap before checking91 * permissions. On non-idmapped mounts or if permission checking is to be92 * performed on the raw inode simply pass @nop_mnt_idmap.93 */94static bool chown_ok(struct mnt_idmap *idmap,95 const struct inode *inode, vfsuid_t ia_vfsuid)96{97 vfsuid_t vfsuid = i_uid_into_vfsuid(idmap, inode);98 if (vfsuid_eq_kuid(vfsuid, current_fsuid()) &&99 vfsuid_eq(ia_vfsuid, vfsuid))100 return true;101 if (capable_wrt_inode_uidgid(idmap, inode, CAP_CHOWN))102 return true;103 if (!vfsuid_valid(vfsuid) &&104 ns_capable(inode->i_sb->s_user_ns, CAP_CHOWN))105 return true;106 return false;107}108 109/**110 * chgrp_ok - verify permissions to chgrp inode111 * @idmap: idmap of the mount @inode was found from112 * @inode: inode to check permissions on113 * @ia_vfsgid: gid to chown @inode to114 *115 * If the inode has been found through an idmapped mount the idmap of116 * the vfsmount must be passed through @idmap. This function will then117 * take care to map the inode according to @idmap before checking118 * permissions. On non-idmapped mounts or if permission checking is to be119 * performed on the raw inode simply pass @nop_mnt_idmap.120 */121static bool chgrp_ok(struct mnt_idmap *idmap,122 const struct inode *inode, vfsgid_t ia_vfsgid)123{124 vfsgid_t vfsgid = i_gid_into_vfsgid(idmap, inode);125 vfsuid_t vfsuid = i_uid_into_vfsuid(idmap, inode);126 if (vfsuid_eq_kuid(vfsuid, current_fsuid())) {127 if (vfsgid_eq(ia_vfsgid, vfsgid))128 return true;129 if (vfsgid_in_group_p(ia_vfsgid))130 return true;131 }132 if (capable_wrt_inode_uidgid(idmap, inode, CAP_CHOWN))133 return true;134 if (!vfsgid_valid(vfsgid) &&135 ns_capable(inode->i_sb->s_user_ns, CAP_CHOWN))136 return true;137 return false;138}139 140/**141 * setattr_prepare - check if attribute changes to a dentry are allowed142 * @idmap: idmap of the mount the inode was found from143 * @dentry: dentry to check144 * @attr: attributes to change145 *146 * Check if we are allowed to change the attributes contained in @attr147 * in the given dentry. This includes the normal unix access permission148 * checks, as well as checks for rlimits and others. The function also clears149 * SGID bit from mode if user is not allowed to set it. Also file capabilities150 * and IMA extended attributes are cleared if ATTR_KILL_PRIV is set.151 *152 * If the inode has been found through an idmapped mount the idmap of153 * the vfsmount must be passed through @idmap. This function will then154 * take care to map the inode according to @idmap before checking155 * permissions. On non-idmapped mounts or if permission checking is to be156 * performed on the raw inode simply pass @nop_mnt_idmap.157 *158 * Should be called as the first thing in ->setattr implementations,159 * possibly after taking additional locks.160 */161int setattr_prepare(struct mnt_idmap *idmap, struct dentry *dentry,162 struct iattr *attr)163{164 struct inode *inode = d_inode(dentry);165 unsigned int ia_valid = attr->ia_valid;166 167 /*168 * First check size constraints. These can't be overriden using169 * ATTR_FORCE.170 */171 if (ia_valid & ATTR_SIZE) {172 int error = inode_newsize_ok(inode, attr->ia_size);173 if (error)174 return error;175 }176 177 /* If force is set do it anyway. */178 if (ia_valid & ATTR_FORCE)179 goto kill_priv;180 181 /* Make sure a caller can chown. */182 if ((ia_valid & ATTR_UID) &&183 !chown_ok(idmap, inode, attr->ia_vfsuid))184 return -EPERM;185 186 /* Make sure caller can chgrp. */187 if ((ia_valid & ATTR_GID) &&188 !chgrp_ok(idmap, inode, attr->ia_vfsgid))189 return -EPERM;190 191 /* Make sure a caller can chmod. */192 if (ia_valid & ATTR_MODE) {193 vfsgid_t vfsgid;194 195 if (!inode_owner_or_capable(idmap, inode))196 return -EPERM;197 198 if (ia_valid & ATTR_GID)199 vfsgid = attr->ia_vfsgid;200 else201 vfsgid = i_gid_into_vfsgid(idmap, inode);202 203 /* Also check the setgid bit! */204 if (!in_group_or_capable(idmap, inode, vfsgid))205 attr->ia_mode &= ~S_ISGID;206 }207 208 /* Check for setting the inode time. */209 if (ia_valid & (ATTR_MTIME_SET | ATTR_ATIME_SET | ATTR_TIMES_SET)) {210 if (!inode_owner_or_capable(idmap, inode))211 return -EPERM;212 }213 214kill_priv:215 /* User has permission for the change */216 if (ia_valid & ATTR_KILL_PRIV) {217 int error;218 219 error = security_inode_killpriv(idmap, dentry);220 if (error)221 return error;222 }223 224 return 0;225}226EXPORT_SYMBOL(setattr_prepare);227 228/**229 * inode_newsize_ok - may this inode be truncated to a given size230 * @inode: the inode to be truncated231 * @offset: the new size to assign to the inode232 *233 * inode_newsize_ok must be called with i_mutex held.234 *235 * inode_newsize_ok will check filesystem limits and ulimits to check that the236 * new inode size is within limits. inode_newsize_ok will also send SIGXFSZ237 * when necessary. Caller must not proceed with inode size change if failure is238 * returned. @inode must be a file (not directory), with appropriate239 * permissions to allow truncate (inode_newsize_ok does NOT check these240 * conditions).241 *242 * Return: 0 on success, -ve errno on failure243 */244int inode_newsize_ok(const struct inode *inode, loff_t offset)245{246 if (offset < 0)247 return -EINVAL;248 if (inode->i_size < offset) {249 unsigned long limit;250 251 limit = rlimit(RLIMIT_FSIZE);252 if (limit != RLIM_INFINITY && offset > limit)253 goto out_sig;254 if (offset > inode->i_sb->s_maxbytes)255 goto out_big;256 } else {257 /*258 * truncation of in-use swapfiles is disallowed - it would259 * cause subsequent swapout to scribble on the now-freed260 * blocks.261 */262 if (IS_SWAPFILE(inode))263 return -ETXTBSY;264 }265 266 return 0;267out_sig:268 send_sig(SIGXFSZ, current, 0);269out_big:270 return -EFBIG;271}272EXPORT_SYMBOL(inode_newsize_ok);273 274/**275 * setattr_copy - copy simple metadata updates into the generic inode276 * @idmap: idmap of the mount the inode was found from277 * @inode: the inode to be updated278 * @attr: the new attributes279 *280 * setattr_copy must be called with i_mutex held.281 *282 * setattr_copy updates the inode's metadata with that specified283 * in attr on idmapped mounts. Necessary permission checks to determine284 * whether or not the S_ISGID property needs to be removed are performed with285 * the correct idmapped mount permission helpers.286 * Noticeably missing is inode size update, which is more complex287 * as it requires pagecache updates.288 *289 * If the inode has been found through an idmapped mount the idmap of290 * the vfsmount must be passed through @idmap. This function will then291 * take care to map the inode according to @idmap before checking292 * permissions. On non-idmapped mounts or if permission checking is to be293 * performed on the raw inode simply pass @nop_mnt_idmap.294 *295 * The inode is not marked as dirty after this operation. The rationale is296 * that for "simple" filesystems, the struct inode is the inode storage.297 * The caller is free to mark the inode dirty afterwards if needed.298 */299void setattr_copy(struct mnt_idmap *idmap, struct inode *inode,300 const struct iattr *attr)301{302 unsigned int ia_valid = attr->ia_valid;303 304 i_uid_update(idmap, attr, inode);305 i_gid_update(idmap, attr, inode);306 if (ia_valid & ATTR_ATIME)307 inode_set_atime_to_ts(inode, attr->ia_atime);308 if (ia_valid & ATTR_MTIME)309 inode_set_mtime_to_ts(inode, attr->ia_mtime);310 if (ia_valid & ATTR_CTIME)311 inode_set_ctime_to_ts(inode, attr->ia_ctime);312 if (ia_valid & ATTR_MODE) {313 umode_t mode = attr->ia_mode;314 if (!in_group_or_capable(idmap, inode,315 i_gid_into_vfsgid(idmap, inode)))316 mode &= ~S_ISGID;317 inode->i_mode = mode;318 }319}320EXPORT_SYMBOL(setattr_copy);321 322int may_setattr(struct mnt_idmap *idmap, struct inode *inode,323 unsigned int ia_valid)324{325 int error;326 327 if (ia_valid & (ATTR_MODE | ATTR_UID | ATTR_GID | ATTR_TIMES_SET)) {328 if (IS_IMMUTABLE(inode) || IS_APPEND(inode))329 return -EPERM;330 }331 332 /*333 * If utimes(2) and friends are called with times == NULL (or both334 * times are UTIME_NOW), then we need to check for write permission335 */336 if (ia_valid & ATTR_TOUCH) {337 if (IS_IMMUTABLE(inode))338 return -EPERM;339 340 if (!inode_owner_or_capable(idmap, inode)) {341 error = inode_permission(idmap, inode, MAY_WRITE);342 if (error)343 return error;344 }345 }346 return 0;347}348EXPORT_SYMBOL(may_setattr);349 350/**351 * notify_change - modify attributes of a filesystem object352 * @idmap: idmap of the mount the inode was found from353 * @dentry: object affected354 * @attr: new attributes355 * @delegated_inode: returns inode, if the inode is delegated356 *357 * The caller must hold the i_mutex on the affected object.358 *359 * If notify_change discovers a delegation in need of breaking,360 * it will return -EWOULDBLOCK and return a reference to the inode in361 * delegated_inode. The caller should then break the delegation and362 * retry. Because breaking a delegation may take a long time, the363 * caller should drop the i_mutex before doing so.364 *365 * Alternatively, a caller may pass NULL for delegated_inode. This may366 * be appropriate for callers that expect the underlying filesystem not367 * to be NFS exported. Also, passing NULL is fine for callers holding368 * the file open for write, as there can be no conflicting delegation in369 * that case.370 *371 * If the inode has been found through an idmapped mount the idmap of372 * the vfsmount must be passed through @idmap. This function will then373 * take care to map the inode according to @idmap before checking374 * permissions. On non-idmapped mounts or if permission checking is to be375 * performed on the raw inode simply pass @nop_mnt_idmap.376 */377int notify_change(struct mnt_idmap *idmap, struct dentry *dentry,378 struct iattr *attr, struct inode **delegated_inode)379{380 struct inode *inode = dentry->d_inode;381 umode_t mode = inode->i_mode;382 int error;383 struct timespec64 now;384 unsigned int ia_valid = attr->ia_valid;385 386 WARN_ON_ONCE(!inode_is_locked(inode));387 388 error = may_setattr(idmap, inode, ia_valid);389 if (error)390 return error;391 392 if ((ia_valid & ATTR_MODE)) {393 /*394 * Don't allow changing the mode of symlinks:395 *396 * (1) The vfs doesn't take the mode of symlinks into account397 * during permission checking.398 * (2) This has never worked correctly. Most major filesystems399 * did return EOPNOTSUPP due to interactions with POSIX ACLs400 * but did still updated the mode of the symlink.401 * This inconsistency led system call wrapper providers such402 * as libc to block changing the mode of symlinks with403 * EOPNOTSUPP already.404 * (3) To even do this in the first place one would have to use405 * specific file descriptors and quite some effort.406 */407 if (S_ISLNK(inode->i_mode))408 return -EOPNOTSUPP;409 410 /* Flag setting protected by i_mutex */411 if (is_sxid(attr->ia_mode))412 inode->i_flags &= ~S_NOSEC;413 }414 415 now = current_time(inode);416 417 attr->ia_ctime = now;418 if (!(ia_valid & ATTR_ATIME_SET))419 attr->ia_atime = now;420 else421 attr->ia_atime = timestamp_truncate(attr->ia_atime, inode);422 if (!(ia_valid & ATTR_MTIME_SET))423 attr->ia_mtime = now;424 else425 attr->ia_mtime = timestamp_truncate(attr->ia_mtime, inode);426 427 if (ia_valid & ATTR_KILL_PRIV) {428 error = security_inode_need_killpriv(dentry);429 if (error < 0)430 return error;431 if (error == 0)432 ia_valid = attr->ia_valid &= ~ATTR_KILL_PRIV;433 }434 435 /*436 * We now pass ATTR_KILL_S*ID to the lower level setattr function so437 * that the function has the ability to reinterpret a mode change438 * that's due to these bits. This adds an implicit restriction that439 * no function will ever call notify_change with both ATTR_MODE and440 * ATTR_KILL_S*ID set.441 */442 if ((ia_valid & (ATTR_KILL_SUID|ATTR_KILL_SGID)) &&443 (ia_valid & ATTR_MODE))444 BUG();445 446 if (ia_valid & ATTR_KILL_SUID) {447 if (mode & S_ISUID) {448 ia_valid = attr->ia_valid |= ATTR_MODE;449 attr->ia_mode = (inode->i_mode & ~S_ISUID);450 }451 }452 if (ia_valid & ATTR_KILL_SGID) {453 if (mode & S_ISGID) {454 if (!(ia_valid & ATTR_MODE)) {455 ia_valid = attr->ia_valid |= ATTR_MODE;456 attr->ia_mode = inode->i_mode;457 }458 attr->ia_mode &= ~S_ISGID;459 }460 }461 if (!(attr->ia_valid & ~(ATTR_KILL_SUID | ATTR_KILL_SGID)))462 return 0;463 464 /*465 * Verify that uid/gid changes are valid in the target466 * namespace of the superblock.467 */468 if (ia_valid & ATTR_UID &&469 !vfsuid_has_fsmapping(idmap, inode->i_sb->s_user_ns,470 attr->ia_vfsuid))471 return -EOVERFLOW;472 if (ia_valid & ATTR_GID &&473 !vfsgid_has_fsmapping(idmap, inode->i_sb->s_user_ns,474 attr->ia_vfsgid))475 return -EOVERFLOW;476 477 /* Don't allow modifications of files with invalid uids or478 * gids unless those uids & gids are being made valid.479 */480 if (!(ia_valid & ATTR_UID) &&481 !vfsuid_valid(i_uid_into_vfsuid(idmap, inode)))482 return -EOVERFLOW;483 if (!(ia_valid & ATTR_GID) &&484 !vfsgid_valid(i_gid_into_vfsgid(idmap, inode)))485 return -EOVERFLOW;486 487 error = security_inode_setattr(idmap, dentry, attr);488 if (error)489 return error;490 491 /*492 * If ATTR_DELEG is set, then these attributes are being set on493 * behalf of the holder of a write delegation. We want to avoid494 * breaking the delegation in this case.495 */496 if (!(ia_valid & ATTR_DELEG)) {497 error = try_break_deleg(inode, delegated_inode);498 if (error)499 return error;500 }501 502 if (inode->i_op->setattr)503 error = inode->i_op->setattr(idmap, dentry, attr);504 else505 error = simple_setattr(idmap, dentry, attr);506 507 if (!error) {508 fsnotify_change(dentry, ia_valid);509 security_inode_post_setattr(idmap, dentry, ia_valid);510 }511 512 return error;513}514EXPORT_SYMBOL(notify_change);515