diff options
| -rw-r--r-- | fs/nfsd/vfs.c | 27 |
1 files changed, 14 insertions, 13 deletions
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c index 1d0406c31a44..a3a291f771f4 100644 --- a/fs/nfsd/vfs.c +++ b/fs/nfsd/vfs.c | |||
| @@ -359,24 +359,25 @@ nfsd_setattr(struct svc_rqst *rqstp, struct svc_fh *fhp, struct iattr *iap, | |||
| 359 | DQUOT_INIT(inode); | 359 | DQUOT_INIT(inode); |
| 360 | } | 360 | } |
| 361 | 361 | ||
| 362 | /* sanitize the mode change */ | ||
| 362 | if (iap->ia_valid & ATTR_MODE) { | 363 | if (iap->ia_valid & ATTR_MODE) { |
| 363 | iap->ia_mode &= S_IALLUGO; | 364 | iap->ia_mode &= S_IALLUGO; |
| 364 | iap->ia_mode |= (inode->i_mode & ~S_IALLUGO); | 365 | iap->ia_mode |= (inode->i_mode & ~S_IALLUGO); |
| 365 | /* if changing uid/gid revoke setuid/setgid in mode */ | 366 | } |
| 366 | if ((iap->ia_valid & ATTR_UID) && iap->ia_uid != inode->i_uid) { | 367 | |
| 367 | iap->ia_valid |= ATTR_KILL_PRIV; | 368 | /* Revoke setuid/setgid on chown */ |
| 369 | if (((iap->ia_valid & ATTR_UID) && iap->ia_uid != inode->i_uid) || | ||
| 370 | ((iap->ia_valid & ATTR_GID) && iap->ia_gid != inode->i_gid)) { | ||
| 371 | iap->ia_valid |= ATTR_KILL_PRIV; | ||
| 372 | if (iap->ia_valid & ATTR_MODE) { | ||
| 373 | /* we're setting mode too, just clear the s*id bits */ | ||
| 368 | iap->ia_mode &= ~S_ISUID; | 374 | iap->ia_mode &= ~S_ISUID; |
| 375 | if (iap->ia_mode & S_IXGRP) | ||
| 376 | iap->ia_mode &= ~S_ISGID; | ||
| 377 | } else { | ||
| 378 | /* set ATTR_KILL_* bits and let VFS handle it */ | ||
| 379 | iap->ia_valid |= (ATTR_KILL_SUID | ATTR_KILL_SGID); | ||
| 369 | } | 380 | } |
| 370 | if ((iap->ia_valid & ATTR_GID) && iap->ia_gid != inode->i_gid) | ||
| 371 | iap->ia_mode &= ~S_ISGID; | ||
| 372 | } else { | ||
| 373 | /* | ||
| 374 | * Revoke setuid/setgid bit on chown/chgrp | ||
| 375 | */ | ||
| 376 | if ((iap->ia_valid & ATTR_UID) && iap->ia_uid != inode->i_uid) | ||
| 377 | iap->ia_valid |= ATTR_KILL_SUID | ATTR_KILL_PRIV; | ||
| 378 | if ((iap->ia_valid & ATTR_GID) && iap->ia_gid != inode->i_gid) | ||
| 379 | iap->ia_valid |= ATTR_KILL_SGID; | ||
| 380 | } | 381 | } |
| 381 | 382 | ||
| 382 | /* Change the attributes. */ | 383 | /* Change the attributes. */ |
