From cb74546354201434a6fd3d53acd1a0808fbfcb1c Mon Sep 17 00:00:00 2001 From: Andreas Dilger Date: Thu, 30 Apr 2020 16:20:01 -0600 Subject: [PATCH] LU-13168 tests: verify truncated xattr is handled Verify that a truncated trusted.lov xattr is handled properly, for both plain and PFL layouts. Add a test case that verifies this is fixed for both layout types. Fixes: f2d06d3c76 ("LU-12911 llite: Don't access lov_md fields before size check") Signed-off-by: Andreas Dilger Change-Id: I11d420c7fdc2362f64689a545b95c76e893ebbe5 Reviewed-on: https://review.whamcloud.com/38434 Tested-by: jenkins Reviewed-by: Sebastien Buisson Reviewed-by: Emoly Liu Tested-by: Maloo Reviewed-by: Oleg Drokin --- lustre/llite/xattr.c | 13 +++++++++-- lustre/tests/sanity.sh | 62 ++++++++++++++++++++++++++++++++------------------ 2 files changed, 51 insertions(+), 24 deletions(-) diff --git a/lustre/llite/xattr.c b/lustre/llite/xattr.c index 829584d..c1535bd 100644 --- a/lustre/llite/xattr.c +++ b/lustre/llite/xattr.c @@ -213,7 +213,7 @@ static int get_hsm_state(struct inode *inode, u32 *hus_states) return rc; } -static int ll_adjust_lum(struct inode *inode, struct lov_user_md *lump) +static int ll_adjust_lum(struct inode *inode, struct lov_user_md *lump, size_t size) { struct lov_comp_md_v1 *comp_v1 = (struct lov_comp_md_v1 *)lump; struct lov_user_md *v1 = lump; @@ -228,7 +228,12 @@ static int ll_adjust_lum(struct inode *inode, struct lov_user_md *lump) return 0; if (lump->lmm_magic == LOV_USER_MAGIC_COMP_V1) { + if (size < sizeof(*comp_v1)) + return -ERANGE; + entry_count = comp_v1->lcm_entry_count; + if (size < offsetof(typeof(*comp_v1), lcm_entries[entry_count])) + return -ERANGE; is_composite = true; } @@ -236,6 +241,10 @@ static int ll_adjust_lum(struct inode *inode, struct lov_user_md *lump) if (lump->lmm_magic == LOV_USER_MAGIC_COMP_V1) { void *ptr = comp_v1; + if (comp_v1->lcm_entries[i].lcme_offset + sizeof(*v1) > + size) + return -ERANGE; + ptr += comp_v1->lcm_entries[i].lcme_offset; v1 = (struct lov_user_md *)ptr; } @@ -289,7 +298,7 @@ static int ll_setstripe_ea(struct dentry *dentry, struct lov_user_md *lump, */ return -ERANGE; } - rc = ll_adjust_lum(inode, lump); + rc = ll_adjust_lum(inode, lump, size); if (rc) return rc; diff --git a/lustre/tests/sanity.sh b/lustre/tests/sanity.sh index c44f731..fb540aa 100755 --- a/lustre/tests/sanity.sh +++ b/lustre/tests/sanity.sh @@ -9525,36 +9525,54 @@ test_102a() { } run_test 102a "user xattr test ==================================" +check_102b_layout() { + local layout="$*" + local testfile=$DIR/$tfile + + echo "test layout '$layout'" + $LFS setstripe $layout $testfile || error "setstripe failed" + $LFS getstripe -y $testfile + + echo "get/set/list trusted.lov xattr ..." # b=10930 + local value=$(getfattr -n trusted.lov -e hex $testfile | grep trusted) + [[ "$value" =~ "trusted.lov" ]] || + error "can't get trusted.lov from $testfile" + local stripe_count_orig=$($LFS getstripe -c $testfile) || + error "getstripe failed" + + $MCREATE $testfile.2 || error "mcreate $testfile.2 failed" + + value=$(cut -d= -f2 <<<$value) + # LU-13168: truncated xattr should fail if short lov_user_md header + [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] && + lens="${#value}" || lens="$(seq 4 2 ${#value})" + for len in $lens; do + echo "setfattr $len $testfile.2" + setfattr -n trusted.lov -v ${value:0:$len} $testfile.2 && + [ $len -lt 66 ] && error "short xattr len=$len worked" + done + local stripe_size=$($LFS getstripe -S $testfile.2) + local stripe_count=$($LFS getstripe -c $testfile.2) + [[ $stripe_size -eq 65536 ]] || + error "stripe size $stripe_size != 65536" + [[ $stripe_count -eq $stripe_count_orig ]] || + error "stripe count $stripe_count != $stripe_count_orig" + rm $testfile $testfile.2 +} + test_102b() { [ -z "$(which setfattr 2>/dev/null)" ] && skip_env "could not find setfattr" [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs" - # b10930: get/set/list trusted.lov xattr - echo "get/set/list trusted.lov xattr ..." - local testfile=$DIR/$tfile - $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile || - error "setstripe failed" - local STRIPECOUNT=$($LFS getstripe -c $testfile) || - error "getstripe failed" - getfattr -d -m "^trusted" $testfile 2>/dev/null | grep "trusted.lov" || - error "can't get trusted.lov from $testfile" + # check plain layout + check_102b_layout -S 65536 -i 1 -c $OSTCOUNT - local testfile2=${testfile}2 - local value=$(getfattr -n trusted.lov $testfile 2>/dev/null | - grep "trusted.lov" | sed -e 's/[^=]\+=//') + # and also check composite layout + check_102b_layout -E 1M -S 65536 -i 1 -c $OSTCOUNT -Eeof -S4M - $MCREATE $testfile2 - setfattr -n trusted.lov -v $value $testfile2 - local stripe_size=$($LFS getstripe -S $testfile2) - local stripe_count=$($LFS getstripe -c $testfile2) - [[ $stripe_size -eq 65536 ]] || - error "stripe size $stripe_size != 65536" - [[ $stripe_count -eq $STRIPECOUNT ]] || - error "stripe count $stripe_count != $STRIPECOUNT" - rm -f $DIR/$tfile } -run_test 102b "getfattr/setfattr for trusted.lov EAs ============" +run_test 102b "getfattr/setfattr for trusted.lov EAs" test_102c() { [ -z "$(which setfattr 2>/dev/null)" ] && -- 1.8.3.1