[PATCH 2/7] knfsd: only set ATTR_KILL_S*ID if ATTR_MODE isn't being explicitly set

2007-09-20 Thread Jeff Layton
It's theoretically possible for a single SETATTR call to come in that
sets the mode and the uid/gid. In that case, don't set the ATTR_KILL_S*ID
bits since that would trip the BUG() in notify_change. Just fix up the
mode to have the same effect.

Signed-off-by: Jeff Layton <[EMAIL PROTECTED]>
---
 fs/nfsd/vfs.c |   21 +++--
 1 files changed, 15 insertions(+), 6 deletions(-)

diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c
index 9b21710..e2f0d98 100644
--- a/fs/nfsd/vfs.c
+++ b/fs/nfsd/vfs.c
@@ -370,14 +370,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;
-- 
1.5.2.1

-
To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 2/7] knfsd: only set ATTR_KILL_S*ID if ATTR_MODE isn't being explicitly set

2007-09-17 Thread Jeff Layton
It's theoretically possible for a single SETATTR call to come in that
sets the mode and the uid/gid. In that case, don't set the ATTR_KILL_S*ID
bits since that would trip the BUG() in notify_change. Just fix up the
mode to have the same effect.

Signed-off-by: Jeff Layton <[EMAIL PROTECTED]>
---
 fs/nfsd/vfs.c |   21 +++--
 1 files changed, 15 insertions(+), 6 deletions(-)

diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c
index 70f2c86..3c188fc 100644
--- a/fs/nfsd/vfs.c
+++ b/fs/nfsd/vfs.c
@@ -369,14 +369,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;
-- 
1.5.2.1

-
To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 2/7] knfsd: only set ATTR_KILL_S*ID if ATTR_MODE isn't being explicitly set

2007-09-10 Thread Jeff Layton
It's theoretically possible for a single SETATTR call to come in that
sets the mode and the uid/gid. In that case, assume the mode is
correct and don't set the ATTR_KILL_S*ID bits. Doing so would trip the
BUG() in notify_change.

Signed-off-by: Jeff Layton <[EMAIL PROTECTED]>
---
 fs/nfsd/vfs.c |   17 +++--
 1 files changed, 11 insertions(+), 6 deletions(-)

diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c
index 70f2c86..3b5b8cf 100644
--- a/fs/nfsd/vfs.c
+++ b/fs/nfsd/vfs.c
@@ -369,14 +369,19 @@ 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 ((iap->ia_valid & ATTR_UID) && iap->ia_uid != inode->i_uid)
+   iap->ia_valid |= ATTR_KILL_PRIV;
+   } else {
+   /*
+* Revoke setuid/setgid bit on chown/chgrp, unless the mode
+* is being explicitly set
+*/
+   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;
-- 
1.5.2.1

-
To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html