#!/bin/bash
#
+# NOTE
+# In order to be able to do the runcon commands in test_4,
+# the SELinux policy must allow transitions from unconfined_t
+# to user_t and guest_t:
+# #============= unconfined_r ==============
+# allow unconfined_r guest_r;
+# allow unconfined_r user_r;
+#
# Run select tests by setting ONLY, or as arguments to the script.
# Skip specific tests by setting EXCEPT.
#
[ "$SLOW" = "no" ] && EXCEPT_SLOW="xxx"
+RUNAS_CMD=${RUNAS_CMD:-runas}
# $RUNAS_ID may get set incorrectly somewhere else
[ $UID -eq 0 -a $RUNAS_ID -eq 0 ] &&
error "RUNAS_ID set to 0, but UID is also 0!"
mds_path=${mds_path#/}
$LFS setdirstripe -i0 -c1 ${DIR}/$tdir || error "create dir failed"
- $LFS mkdir -c0 $dirname1 || error "cannot 'lfs mkdir' $dirname1"
+ $LFS mkdir -c0 -i0 $dirname1 || error "cannot 'lfs mkdir' $dirname1"
local xattrval=$(check_selinux_xattr "mds1" $mds_path)
run_test 2b "create dir with lfs and check security.selinux xattr is set on MDT"
test_3() {
- local filename=$DIR/df3
-
- # get current mapping of runasid, and save it
- local uname=$(getent passwd $RUNAS_ID | cut -d: -f1)
- local sename=$(semanage login -l |
- awk -v uname=$uname '$1==uname {print $2}')
- local serange=$(semanage login -l |
- awk -v uname=$uname '$1==uname {print $3}')
+ local filename=$DIR/$tdir/df3
+ local level=$(id -Z | cut -d':' -f4-)
+ local unconctx="-u unconfined_u -r unconfined_r -t unconfined_t \
+ -l $level"
- # change mapping of runasid to unconfined_u
- semanage login -a -s unconfined_u $uname ||
- error "unable to map $uname to unconfined_u"
+ mkdir -p $DIR/$tdir
+ chmod 777 $DIR/$tdir
# "access" Lustre
- echo "${uname} mapped as unconfined_u: touch $filename"
- $PDSH ${uname}@localhost "touch $filename" ||
+ echo "As unconfined_u: touch $filename"
+ $RUNAS_CMD -u $RUNAS_ID runcon $unconctx touch $filename ||
error "can't touch $filename"
- echo "${uname} mapped as unconfined_u: rm -f $filename"
- $PDSH ${uname}@localhost "rm -f $filename" ||
+ echo "As unconfined_u: rm -f $filename"
+ $RUNAS_CMD -u $RUNAS_ID runcon $unconctx rm -f $filename ||
error "can't remove $filename"
- # restore original mapping of runasid
- if [ -n "$sename" ]; then
- if [ -n "$serange" ]; then
- semanage login -a -s $sename -r $serange $uname ||
- error "unable to restore mapping for $uname"
- else
- semanage login -a -s $sename $uname ||
- error "unable to restore mapping for $uname"
- fi
- else
- semanage login -d $uname
- fi
-
return 0
}
run_test 3 "access with unconfined user"
test_4() {
- local filename=$DIR/df4
-
- # get current mapping of runasid, and save it
- local uname=$(getent passwd $RUNAS_ID | cut -d: -f1)
- local sename=$(semanage login -l |
- awk -v uname=$uname '$1==uname {print $2}')
- local serange=$(semanage login -l |
- awk -v uname=$uname '$1==uname {print $3}')
+ local filename=$DIR/$tdir/df4
+ local guestctx="-u guest_u -r guest_r -t guest_t -l s0"
+ local usrctx="-u user_u -r user_r -t user_t -l s0"
+
+ sesearch --role_allow | grep -q "allow unconfined_r user_r"
+ if [ $? -ne 0 ]; then
+ skip "SELinux policy module must allow transition from \
+ unconfined_r to user_r for this test." && exit 0
+ fi
+ sesearch --role_allow | grep -q "allow unconfined_r guest_r"
+ if [ $? -ne 0 ]; then
+ skip "SELinux policy module must allow transition from \
+ unconfined_r to guest_r for this test." && exit 0
+ fi
- # change mapping of runasid to guest_u
- semanage login -a -s guest_u $uname ||
- error "unable to map $uname to guest_u"
+ mkdir -p $DIR/$tdir
+ chmod 777 $DIR/$tdir
# "access" Lustre
- echo "${uname} mapped as guest_u: touch $filename"
- $PDSH ${uname}@localhost "touch $filename" &&
+ echo "As guest_u: touch $filename"
+ $RUNAS_CMD -u $RUNAS_ID runcon $guestctx touch $filename &&
error "touch $filename should have failed"
- # change mapping of runasid to user_u
- semanage login -a -s user_u $uname ||
- error "unable to map $uname to user_u"
-
# "access" Lustre
- echo "${uname} mapped as user_u: touch $filename"
- $PDSH ${uname}@localhost "touch $filename" ||
+ echo "As user_u: touch $filename"
+ $RUNAS_CMD -u $RUNAS_ID runcon $usrctx touch $filename ||
error "can't touch $filename"
- echo "${uname} mapped as user_u: rm -f $filename"
- $PDSH ${uname}@localhost "rm -f $filename" ||
+ echo "As user_u: rm -f $filename"
+ $RUNAS_CMD -u $RUNAS_ID runcon $usrctx rm -f $filename ||
error "can't remove $filename"
- # restore original mapping of runasid
- if [ -n "$sename" ]; then
- if [ -n "$serange" ]; then
- semanage login -a -s $sename -r $serange $uname ||
- error "unable to restore mapping for $uname"
- else
- semanage login -a -s $sename $uname ||
- error "unable to restore mapping for $uname"
- fi
- else
- semanage login -d $uname
- fi
-
return 0
}
run_test 4 "access with specific SELinux user"
local secctxseen=$(ls -lZ $filename1 | awk '{print $4}' | cut -d: -f3)
[ "$newsecctx" == "$secctxseen" ] ||
- error "sec context seen from 1st mount point is not correct"
+ error_ignore LU-6784 \
+ "sec context seen from 1st mount point is not correct"
return 0
}
run_test 10 "[consistency] concurrent security context change"
test_20a() {
- local uname=$(getent passwd $RUNAS_ID | cut -d: -f1)
- local filename1=$DIR/df20a
- local filename2=$DIR2/df20a
+ local filename1=$DIR/$tdir/df20a
+ local filename2=$DIR2/$tdir/df20a
local req_delay=20
+ local unconctx="-u unconfined_u -r unconfined_r -t unconfined_t -l s0"
+
+ mkdir -p $DIR/$tdir
+ chmod 777 $DIR/$tdir
# sleep some time in ll_create_nd()
#define OBD_FAIL_LLITE_CREATE_FILE_PAUSE 0x1409
do_facet client "$LCTL set_param fail_val=$req_delay fail_loc=0x1409"
# create file on first mount point
- $PDSH ${uname}@localhost "touch $filename1" &
+ $RUNAS_CMD -u $RUNAS_ID runcon $unconctx touch $filename1 &
local touchpid=$!
sleep 5
run_test 20a "[atomicity] concurrent access from another client (file)"
test_20b() {
- local uname=$(getent passwd $RUNAS_ID | cut -d: -f1)
- local dirname1=$DIR/dd20b
- local dirname2=$DIR2/dd20b
+ local dirname1=$DIR/$tdir/dd20b
+ local dirname2=$DIR2/$tdir/dd20b
local req_delay=20
+ local unconctx="-u unconfined_u -r unconfined_r -t unconfined_t -l s0"
+
+ mkdir -p $DIR/$tdir
+ chmod 777 $DIR/$tdir
# sleep some time in ll_create_nd()
#define OBD_FAIL_LLITE_NEWNODE_PAUSE 0x140a
do_facet client "$LCTL set_param fail_val=$req_delay fail_loc=0x140a"
# create file on first mount point
- $PDSH ${uname}@localhost "mkdir $dirname1" &
+ $RUNAS_CMD -u $RUNAS_ID runcon $unconctx mkdir $dirname1 &
local mkdirpid=$!
sleep 5
do_facet client "$LCTL set_param fail_val=$req_delay fail_loc=0x140b"
# create file on first mount point
- lfs mkdir -c0 $dirname1 &
+ $LFS mkdir -c0 -i0 $dirname1 &
local mkdirpid=$!
sleep 5
}
run_test 20c "[atomicity] concurrent access from another client (dir via lfs)"
+cleanup_20d() {
+ umount_client $MOUNT || error "umount $MOUNT failed"
+ mountcli
+}
+
+trace_cmd() {
+ local cmd="$@"
+ local xattr_prefix=$(grep -E \
+ "#define[[:space:]]+XATTR_SECURITY_PREFIX[[:space:]]+" \
+ /usr/include/linux/xattr.h 2>/dev/null |
+ awk '{print $3}' | sed s+\"++g)
+ local xattr_suffix=$(grep -E \
+ "#define[[:space:]]+XATTR_SELINUX_SUFFIX[[:space:]]+" \
+ /usr/include/linux/xattr.h 2>/dev/null |
+ awk '{print $3}' | sed s+\"++g)
+ local xattr_name=${xattr_prefix}${xattr_suffix}
+
+ [ -z "$xattr_name" ] && xattr_name="security.selinux"
+
+ # umount client
+ if [ "$MOUNT_2" ] && $(grep -q $MOUNT2' ' /proc/mounts); then
+ umount_client $MOUNT2 || error "umount $MOUNT2 failed"
+ fi
+ if $(grep -q $MOUNT' ' /proc/mounts); then
+ umount_client $MOUNT || error "umount $MOUNT failed"
+ fi
+ lustre_rmmod
+ # remount client
+ mount_client $MOUNT ${MOUNT_OPTS} || error "mount client failed"
+
+ $LCTL set_param debug=+info
+ $LCTL clear
+
+ echo $cmd
+ eval $cmd
+
+ $LCTL dk | grep "get xattr '${xattr_name}'"
+ [ $? -eq 0 ] && error "get xattr event was triggered" || true
+}
+
+test_20d() {
+ if [ $MDS1_VERSION -lt $(version_code 2.12.50) ] ||
+ [ $CLIENT_VERSION -lt $(version_code 2.12.50) ]; then
+ skip "Need version >= 2.12.50"
+ fi
+ [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
+
+ stack_trap cleanup_20d EXIT
+
+ local dirname=$DIR/$tdir/subdir
+
+ mkdir -p $DIR/$tdir
+ mkdir $dirname
+
+ trace_cmd stat $dirname
+ trace_cmd touch $dirname/f1
+ trace_cmd stat $dirname/f1
+ trace_cmd cat $dirname/f1
+ dd if=/dev/zero of=$dirname/f1 bs=1M count=10
+ trace_cmd /usr/bin/truncate -s 10240 $dirname/f1
+ trace_cmd lfs setstripe -E -1 -S 4M $dirname/f2
+ trace_cmd lfs migrate -E -1 -S 256K $dirname/f2
+ trace_cmd lfs setdirstripe -i 1 $dirname/d2
+ trace_cmd lfs migrate -m 0 $dirname/d2
+
+ lfs setdirstripe -i 1 -c 1 $dirname/d3
+ dirname=$dirname/d3/subdir
+ mkdir $dirname
+
+ trace_cmd stat $dirname
+ trace_cmd touch $dirname/f1
+ trace_cmd stat $dirname/f1
+ trace_cmd cat $dirname/f1
+ dd if=/dev/zero of=$dirname/f1 bs=1M count=10
+ trace_cmd /usr/bin/truncate -s 10240 $dirname/f1
+ trace_cmd lfs setstripe -E -1 -S 4M $dirname/f2
+ trace_cmd lfs migrate -E -1 -S 256K $dirname/f2
+}
+run_test 20d "[atomicity] avoid getxattr for security context"
complete $SECONDS
check_and_cleanup_lustre