diff options
Diffstat (limited to 'fs/nfsd')
-rw-r--r-- | fs/nfsd/vfs.c | 27 |
1 files changed, 18 insertions, 9 deletions
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c index 819545d..d019918 100644 --- a/fs/nfsd/vfs.c +++ b/fs/nfsd/vfs.c @@ -364,14 +364,23 @@ nfsd_setattr(struct svc_rqst *rqstp, struct svc_fh *fhp, struct iattr *iap, if (iap->ia_valid & ATTR_MODE) { iap->ia_mode &= S_IALLUGO; imode = iap->ia_mode |= (imode & ~S_IALLUGO); + /* if changing uid/gid revoke setuid/setgid in mode */ + if ((iap->ia_valid & ATTR_UID) && iap->ia_uid != inode->i_uid) { + iap->ia_valid |= ATTR_KILL_PRIV; + iap->ia_mode &= ~S_ISUID; + } + if ((iap->ia_valid & ATTR_GID) && iap->ia_gid != inode->i_gid) + iap->ia_mode &= ~S_ISGID; + } else { + /* + * Revoke setuid/setgid bit on chown/chgrp + */ + if ((iap->ia_valid & ATTR_UID) && iap->ia_uid != inode->i_uid) + iap->ia_valid |= ATTR_KILL_SUID | ATTR_KILL_PRIV; + if ((iap->ia_valid & ATTR_GID) && iap->ia_gid != inode->i_gid) + iap->ia_valid |= ATTR_KILL_SGID; } - /* Revoke setuid/setgid bit on chown/chgrp */ - if ((iap->ia_valid & ATTR_UID) && iap->ia_uid != inode->i_uid) - iap->ia_valid |= ATTR_KILL_SUID | ATTR_KILL_PRIV; - if ((iap->ia_valid & ATTR_GID) && iap->ia_gid != inode->i_gid) - iap->ia_valid |= ATTR_KILL_SGID; - /* Change the attributes. */ iap->ia_valid |= ATTR_CTIME; @@ -1020,13 +1029,13 @@ nfsd_vfs_write(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file, if (EX_WGATHER(exp)) { if (atomic_read(&inode->i_writecount) > 1 || (last_ino == inode->i_ino && last_dev == inode->i_sb->s_dev)) { - dprintk("nfsd: write defer %d\n", current->pid); + dprintk("nfsd: write defer %d\n", task_pid_nr(current)); msleep(10); - dprintk("nfsd: write resume %d\n", current->pid); + dprintk("nfsd: write resume %d\n", task_pid_nr(current)); } if (inode->i_state & I_DIRTY) { - dprintk("nfsd: write sync %d\n", current->pid); + dprintk("nfsd: write sync %d\n", task_pid_nr(current)); host_err=nfsd_sync(file); } #if 0 |