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>
This commit is contained in:
parent
11990a5bd7
commit
9af47666cb
|
@ -1,2 +1,3 @@
|
|||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
default_file_splice_read
|
||||
splice_read
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
CONFIG_TEST_LKM=m
|
|
@ -0,0 +1 @@
|
|||
timeout=5
|
|
@ -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
|
|
@ -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;
|
||||
}
|
Loading…
Reference in New Issue