Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

selftests: splice: Adjust for handler fallback removal

Some pseudo-filesystems do not have an explicit splice fops since adding
commit 36e2c7421f02 ("fs: don't allow splice read/write without explicit ops"),
and now will reject attempts to use splice() in those filesystem paths.

Reported-by: kernel test robot <rong.a.chen@intel.com>
Link: https://lore.kernel.org/lkml/202009181443.C2179FB@keescook/
Fixes: 36e2c7421f02 ("fs: don't allow splice read/write without explicit ops")
Cc: Christoph Hellwig <hch@lst.de>
Cc: Shuah Khan <shuah@kernel.org>
Cc: linux-kselftest@vger.kernel.org
Signed-off-by: Kees Cook <keescook@chromium.org>
Signed-off-by: Shuah Khan <skhan@linuxfoundation.org>

authored by

Kees Cook and committed by
Shuah Khan
6daf076b f50688b4

+98 -21
+98 -21
tools/testing/selftests/splice/short_splice_read.sh
··· 1 1 #!/bin/sh 2 2 # SPDX-License-Identifier: GPL-2.0 3 + # 4 + # Test for mishandling of splice() on pseudofilesystems, which should catch 5 + # bugs like 11990a5bd7e5 ("module: Correctly truncate sysfs sections output") 6 + # 7 + # Since splice fallback was removed as part of the set_fs() rework, many of these 8 + # tests expect to fail now. See https://lore.kernel.org/lkml/202009181443.C2179FB@keescook/ 3 9 set -e 4 10 11 + DIR=$(dirname "$0") 12 + 5 13 ret=0 14 + 15 + expect_success() 16 + { 17 + title="$1" 18 + shift 19 + 20 + echo "" >&2 21 + echo "$title ..." >&2 22 + 23 + set +e 24 + "$@" 25 + rc=$? 26 + set -e 27 + 28 + case "$rc" in 29 + 0) 30 + echo "ok: $title succeeded" >&2 31 + ;; 32 + 1) 33 + echo "FAIL: $title should work" >&2 34 + ret=$(( ret + 1 )) 35 + ;; 36 + *) 37 + echo "FAIL: something else went wrong" >&2 38 + ret=$(( ret + 1 )) 39 + ;; 40 + esac 41 + } 42 + 43 + expect_failure() 44 + { 45 + title="$1" 46 + shift 47 + 48 + echo "" >&2 49 + echo "$title ..." >&2 50 + 51 + set +e 52 + "$@" 53 + rc=$? 54 + set -e 55 + 56 + case "$rc" in 57 + 0) 58 + echo "FAIL: $title unexpectedly worked" >&2 59 + ret=$(( ret + 1 )) 60 + ;; 61 + 1) 62 + echo "ok: $title correctly failed" >&2 63 + ;; 64 + *) 65 + echo "FAIL: something else went wrong" >&2 66 + ret=$(( ret + 1 )) 67 + ;; 68 + esac 69 + } 6 70 7 71 do_splice() 8 72 { 9 73 filename="$1" 10 74 bytes="$2" 11 75 expected="$3" 76 + report="$4" 12 77 13 - out=$(./splice_read "$filename" "$bytes" | cat) 78 + out=$("$DIR"/splice_read "$filename" "$bytes" | cat) 14 79 if [ "$out" = "$expected" ] ; then 15 - echo "ok: $filename $bytes" 80 + echo " matched $report" >&2 81 + return 0 16 82 else 17 - echo "FAIL: $filename $bytes" 18 - ret=1 83 + echo " no match: '$out' vs $report" >&2 84 + return 1 19 85 fi 20 86 } 21 87 ··· 89 23 { 90 24 filename="$1" 91 25 26 + echo " checking $filename ..." >&2 27 + 92 28 full=$(cat "$filename") 29 + rc=$? 30 + if [ $rc -ne 0 ] ; then 31 + return 2 32 + fi 33 + 93 34 two=$(echo "$full" | grep -m1 . | cut -c-2) 94 35 95 36 # Make sure full splice has the same contents as a standard read. 96 - do_splice "$filename" 4096 "$full" 37 + echo " splicing 4096 bytes ..." >&2 38 + if ! do_splice "$filename" 4096 "$full" "full read" ; then 39 + return 1 40 + fi 97 41 98 42 # Make sure a partial splice see the first two characters. 99 - do_splice "$filename" 2 "$two" 43 + echo " splicing 2 bytes ..." >&2 44 + if ! do_splice "$filename" 2 "$two" "'$two'" ; then 45 + return 1 46 + fi 47 + 48 + return 0 100 49 } 101 50 102 - # proc_single_open(), seq_read() 103 - test_splice /proc/$$/limits 104 - # special open, seq_read() 105 - test_splice /proc/$$/comm 51 + ### /proc/$pid/ has no splice interface; these should all fail. 52 + expect_failure "proc_single_open(), seq_read() splice" test_splice /proc/$$/limits 53 + expect_failure "special open(), seq_read() splice" test_splice /proc/$$/comm 106 54 107 - # proc_handler, proc_dointvec_minmax 108 - test_splice /proc/sys/fs/nr_open 109 - # proc_handler, proc_dostring 110 - test_splice /proc/sys/kernel/modprobe 111 - # proc_handler, special read 112 - test_splice /proc/sys/kernel/version 55 + ### /proc/sys/ has a splice interface; these should all succeed. 56 + expect_success "proc_handler: proc_dointvec_minmax() splice" test_splice /proc/sys/fs/nr_open 57 + expect_success "proc_handler: proc_dostring() splice" test_splice /proc/sys/kernel/modprobe 58 + expect_success "proc_handler: special read splice" test_splice /proc/sys/kernel/version 113 59 60 + ### /sys/ has no splice interface; these should all fail. 114 61 if ! [ -d /sys/module/test_module/sections ] ; then 115 - modprobe test_module 62 + expect_success "test_module kernel module load" modprobe test_module 116 63 fi 117 - # kernfs, attr 118 - test_splice /sys/module/test_module/coresize 119 - # kernfs, binattr 120 - test_splice /sys/module/test_module/sections/.init.text 64 + expect_failure "kernfs attr splice" test_splice /sys/module/test_module/coresize 65 + expect_failure "kernfs binattr splice" test_splice /sys/module/test_module/sections/.init.text 121 66 122 67 exit $ret