Skip to content

Commit

Permalink
selftests/livepatch: Don't clear dmesg when running tests
Browse files Browse the repository at this point in the history
Inspired by commit f131d9e ("selftests/lkdtm: Don't clear dmesg
when running tests"), keep a reference dmesg copy when beginning each
test.  This way check_result() can compare against the initial copy
rather than relying upon an empty log.

Signed-off-by: Joe Lawrence <joe.lawrence@redhat.com>
Reviewed-by: Kamalesh Babulal <kamalesh@linux.vnet.ibm.com>
Reviewed-by: Yannick Cote <ycote@redhat.com>
Reviewed-by: Petr Mladek <pmladek@suse.com>
Acked-by: Miroslav Benes <mbenes@suse.cz>
Signed-off-by: Petr Mladek <pmladek@suse.com>
Link: https://lore.kernel.org/r/20200618181040.21132-2-joe.lawrence@redhat.com
  • Loading branch information
joe-lawrence authored and pmladek committed Jun 19, 2020
1 parent 270f780 commit 2eeb0d4
Show file tree
Hide file tree
Showing 7 changed files with 66 additions and 81 deletions.
16 changes: 8 additions & 8 deletions tools/testing/selftests/livepatch/README
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ This is a small set of sanity tests for the kernel livepatching.

The test suite loads and unloads several test kernel modules to verify
livepatch behavior. Debug information is logged to the kernel's message
buffer and parsed for expected messages. (Note: the tests will clear
the message buffer between individual tests.)
buffer and parsed for expected messages. (Note: the tests will compare
the message buffer for only the duration of each individual test.)


Config
Expand Down Expand Up @@ -35,9 +35,9 @@ Adding tests
------------

See the common functions.sh file for the existing collection of utility
functions, most importantly setup_config() and check_result(). The
latter function greps the kernel's ring buffer for "livepatch:" and
"test_klp" strings, so tests be sure to include one of those strings for
result comparison. Other utility functions include general module
loading and livepatch loading helpers (waiting for patch transitions,
sysfs entries, etc.)
functions, most importantly setup_config(), start_test() and
check_result(). The latter function greps the kernel's ring buffer for
"livepatch:" and "test_klp" strings, so tests be sure to include one of
those strings for result comparison. Other utility functions include
general module loading and livepatch loading helpers (waiting for patch
transitions, sysfs entries, etc.)
35 changes: 33 additions & 2 deletions tools/testing/selftests/livepatch/functions.sh
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,17 @@ function die() {
exit 1
}

# save existing dmesg so we can detect new content
function save_dmesg() {
SAVED_DMESG=$(mktemp --tmpdir -t klp-dmesg-XXXXXX)
dmesg > "$SAVED_DMESG"
}

# cleanup temporary dmesg file from save_dmesg()
function cleanup_dmesg_file() {
rm -f "$SAVED_DMESG"
}

function push_config() {
DYNAMIC_DEBUG=$(grep '^kernel/livepatch' /sys/kernel/debug/dynamic_debug/control | \
awk -F'[: ]' '{print "file " $1 " line " $2 " " $4}')
Expand Down Expand Up @@ -68,6 +79,11 @@ function set_ftrace_enabled() {
echo "livepatch: $result" > /dev/kmsg
}

function cleanup() {
pop_config
cleanup_dmesg_file
}

# setup_config - save the current config and set a script exit trap that
# restores the original config. Setup the dynamic debug
# for verbose livepatching output and turn on
Expand All @@ -77,7 +93,7 @@ function setup_config() {
push_config
set_dynamic_debug
set_ftrace_enabled 1
trap pop_config EXIT INT TERM HUP
trap cleanup EXIT INT TERM HUP
}

# loop_until(cmd) - loop a command until it is successful or $MAX_RETRIES,
Expand Down Expand Up @@ -243,18 +259,33 @@ function set_pre_patch_ret {
die "failed to set pre_patch_ret parameter for $mod module"
}

function start_test {
local test="$1"

save_dmesg
echo -n "TEST: $test ... "
}

# check_result() - verify dmesg output
# TODO - better filter, out of order msgs, etc?
function check_result {
local expect="$*"
local result

result=$(dmesg | grep -v 'tainting' | grep -e 'livepatch:' -e 'test_klp' | sed 's/^\[[ 0-9.]*\] //')
# Note: when comparing dmesg output, the kernel log timestamps
# help differentiate repeated testing runs. Remove them with a
# post-comparison sed filter.

result=$(dmesg | diff --changed-group-format='%>' --unchanged-group-format='' "$SAVED_DMESG" - | \
grep -v 'tainting' | grep -e 'livepatch:' -e 'test_klp' | \
sed 's/^\[[ 0-9.]*\] //')

if [[ "$expect" == "$result" ]] ; then
echo "ok"
else
echo -e "not ok\n\n$(diff -upr --label expected --label result <(echo "$expect") <(echo "$result"))\n"
die "livepatch kselftest(s) failed"
fi

cleanup_dmesg_file
}
55 changes: 11 additions & 44 deletions tools/testing/selftests/livepatch/test-callbacks.sh
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,6 @@ MOD_TARGET_BUSY=test_klp_callbacks_busy
setup_config


# TEST: target module before livepatch
#
# Test a combination of loading a kernel module and a livepatch that
# patches a function in the first module. Load the target module
# before the livepatch module. Unload them in the same order.
Expand All @@ -28,8 +26,7 @@ setup_config
# unpatching transition starts. klp_objects are reverted, post-patch
# callbacks execute and the transition completes.

echo -n "TEST: target module before livepatch ... "
dmesg -C
start_test "target module before livepatch"

load_mod $MOD_TARGET
load_lp $MOD_LIVEPATCH
Expand Down Expand Up @@ -63,8 +60,6 @@ livepatch: '$MOD_LIVEPATCH': unpatching complete
$MOD_TARGET: ${MOD_TARGET}_exit"


# TEST: module_coming notifier
#
# This test is similar to the previous test, but (un)load the livepatch
# module before the target kernel module. This tests the livepatch
# core's module_coming handler.
Expand All @@ -78,8 +73,7 @@ $MOD_TARGET: ${MOD_TARGET}_exit"
# - On livepatch disable, all currently loaded klp_objects' (vmlinux and
# $MOD_TARGET) pre/post-unpatch callbacks are executed.

echo -n "TEST: module_coming notifier ... "
dmesg -C
start_test "module_coming notifier"

load_lp $MOD_LIVEPATCH
load_mod $MOD_TARGET
Expand Down Expand Up @@ -114,8 +108,6 @@ livepatch: '$MOD_LIVEPATCH': unpatching complete
$MOD_TARGET: ${MOD_TARGET}_exit"


# TEST: module_going notifier
#
# Test loading the livepatch after a targeted kernel module, then unload
# the kernel module before disabling the livepatch. This tests the
# livepatch core's module_going handler.
Expand All @@ -129,8 +121,7 @@ $MOD_TARGET: ${MOD_TARGET}_exit"
# - When the livepatch is disabled, pre and post-unpatch callbacks are
# run for the remaining klp_object, vmlinux.

echo -n "TEST: module_going notifier ... "
dmesg -C
start_test "module_going notifier"

load_mod $MOD_TARGET
load_lp $MOD_LIVEPATCH
Expand Down Expand Up @@ -165,8 +156,6 @@ livepatch: '$MOD_LIVEPATCH': unpatching complete
% rmmod $MOD_LIVEPATCH"


# TEST: module_coming and module_going notifiers
#
# This test is similar to the previous test, however the livepatch is
# loaded first. This tests the livepatch core's module_coming and
# module_going handlers.
Expand All @@ -180,8 +169,7 @@ livepatch: '$MOD_LIVEPATCH': unpatching complete
# from the $MOD_TARGET klp_object. As such, only pre and
# post-unpatch callbacks are executed when this occurs.

echo -n "TEST: module_coming and module_going notifiers ... "
dmesg -C
start_test "module_coming and module_going notifiers"

load_lp $MOD_LIVEPATCH
load_mod $MOD_TARGET
Expand Down Expand Up @@ -217,8 +205,6 @@ livepatch: '$MOD_LIVEPATCH': unpatching complete
% rmmod $MOD_LIVEPATCH"


# TEST: target module not present
#
# A simple test of loading a livepatch without one of its patch target
# klp_objects ever loaded ($MOD_TARGET).
#
Expand All @@ -227,8 +213,7 @@ livepatch: '$MOD_LIVEPATCH': unpatching complete
# - As expected, only pre/post-(un)patch handlers are executed for
# vmlinux.

echo -n "TEST: target module not present ... "
dmesg -C
start_test "target module not present"

load_lp $MOD_LIVEPATCH
disable_lp $MOD_LIVEPATCH
Expand All @@ -252,8 +237,6 @@ livepatch: '$MOD_LIVEPATCH': unpatching complete
% rmmod $MOD_LIVEPATCH"


# TEST: pre-patch callback -ENODEV
#
# Test a scenario where a vmlinux pre-patch callback returns a non-zero
# status (ie, failure).
#
Expand All @@ -265,8 +248,7 @@ livepatch: '$MOD_LIVEPATCH': unpatching complete
# The result is that the insmod command refuses to load the livepatch
# module.

echo -n "TEST: pre-patch callback -ENODEV ... "
dmesg -C
start_test "pre-patch callback -ENODEV"

load_mod $MOD_TARGET
load_failing_mod $MOD_LIVEPATCH pre_patch_ret=-19
Expand All @@ -288,8 +270,6 @@ modprobe: ERROR: could not insert '$MOD_LIVEPATCH': No such device
$MOD_TARGET: ${MOD_TARGET}_exit"


# TEST: module_coming + pre-patch callback -ENODEV
#
# Similar to the previous test, setup a livepatch such that its vmlinux
# pre-patch callback returns success. However, when a targeted kernel
# module is later loaded, have the livepatch return a failing status
Expand All @@ -307,8 +287,7 @@ $MOD_TARGET: ${MOD_TARGET}_exit"
#
# - Pre/post-unpatch callbacks are run for the vmlinux klp_object.

echo -n "TEST: module_coming + pre-patch callback -ENODEV ... "
dmesg -C
start_test "module_coming + pre-patch callback -ENODEV"

load_lp $MOD_LIVEPATCH
set_pre_patch_ret $MOD_LIVEPATCH -19
Expand Down Expand Up @@ -341,8 +320,6 @@ livepatch: '$MOD_LIVEPATCH': unpatching complete
% rmmod $MOD_LIVEPATCH"


# TEST: multiple target modules
#
# Test loading multiple targeted kernel modules. This test-case is
# mainly for comparing with the next test-case.
#
Expand All @@ -353,8 +330,7 @@ livepatch: '$MOD_LIVEPATCH': unpatching complete
# module. Post-patch callbacks are executed and the transition
# completes quickly.

echo -n "TEST: multiple target modules ... "
dmesg -C
start_test "multiple target modules"

load_mod $MOD_TARGET_BUSY block_transition=N
load_lp $MOD_LIVEPATCH
Expand Down Expand Up @@ -402,8 +378,6 @@ livepatch: '$MOD_LIVEPATCH': unpatching complete
$MOD_TARGET_BUSY: ${MOD_TARGET_BUSY}_exit"


# TEST: busy target module
#
# A similar test as the previous one, but force the "busy" kernel module
# to block the livepatch transition.
#
Expand Down Expand Up @@ -431,8 +405,7 @@ $MOD_TARGET_BUSY: ${MOD_TARGET_BUSY}_exit"
# klp_object's post-patch callbacks executed, the remaining
# klp_object's pre-unpatch callbacks are skipped.

echo -n "TEST: busy target module ... "
dmesg -C
start_test "busy target module"

load_mod $MOD_TARGET_BUSY block_transition=Y
load_lp_nowait $MOD_LIVEPATCH
Expand Down Expand Up @@ -478,17 +451,14 @@ $MOD_TARGET_BUSY: busymod_work_func exit
$MOD_TARGET_BUSY: ${MOD_TARGET_BUSY}_exit"


# TEST: multiple livepatches
#
# Test loading multiple livepatches. This test-case is mainly for comparing
# with the next test-case.
#
# - Load and unload two livepatches, pre and post (un)patch callbacks
# execute as each patch progresses through its (un)patching
# transition.

echo -n "TEST: multiple livepatches ... "
dmesg -C
start_test "multiple livepatches"

load_lp $MOD_LIVEPATCH
load_lp $MOD_LIVEPATCH2
Expand Down Expand Up @@ -531,8 +501,6 @@ livepatch: '$MOD_LIVEPATCH': unpatching complete
% rmmod $MOD_LIVEPATCH"


# TEST: atomic replace
#
# Load multiple livepatches, but the second as an 'atomic-replace'
# patch. When the latter loads, the original livepatch should be
# disabled and *none* of its pre/post-unpatch callbacks executed. On
Expand All @@ -547,8 +515,7 @@ livepatch: '$MOD_LIVEPATCH': unpatching complete
# - Once the atomic replace module is loaded, only its pre and post
# unpatch callbacks are executed.

echo -n "TEST: atomic replace ... "
dmesg -C
start_test "atomic replace"

load_lp $MOD_LIVEPATCH
load_lp $MOD_LIVEPATCH2 replace=1
Expand Down
4 changes: 1 addition & 3 deletions tools/testing/selftests/livepatch/test-ftrace.sh
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,11 @@ MOD_LIVEPATCH=test_klp_livepatch
setup_config


# TEST: livepatch interaction with ftrace_enabled sysctl
# - turn ftrace_enabled OFF and verify livepatches can't load
# - turn ftrace_enabled ON and verify livepatch can load
# - verify that ftrace_enabled can't be turned OFF while a livepatch is loaded

echo -n "TEST: livepatch interaction with ftrace_enabled sysctl ... "
dmesg -C
start_test "livepatch interaction with ftrace_enabled sysctl"

set_ftrace_enabled 0
load_failing_mod $MOD_LIVEPATCH
Expand Down
12 changes: 3 additions & 9 deletions tools/testing/selftests/livepatch/test-livepatch.sh
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,11 @@ MOD_REPLACE=test_klp_atomic_replace
setup_config


# TEST: basic function patching
# - load a livepatch that modifies the output from /proc/cmdline and
# verify correct behavior
# - unload the livepatch and make sure the patch was removed

echo -n "TEST: basic function patching ... "
dmesg -C
start_test "basic function patching"

load_lp $MOD_LIVEPATCH

Expand Down Expand Up @@ -47,15 +45,13 @@ livepatch: '$MOD_LIVEPATCH': unpatching complete
% rmmod $MOD_LIVEPATCH"


# TEST: multiple livepatches
# - load a livepatch that modifies the output from /proc/cmdline and
# verify correct behavior
# - load another livepatch and verify that both livepatches are active
# - unload the second livepatch and verify that the first is still active
# - unload the first livepatch and verify none are active

echo -n "TEST: multiple livepatches ... "
dmesg -C
start_test "multiple livepatches"

load_lp $MOD_LIVEPATCH

Expand Down Expand Up @@ -109,16 +105,14 @@ livepatch: '$MOD_LIVEPATCH': unpatching complete
% rmmod $MOD_LIVEPATCH"


# TEST: atomic replace livepatch
# - load a livepatch that modifies the output from /proc/cmdline and
# verify correct behavior
# - load an atomic replace livepatch and verify that only the second is active
# - remove the first livepatch and verify that the atomic replace livepatch
# is still active
# - remove the atomic replace livepatch and verify that none are active

echo -n "TEST: atomic replace livepatch ... "
dmesg -C
start_test "atomic replace livepatch"

load_lp $MOD_LIVEPATCH

Expand Down
4 changes: 1 addition & 3 deletions tools/testing/selftests/livepatch/test-shadow-vars.sh
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,9 @@ MOD_TEST=test_klp_shadow_vars
setup_config


# TEST: basic shadow variable API
# - load a module that exercises the shadow variable API

echo -n "TEST: basic shadow variable API ... "
dmesg -C
start_test "basic shadow variable API"

load_mod $MOD_TEST
unload_mod $MOD_TEST
Expand Down
Loading

0 comments on commit 2eeb0d4

Please sign in to comment.