selftests/lkdtm: Add tests for LKDTM targets
This adds a basic framework for running all the "safe" LKDTM tests. This will allow easy introspection into any selftest logs to examine the results of most LKDTM tests. Signed-off-by: Kees Cook <keescook@chromium.org> Signed-off-by: Shuah Khan <skhan@linuxfoundation.org>
This commit is contained in:
parent
192c197cbc
commit
46d1a0f03d
@ -9581,6 +9581,7 @@ LINUX KERNEL DUMP TEST MODULE (LKDTM)
|
|||||||
M: Kees Cook <keescook@chromium.org>
|
M: Kees Cook <keescook@chromium.org>
|
||||||
S: Maintained
|
S: Maintained
|
||||||
F: drivers/misc/lkdtm/*
|
F: drivers/misc/lkdtm/*
|
||||||
|
F: tools/testing/selftests/lkdtm/*
|
||||||
|
|
||||||
LINUX KERNEL MEMORY CONSISTENCY MODEL (LKMM)
|
LINUX KERNEL MEMORY CONSISTENCY MODEL (LKMM)
|
||||||
M: Alan Stern <stern@rowland.harvard.edu>
|
M: Alan Stern <stern@rowland.harvard.edu>
|
||||||
|
@ -26,6 +26,7 @@ TARGETS += kexec
|
|||||||
TARGETS += kvm
|
TARGETS += kvm
|
||||||
TARGETS += lib
|
TARGETS += lib
|
||||||
TARGETS += livepatch
|
TARGETS += livepatch
|
||||||
|
TARGETS += lkdtm
|
||||||
TARGETS += membarrier
|
TARGETS += membarrier
|
||||||
TARGETS += memfd
|
TARGETS += memfd
|
||||||
TARGETS += memory-hotplug
|
TARGETS += memory-hotplug
|
||||||
|
12
tools/testing/selftests/lkdtm/Makefile
Normal file
12
tools/testing/selftests/lkdtm/Makefile
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
# SPDX-License-Identifier: GPL-2.0
|
||||||
|
# Makefile for LKDTM regression tests
|
||||||
|
|
||||||
|
include ../lib.mk
|
||||||
|
|
||||||
|
# NOTE: $(OUTPUT) won't get default value if used before lib.mk
|
||||||
|
TEST_FILES := tests.txt
|
||||||
|
TEST_GEN_PROGS = $(patsubst %,$(OUTPUT)/%.sh,$(shell awk '{print $$1}' tests.txt | sed -e 's/\#//'))
|
||||||
|
all: $(TEST_GEN_PROGS)
|
||||||
|
|
||||||
|
$(OUTPUT)/%: run.sh tests.txt
|
||||||
|
install -m 0744 run.sh $@
|
1
tools/testing/selftests/lkdtm/config
Normal file
1
tools/testing/selftests/lkdtm/config
Normal file
@ -0,0 +1 @@
|
|||||||
|
CONFIG_LKDTM=y
|
92
tools/testing/selftests/lkdtm/run.sh
Executable file
92
tools/testing/selftests/lkdtm/run.sh
Executable file
@ -0,0 +1,92 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
# SPDX-License-Identifier: GPL-2.0
|
||||||
|
#
|
||||||
|
# This reads tests.txt for the list of LKDTM tests to invoke. Any marked
|
||||||
|
# with a leading "#" are skipped. The rest of the line after the
|
||||||
|
# test name is either the text to look for in dmesg for a "success",
|
||||||
|
# or the rationale for why a test is marked to be skipped.
|
||||||
|
#
|
||||||
|
set -e
|
||||||
|
TRIGGER=/sys/kernel/debug/provoke-crash/DIRECT
|
||||||
|
KSELFTEST_SKIP_TEST=4
|
||||||
|
|
||||||
|
# Verify we have LKDTM available in the kernel.
|
||||||
|
if [ ! -r $TRIGGER ] ; then
|
||||||
|
/sbin/modprobe -q lkdtm || true
|
||||||
|
if [ ! -r $TRIGGER ] ; then
|
||||||
|
echo "Cannot find $TRIGGER (missing CONFIG_LKDTM?)"
|
||||||
|
else
|
||||||
|
echo "Cannot write $TRIGGER (need to run as root?)"
|
||||||
|
fi
|
||||||
|
# Skip this test
|
||||||
|
exit $KSELFTEST_SKIP_TEST
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Figure out which test to run from our script name.
|
||||||
|
test=$(basename $0 .sh)
|
||||||
|
# Look up details about the test from master list of LKDTM tests.
|
||||||
|
line=$(egrep '^#?'"$test"'\b' tests.txt)
|
||||||
|
if [ -z "$line" ]; then
|
||||||
|
echo "Skipped: missing test '$test' in tests.txt"
|
||||||
|
exit $KSELFTEST_SKIP_TEST
|
||||||
|
fi
|
||||||
|
# Check that the test is known to LKDTM.
|
||||||
|
if ! egrep -q '^'"$test"'$' "$TRIGGER" ; then
|
||||||
|
echo "Skipped: test '$test' missing in $TRIGGER!"
|
||||||
|
exit $KSELFTEST_SKIP_TEST
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Extract notes/expected output from test list.
|
||||||
|
test=$(echo "$line" | cut -d" " -f1)
|
||||||
|
if echo "$line" | grep -q ' ' ; then
|
||||||
|
expect=$(echo "$line" | cut -d" " -f2-)
|
||||||
|
else
|
||||||
|
expect=""
|
||||||
|
fi
|
||||||
|
|
||||||
|
# If the test is commented out, report a skip
|
||||||
|
if echo "$test" | grep -q '^#' ; then
|
||||||
|
test=$(echo "$test" | cut -c2-)
|
||||||
|
if [ -z "$expect" ]; then
|
||||||
|
expect="crashes entire system"
|
||||||
|
fi
|
||||||
|
echo "Skipping $test: $expect"
|
||||||
|
exit $KSELFTEST_SKIP_TEST
|
||||||
|
fi
|
||||||
|
|
||||||
|
# If no expected output given, assume an Oops with back trace is success.
|
||||||
|
if [ -z "$expect" ]; then
|
||||||
|
expect="call trace:"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Clear out dmesg for output reporting
|
||||||
|
dmesg -c >/dev/null
|
||||||
|
|
||||||
|
# Prepare log for report checking
|
||||||
|
LOG=$(mktemp --tmpdir -t lkdtm-XXXXXX)
|
||||||
|
cleanup() {
|
||||||
|
rm -f "$LOG"
|
||||||
|
}
|
||||||
|
trap cleanup EXIT
|
||||||
|
|
||||||
|
# Most shells yell about signals and we're expecting the "cat" process
|
||||||
|
# to usually be killed by the kernel. So we have to run it in a sub-shell
|
||||||
|
# and silence errors.
|
||||||
|
($SHELL -c 'cat <(echo '"$test"') >'"$TRIGGER" 2>/dev/null) || true
|
||||||
|
|
||||||
|
# Record and dump the results
|
||||||
|
dmesg -c >"$LOG"
|
||||||
|
cat "$LOG"
|
||||||
|
# Check for expected output
|
||||||
|
if egrep -qi "$expect" "$LOG" ; then
|
||||||
|
echo "$test: saw '$expect': ok"
|
||||||
|
exit 0
|
||||||
|
else
|
||||||
|
if egrep -qi XFAIL: "$LOG" ; then
|
||||||
|
echo "$test: saw 'XFAIL': [SKIP]"
|
||||||
|
exit $KSELFTEST_SKIP_TEST
|
||||||
|
else
|
||||||
|
echo "$test: missing '$expect': [FAIL]"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
fi
|
71
tools/testing/selftests/lkdtm/tests.txt
Normal file
71
tools/testing/selftests/lkdtm/tests.txt
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
#PANIC
|
||||||
|
BUG kernel BUG at
|
||||||
|
WARNING WARNING:
|
||||||
|
WARNING_MESSAGE message trigger
|
||||||
|
EXCEPTION
|
||||||
|
#LOOP Hangs the system
|
||||||
|
#EXHAUST_STACK Corrupts memory on failure
|
||||||
|
#CORRUPT_STACK Crashes entire system on success
|
||||||
|
#CORRUPT_STACK_STRONG Crashes entire system on success
|
||||||
|
CORRUPT_LIST_ADD list_add corruption
|
||||||
|
CORRUPT_LIST_DEL list_del corruption
|
||||||
|
CORRUPT_USER_DS Invalid address limit on user-mode return
|
||||||
|
STACK_GUARD_PAGE_LEADING
|
||||||
|
STACK_GUARD_PAGE_TRAILING
|
||||||
|
UNSET_SMEP CR4 bits went missing
|
||||||
|
DOUBLE_FAULT
|
||||||
|
UNALIGNED_LOAD_STORE_WRITE
|
||||||
|
#OVERWRITE_ALLOCATION Corrupts memory on failure
|
||||||
|
#WRITE_AFTER_FREE Corrupts memory on failure
|
||||||
|
READ_AFTER_FREE
|
||||||
|
#WRITE_BUDDY_AFTER_FREE Corrupts memory on failure
|
||||||
|
READ_BUDDY_AFTER_FREE
|
||||||
|
SLAB_FREE_DOUBLE
|
||||||
|
SLAB_FREE_CROSS
|
||||||
|
SLAB_FREE_PAGE
|
||||||
|
#SOFTLOCKUP Hangs the system
|
||||||
|
#HARDLOCKUP Hangs the system
|
||||||
|
#SPINLOCKUP Hangs the system
|
||||||
|
#HUNG_TASK Hangs the system
|
||||||
|
EXEC_DATA
|
||||||
|
EXEC_STACK
|
||||||
|
EXEC_KMALLOC
|
||||||
|
EXEC_VMALLOC
|
||||||
|
EXEC_RODATA
|
||||||
|
EXEC_USERSPACE
|
||||||
|
EXEC_NULL
|
||||||
|
ACCESS_USERSPACE
|
||||||
|
ACCESS_NULL
|
||||||
|
WRITE_RO
|
||||||
|
WRITE_RO_AFTER_INIT
|
||||||
|
WRITE_KERN
|
||||||
|
REFCOUNT_INC_OVERFLOW
|
||||||
|
REFCOUNT_ADD_OVERFLOW
|
||||||
|
REFCOUNT_INC_NOT_ZERO_OVERFLOW
|
||||||
|
REFCOUNT_ADD_NOT_ZERO_OVERFLOW
|
||||||
|
REFCOUNT_DEC_ZERO
|
||||||
|
REFCOUNT_DEC_NEGATIVE Negative detected: saturated
|
||||||
|
REFCOUNT_DEC_AND_TEST_NEGATIVE Negative detected: saturated
|
||||||
|
REFCOUNT_SUB_AND_TEST_NEGATIVE Negative detected: saturated
|
||||||
|
REFCOUNT_INC_ZERO
|
||||||
|
REFCOUNT_ADD_ZERO
|
||||||
|
REFCOUNT_INC_SATURATED Saturation detected: still saturated
|
||||||
|
REFCOUNT_DEC_SATURATED Saturation detected: still saturated
|
||||||
|
REFCOUNT_ADD_SATURATED Saturation detected: still saturated
|
||||||
|
REFCOUNT_INC_NOT_ZERO_SATURATED
|
||||||
|
REFCOUNT_ADD_NOT_ZERO_SATURATED
|
||||||
|
REFCOUNT_DEC_AND_TEST_SATURATED Saturation detected: still saturated
|
||||||
|
REFCOUNT_SUB_AND_TEST_SATURATED Saturation detected: still saturated
|
||||||
|
#REFCOUNT_TIMING timing only
|
||||||
|
#ATOMIC_TIMING timing only
|
||||||
|
USERCOPY_HEAP_SIZE_TO
|
||||||
|
USERCOPY_HEAP_SIZE_FROM
|
||||||
|
USERCOPY_HEAP_WHITELIST_TO
|
||||||
|
USERCOPY_HEAP_WHITELIST_FROM
|
||||||
|
USERCOPY_STACK_FRAME_TO
|
||||||
|
USERCOPY_STACK_FRAME_FROM
|
||||||
|
USERCOPY_STACK_BEYOND
|
||||||
|
USERCOPY_KERNEL
|
||||||
|
USERCOPY_KERNEL_DS
|
||||||
|
STACKLEAK_ERASING OK: the rest of the thread stack is properly erased
|
||||||
|
CFI_FORWARD_PROTO
|
Loading…
Reference in New Issue
Block a user