From 31585737203acd82f3a46ffaf208600d702b5307 Mon Sep 17 00:00:00 2001 From: James Simmons Date: Fri, 17 Dec 2010 23:57:43 +0100 Subject: [PATCH] b=24226 Only force the mode change if we're changing the size as well i=johann The offending code was added by commit 77ba4b2141d04180211efa8a75c11ab0abf7fafb to remove setgid/setuid bits when do_truncate() is called on the file. We should only force the change when that occurs, similarly to ll_setattr() in lustre/llite/llite_lib.c --- lustre/mds/mds_reint.c | 22 +++++++++++++--------- lustre/tests/sanity.sh | 31 ++++++++++++++++++++++++++++++- 2 files changed, 43 insertions(+), 10 deletions(-) diff --git a/lustre/mds/mds_reint.c b/lustre/mds/mds_reint.c index 533027b..66a4487 100644 --- a/lustre/mds/mds_reint.c +++ b/lustre/mds/mds_reint.c @@ -371,7 +371,7 @@ int mds_fix_attr(struct inode *inode, struct mds_update_record *rec) time_t now = CURRENT_SECONDS; struct iattr *attr = &rec->ur_iattr; unsigned int ia_valid = attr->ia_valid; - int error; + int error, mode; ENTRY; if (ia_valid & ATTR_RAW) @@ -404,6 +404,17 @@ int mds_fix_attr(struct inode *inode, struct mds_update_record *rec) RETURN(error); } + /* Some older clients are broken so we do the client's magic + * here just in case */ + if ((attr->ia_valid & (ATTR_MODE|ATTR_FORCE|ATTR_SIZE)) == + (ATTR_SIZE|ATTR_MODE)) { + mode = inode->i_mode; + if (((mode & S_ISUID) && (!(attr->ia_mode & S_ISUID))) || + ((mode & S_ISGID) && (mode & S_IXGRP) && + (!(attr->ia_mode & S_ISGID)))) + attr->ia_valid |= ATTR_FORCE; + } + if (ia_valid & (ATTR_UID | ATTR_GID)) { /* chown */ error = -EPERM; @@ -447,15 +458,8 @@ int mds_fix_attr(struct inode *inode, struct mds_update_record *rec) attr->ia_valid |= ATTR_MODE; } } else if (ia_valid & ATTR_MODE) { - int mode; - if (!(attr->ia_valid & ATTR_FORCE)) { - mode = inode->i_mode; - if (((mode & S_ISUID) && (!(attr->ia_mode & S_ISUID))) || - ((mode & S_ISGID) && (mode & S_IXGRP) && - (!(attr->ia_mode & S_ISGID)))) - attr->ia_valid |= ATTR_FORCE; - } mode = attr->ia_mode; + /* chmod */ if (attr->ia_mode == (umode_t)-1) mode = inode->i_mode; diff --git a/lustre/tests/sanity.sh b/lustre/tests/sanity.sh index 0cdc68f..8dfe525 100644 --- a/lustre/tests/sanity.sh +++ b/lustre/tests/sanity.sh @@ -3392,7 +3392,8 @@ test_71() { } run_test 71 "Running dbench on lustre (don't segment fault) ====" -test_72() { # bug 5695 - Test that on 2.6 remove_suid works properly +# was test 72 +test_72a() { # bug 5695 - Test that on 2.6 remove_suid works properly check_kernel_version 43 || return 0 [ "$RUNAS_ID" = "$UID" ] && skip_env "RUNAS_ID = UID = $UID -- skipping" && return @@ -3414,6 +3415,34 @@ test_72() { # bug 5695 - Test that on 2.6 remove_suid works properly } run_test 72 "Test that remove suid works properly (bug5695) ====" +test_72b() { # bug 24226 -- keep mode setting when size is not changing + local perm + + [ "$RUNAS_ID" = "$UID" ] && \ + skip_env "RUNAS_ID = UID = $UID -- skipping" && return + [ "$RUNAS_ID" -eq 0 ] && \ + skip_env "RUNAS_ID = 0 -- skipping" && return + + # Check that testing environment is properly set up. Skip if not + FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_ID $RUNAS || { + skip_env "User $RUNAS_ID does not exist - skipping" + return 0 + } + touch $DIR/${tfile}-f{g,u} + mkdir $DIR/${tfile}-d{g,u} + chmod 770 $DIR/${tfile}-{f,d}{g,u} + chmod g+s $DIR/${tfile}-{f,d}g + chmod u+s $DIR/${tfile}-{f,d}u + for perm in 777 2777 4777; do + $RUNAS chmod $perm $DIR/${tfile}-fg && error "S/gid file allowed improper chmod to $perm" + $RUNAS chmod $perm $DIR/${tfile}-fu && error "S/uid file allowed improper chmod to $perm" + $RUNAS chmod $perm $DIR/${tfile}-dg && error "S/gid dir allowed improper chmod to $perm" + $RUNAS chmod $perm $DIR/${tfile}-du && error "S/uid dir allowed improper chmod to $perm" + done + true +} +run_test 72b "Test that we keep mode setting when not changing size (bug 24226)" + # bug 3462 - multiple simultaneous MDC requests test_73() { mkdir $DIR/d73-1 -- 1.8.3.1