diff options
author | Kees Cook <keescook@chromium.org> | 2020-08-06 23:01:09 -0700 |
---|---|---|
committer | Kees Cook <keescook@chromium.org> | 2020-08-07 10:50:11 -0700 |
commit | 9af47666cb0f331bfcd76799ee368cdfcb00882c (patch) | |
tree | 9134feaef0f6076f5f1ebe484fb3791d60d1ff7b | |
parent | 11990a5bd7e558e9203c1070fc52fb6f0488e75b (diff) |
selftests: splice: Check behavior of full and short splices
In order to help catch regressions in splice vs read behavior in certain
special files, test a few with various different kinds of internal
kernel helpers.
Cc: Shuah Khan <shuah@kernel.org>
Signed-off-by: Kees Cook <keescook@chromium.org>
-rw-r--r-- | tools/testing/selftests/splice/.gitignore | 1 | ||||
-rw-r--r-- | tools/testing/selftests/splice/Makefile | 4 | ||||
-rw-r--r-- | tools/testing/selftests/splice/config | 1 | ||||
-rw-r--r-- | tools/testing/selftests/splice/settings | 1 | ||||
-rwxr-xr-x | tools/testing/selftests/splice/short_splice_read.sh | 56 | ||||
-rw-r--r-- | tools/testing/selftests/splice/splice_read.c | 57 |
6 files changed, 118 insertions, 2 deletions
diff --git a/tools/testing/selftests/splice/.gitignore b/tools/testing/selftests/splice/.gitignore index d5a2da428752..be8266f5d04c 100644 --- a/tools/testing/selftests/splice/.gitignore +++ b/tools/testing/selftests/splice/.gitignore @@ -1,2 +1,3 @@ # SPDX-License-Identifier: GPL-2.0-only default_file_splice_read +splice_read diff --git a/tools/testing/selftests/splice/Makefile b/tools/testing/selftests/splice/Makefile index e519b159b60d..541cd826d5a5 100644 --- a/tools/testing/selftests/splice/Makefile +++ b/tools/testing/selftests/splice/Makefile @@ -1,5 +1,5 @@ # SPDX-License-Identifier: GPL-2.0 -TEST_PROGS := default_file_splice_read.sh -TEST_GEN_PROGS_EXTENDED := default_file_splice_read +TEST_PROGS := default_file_splice_read.sh short_splice_read.sh +TEST_GEN_PROGS_EXTENDED := default_file_splice_read splice_read include ../lib.mk diff --git a/tools/testing/selftests/splice/config b/tools/testing/selftests/splice/config new file mode 100644 index 000000000000..058c928368b8 --- /dev/null +++ b/tools/testing/selftests/splice/config @@ -0,0 +1 @@ +CONFIG_TEST_LKM=m diff --git a/tools/testing/selftests/splice/settings b/tools/testing/selftests/splice/settings new file mode 100644 index 000000000000..89cedfc0d12b --- /dev/null +++ b/tools/testing/selftests/splice/settings @@ -0,0 +1 @@ +timeout=5 diff --git a/tools/testing/selftests/splice/short_splice_read.sh b/tools/testing/selftests/splice/short_splice_read.sh new file mode 100755 index 000000000000..7810d3589d9a --- /dev/null +++ b/tools/testing/selftests/splice/short_splice_read.sh @@ -0,0 +1,56 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +set -e + +ret=0 + +do_splice() +{ + filename="$1" + bytes="$2" + expected="$3" + + out=$(./splice_read "$filename" "$bytes" | cat) + if [ "$out" = "$expected" ] ; then + echo "ok: $filename $bytes" + else + echo "FAIL: $filename $bytes" + ret=1 + fi +} + +test_splice() +{ + filename="$1" + + full=$(cat "$filename") + two=$(echo "$full" | grep -m1 . | cut -c-2) + + # Make sure full splice has the same contents as a standard read. + do_splice "$filename" 4096 "$full" + + # Make sure a partial splice see the first two characters. + do_splice "$filename" 2 "$two" +} + +# proc_single_open(), seq_read() +test_splice /proc/$$/limits +# special open, seq_read() +test_splice /proc/$$/comm + +# proc_handler, proc_dointvec_minmax +test_splice /proc/sys/fs/nr_open +# proc_handler, proc_dostring +test_splice /proc/sys/kernel/modprobe +# proc_handler, special read +test_splice /proc/sys/kernel/version + +if ! [ -d /sys/module/test_module/sections ] ; then + modprobe test_module +fi +# kernfs, attr +test_splice /sys/module/test_module/coresize +# kernfs, binattr +test_splice /sys/module/test_module/sections/.init.text + +exit $ret diff --git a/tools/testing/selftests/splice/splice_read.c b/tools/testing/selftests/splice/splice_read.c new file mode 100644 index 000000000000..46dae6a25cfb --- /dev/null +++ b/tools/testing/selftests/splice/splice_read.c @@ -0,0 +1,57 @@ +// SPDX-License-Identifier: GPL-2.0 +#define _GNU_SOURCE +#include <errno.h> +#include <fcntl.h> +#include <limits.h> +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <sys/types.h> +#include <sys/stat.h> + +int main(int argc, char *argv[]) +{ + int fd; + size_t size; + ssize_t spliced; + + if (argc < 2) { + fprintf(stderr, "Usage: %s INPUT [BYTES]\n", argv[0]); + return EXIT_FAILURE; + } + + fd = open(argv[1], O_RDONLY); + if (fd < 0) { + perror(argv[1]); + return EXIT_FAILURE; + } + + if (argc == 3) + size = atol(argv[2]); + else { + struct stat statbuf; + + if (fstat(fd, &statbuf) < 0) { + perror(argv[1]); + return EXIT_FAILURE; + } + + if (statbuf.st_size > INT_MAX) { + fprintf(stderr, "%s: Too big\n", argv[1]); + return EXIT_FAILURE; + } + + size = statbuf.st_size; + } + + /* splice(2) file to stdout. */ + spliced = splice(fd, NULL, STDOUT_FILENO, NULL, + size, SPLICE_F_MOVE); + if (spliced < 0) { + perror("splice"); + return EXIT_FAILURE; + } + + close(fd); + return EXIT_SUCCESS; +} |