From f0afc2e7c7bee3043ac1e7d098bc44db60186856 Mon Sep 17 00:00:00 2001 From: Krutika Dhananjay Date: Wed, 19 Aug 2015 16:54:42 +0530 Subject: features/shard: Fix permission issues Backport of: http://review.gluster.org/11992 This patch does the following: * reverts commit b467af0e99b39ef708420d3f7f6696b0ca618512 * changes ownership on shards under /.shard to be root:root * makes readv, writev, [f]truncate, rename, and unlink fops to perform operations on files under /.shard with frame->root->{uid,gid} as 0. This would ensure that a [f]setattr on a sharded file does not need to be called on all the shards associated with it. Change-Id: I50d8533bd2b769a4dfe8cd1b49bdcfc117a7e660 BUG: 1253151 Signed-off-by: Krutika Dhananjay Reviewed-on: http://review.gluster.org/12052 Reviewed-by: Pranith Kumar Karampuri Tested-by: Gluster Build System Tested-by: NetBSD Build System --- tests/bugs/shard/bug-1251824.t | 68 +++++++++++++++++++++++++++++++++++------- tests/common-utils.rc | 7 +++++ 2 files changed, 64 insertions(+), 11 deletions(-) create mode 100644 tests/common-utils.rc (limited to 'tests') diff --git a/tests/bugs/shard/bug-1251824.t b/tests/bugs/shard/bug-1251824.t index 71bfdc7fdae..9e6ceaa8161 100644 --- a/tests/bugs/shard/bug-1251824.t +++ b/tests/bugs/shard/bug-1251824.t @@ -1,6 +1,7 @@ #!/bin/bash . $(dirname $0)/../../include.rc +. $(dirname $0)/../../common-utils.rc cleanup; @@ -8,52 +9,97 @@ TEST glusterd TEST pidof glusterd TEST $CLI volume create $V0 $H0:$B0/${V0}{0,1} TEST $CLI volume set $V0 features.shard on +TEST $CLI volume set $V0 performance.strict-write-ordering on TEST $CLI volume start $V0 -TEST $GFS --volfile-id=$V0 --volfile-server=$H0 $M0 +TEST glusterfs --volfile-id=$V0 --volfile-server=$H0 $M0 TEST useradd -M test_user 2>/dev/null # Create 3 files as root. TEST touch $M0/foo TEST touch $M0/bar TEST touch $M0/baz +TEST touch $M0/qux +TEST mkdir $M0/dir # Change ownership to non-root on foo and bar. TEST chown test_user:test_user $M0/foo TEST chown test_user:test_user $M0/bar # Write 6M of data on foo as non-root, 2M overflowing into block-1. -su -m test_user -c "dd if=/dev/zero of=$M0/foo bs=1M count=6" +TEST run_cmd_as_user test_user "dd if=/dev/zero of=$M0/foo bs=1M count=6" -# Ensure owner and group are same on the shard as the main file. +# Ensure owner and group are root on the block-1 shard. gfid_foo=`getfattr -n glusterfs.gfid.string $M0/foo 2>/dev/null \ | grep glusterfs.gfid.string | cut -d '"' -f 2` -EXPECT "test_user" echo `find $B0 -name $gfid_foo.1 | xargs stat -c %U` -EXPECT "test_user" echo `find $B0 -name $gfid_foo.1 | xargs stat -c %G` +EXPECT "root" echo `find $B0 -name $gfid_foo.1 | xargs stat -c %U` +EXPECT "root" echo `find $B0 -name $gfid_foo.1 | xargs stat -c %G` + +#Ensure /.shard is owned by root. +EXPECT "root" echo `find $B0/${V0}0 -name .shard | xargs stat -c %U` +EXPECT "root" echo `find $B0/${V0}0 -name .shard | xargs stat -c %G` +EXPECT "root" echo `find $B0/${V0}1 -name .shard | xargs stat -c %U` +EXPECT "root" echo `find $B0/${V0}1 -name .shard | xargs stat -c %G` # Write 6M of data on bar as root. TEST dd if=/dev/zero of=$M0/bar bs=1M count=6 -# Ensure owner and group are same on the shard as the main file. +# Ensure owner and group are root on the block-1 shard. gfid_bar=`getfattr -n glusterfs.gfid.string $M0/bar 2>/dev/null \ | grep glusterfs.gfid.string | cut -d '"' -f 2` -EXPECT "test_user" echo `find $B0 -name $gfid_bar.1 | xargs stat -c %U` -EXPECT "test_user" echo `find $B0 -name $gfid_bar.1 | xargs stat -c %G` +EXPECT "root" echo `find $B0 -name $gfid_bar.1 | xargs stat -c %U` +EXPECT "root" echo `find $B0 -name $gfid_bar.1 | xargs stat -c %G` # Write 6M of data on baz as root. TEST dd if=/dev/zero of=$M0/baz bs=1M count=6 -# Ensure owner andgroup are same on the shard as the main file. gfid_baz=`getfattr -n glusterfs.gfid.string $M0/baz 2>/dev/null \ | grep glusterfs.gfid.string | cut -d '"' -f 2` +# Ensure owner and group are root on the block-1 shard. EXPECT "root" echo `find $B0 -name $gfid_baz.1 | xargs stat -c %U` EXPECT "root" echo `find $B0 -name $gfid_baz.1 | xargs stat -c %G` -userdel test_user -TEST umount $M0 +# Test to ensure unlink from an unauthorized user does not lead to only +# the shards under /.shard getting unlinked while that on the base file fails +# with EPERM/ACCES. + +TEST ! run_cmd_as_user test_user "unlink $M0/baz" +TEST find $B0/*/.shard/$gfid_baz.1 + +# Test to ensure rename of a file where the dest file exists and is sharded, +# from an unauthorized user does not lead to only the shards under /.shard +# getting unlinked while that on the base file fails with EPERM/ACCES. + +TEST ! run_cmd_as_user test_user "mv -f $M0/qux $M0/baz" +TEST find $B0/*/.shard/$gfid_baz.1 +TEST stat $M0/qux + +# Shard translator executes steps in the following order while doing a truncate +# to a lower size: +# 1) unlinking shards under /.shard first with frame->root->{uid,gid} being 0, +# 2) truncate the original file by the right amount. +# The following two tests are towards ensuring that truncate attempt from an +# unauthorised user doesn't result in only the shards under /.shard getting +# removed (since they're being performed as root) while step 2) above fails, +# leaving the file in an inconsistent state. + +TEST ! run_cmd_as_user test_user "truncate -s 1M $M0/baz" +TEST find $B0/*/.shard/$gfid_baz.1 + +# Perform a cp as non-root user. This should trigger readv() which will trigger +# reads on first shard of "foo" under /.shard, and this must not fail if shard +# translator correctly sets frame->root->uid,gid to 0 before reading off the +# first shard, since it's owned by root. +TEST chown test_user:test_user $M0/dir +TEST run_cmd_as_user test_user "cp $M0/foo $M0/dir/quux" + +md5sum_foo=$(md5sum $M0/foo | awk '{print $1}') +EXPECT "$md5sum_foo" echo `md5sum $M0/dir/quux | awk '{print $1}'` + +userdel test_user TEST $CLI volume stop $V0 TEST $CLI volume delete $V0 diff --git a/tests/common-utils.rc b/tests/common-utils.rc new file mode 100644 index 00000000000..2be4076e8b6 --- /dev/null +++ b/tests/common-utils.rc @@ -0,0 +1,7 @@ + +function run_cmd_as_user { + local user=$1 + shift + su -m $user -c "$*" || return 1 + return 0 +} -- cgit