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