162306a36Sopenharmony_ci#!/bin/bash 262306a36Sopenharmony_ci# SPDX-License-Identifier: GPL-2.0 362306a36Sopenharmony_ci# Copyright (C) 2018 Joe Lawrence <joe.lawrence@redhat.com> 462306a36Sopenharmony_ci 562306a36Sopenharmony_ci. $(dirname $0)/functions.sh 662306a36Sopenharmony_ci 762306a36Sopenharmony_ciMOD_LIVEPATCH=test_klp_callbacks_demo 862306a36Sopenharmony_ciMOD_LIVEPATCH2=test_klp_callbacks_demo2 962306a36Sopenharmony_ciMOD_TARGET=test_klp_callbacks_mod 1062306a36Sopenharmony_ciMOD_TARGET_BUSY=test_klp_callbacks_busy 1162306a36Sopenharmony_ci 1262306a36Sopenharmony_cisetup_config 1362306a36Sopenharmony_ci 1462306a36Sopenharmony_ci 1562306a36Sopenharmony_ci# Test a combination of loading a kernel module and a livepatch that 1662306a36Sopenharmony_ci# patches a function in the first module. Load the target module 1762306a36Sopenharmony_ci# before the livepatch module. Unload them in the same order. 1862306a36Sopenharmony_ci# 1962306a36Sopenharmony_ci# - On livepatch enable, before the livepatch transition starts, 2062306a36Sopenharmony_ci# pre-patch callbacks are executed for vmlinux and $MOD_TARGET (those 2162306a36Sopenharmony_ci# klp_objects currently loaded). After klp_objects are patched 2262306a36Sopenharmony_ci# according to the klp_patch, their post-patch callbacks run and the 2362306a36Sopenharmony_ci# transition completes. 2462306a36Sopenharmony_ci# 2562306a36Sopenharmony_ci# - Similarly, on livepatch disable, pre-patch callbacks run before the 2662306a36Sopenharmony_ci# unpatching transition starts. klp_objects are reverted, post-patch 2762306a36Sopenharmony_ci# callbacks execute and the transition completes. 2862306a36Sopenharmony_ci 2962306a36Sopenharmony_cistart_test "target module before livepatch" 3062306a36Sopenharmony_ci 3162306a36Sopenharmony_ciload_mod $MOD_TARGET 3262306a36Sopenharmony_ciload_lp $MOD_LIVEPATCH 3362306a36Sopenharmony_cidisable_lp $MOD_LIVEPATCH 3462306a36Sopenharmony_ciunload_lp $MOD_LIVEPATCH 3562306a36Sopenharmony_ciunload_mod $MOD_TARGET 3662306a36Sopenharmony_ci 3762306a36Sopenharmony_cicheck_result "% modprobe $MOD_TARGET 3862306a36Sopenharmony_ci$MOD_TARGET: ${MOD_TARGET}_init 3962306a36Sopenharmony_ci% modprobe $MOD_LIVEPATCH 4062306a36Sopenharmony_cilivepatch: enabling patch '$MOD_LIVEPATCH' 4162306a36Sopenharmony_cilivepatch: '$MOD_LIVEPATCH': initializing patching transition 4262306a36Sopenharmony_ci$MOD_LIVEPATCH: pre_patch_callback: vmlinux 4362306a36Sopenharmony_ci$MOD_LIVEPATCH: pre_patch_callback: $MOD_TARGET -> [MODULE_STATE_LIVE] Normal state 4462306a36Sopenharmony_cilivepatch: '$MOD_LIVEPATCH': starting patching transition 4562306a36Sopenharmony_cilivepatch: '$MOD_LIVEPATCH': completing patching transition 4662306a36Sopenharmony_ci$MOD_LIVEPATCH: post_patch_callback: vmlinux 4762306a36Sopenharmony_ci$MOD_LIVEPATCH: post_patch_callback: $MOD_TARGET -> [MODULE_STATE_LIVE] Normal state 4862306a36Sopenharmony_cilivepatch: '$MOD_LIVEPATCH': patching complete 4962306a36Sopenharmony_ci% echo 0 > /sys/kernel/livepatch/$MOD_LIVEPATCH/enabled 5062306a36Sopenharmony_cilivepatch: '$MOD_LIVEPATCH': initializing unpatching transition 5162306a36Sopenharmony_ci$MOD_LIVEPATCH: pre_unpatch_callback: vmlinux 5262306a36Sopenharmony_ci$MOD_LIVEPATCH: pre_unpatch_callback: $MOD_TARGET -> [MODULE_STATE_LIVE] Normal state 5362306a36Sopenharmony_cilivepatch: '$MOD_LIVEPATCH': starting unpatching transition 5462306a36Sopenharmony_cilivepatch: '$MOD_LIVEPATCH': completing unpatching transition 5562306a36Sopenharmony_ci$MOD_LIVEPATCH: post_unpatch_callback: vmlinux 5662306a36Sopenharmony_ci$MOD_LIVEPATCH: post_unpatch_callback: $MOD_TARGET -> [MODULE_STATE_LIVE] Normal state 5762306a36Sopenharmony_cilivepatch: '$MOD_LIVEPATCH': unpatching complete 5862306a36Sopenharmony_ci% rmmod $MOD_LIVEPATCH 5962306a36Sopenharmony_ci% rmmod $MOD_TARGET 6062306a36Sopenharmony_ci$MOD_TARGET: ${MOD_TARGET}_exit" 6162306a36Sopenharmony_ci 6262306a36Sopenharmony_ci 6362306a36Sopenharmony_ci# This test is similar to the previous test, but (un)load the livepatch 6462306a36Sopenharmony_ci# module before the target kernel module. This tests the livepatch 6562306a36Sopenharmony_ci# core's module_coming handler. 6662306a36Sopenharmony_ci# 6762306a36Sopenharmony_ci# - On livepatch enable, only pre/post-patch callbacks are executed for 6862306a36Sopenharmony_ci# currently loaded klp_objects, in this case, vmlinux. 6962306a36Sopenharmony_ci# 7062306a36Sopenharmony_ci# - When a targeted module is subsequently loaded, only its 7162306a36Sopenharmony_ci# pre/post-patch callbacks are executed. 7262306a36Sopenharmony_ci# 7362306a36Sopenharmony_ci# - On livepatch disable, all currently loaded klp_objects' (vmlinux and 7462306a36Sopenharmony_ci# $MOD_TARGET) pre/post-unpatch callbacks are executed. 7562306a36Sopenharmony_ci 7662306a36Sopenharmony_cistart_test "module_coming notifier" 7762306a36Sopenharmony_ci 7862306a36Sopenharmony_ciload_lp $MOD_LIVEPATCH 7962306a36Sopenharmony_ciload_mod $MOD_TARGET 8062306a36Sopenharmony_cidisable_lp $MOD_LIVEPATCH 8162306a36Sopenharmony_ciunload_lp $MOD_LIVEPATCH 8262306a36Sopenharmony_ciunload_mod $MOD_TARGET 8362306a36Sopenharmony_ci 8462306a36Sopenharmony_cicheck_result "% modprobe $MOD_LIVEPATCH 8562306a36Sopenharmony_cilivepatch: enabling patch '$MOD_LIVEPATCH' 8662306a36Sopenharmony_cilivepatch: '$MOD_LIVEPATCH': initializing patching transition 8762306a36Sopenharmony_ci$MOD_LIVEPATCH: pre_patch_callback: vmlinux 8862306a36Sopenharmony_cilivepatch: '$MOD_LIVEPATCH': starting patching transition 8962306a36Sopenharmony_cilivepatch: '$MOD_LIVEPATCH': completing patching transition 9062306a36Sopenharmony_ci$MOD_LIVEPATCH: post_patch_callback: vmlinux 9162306a36Sopenharmony_cilivepatch: '$MOD_LIVEPATCH': patching complete 9262306a36Sopenharmony_ci% modprobe $MOD_TARGET 9362306a36Sopenharmony_cilivepatch: applying patch '$MOD_LIVEPATCH' to loading module '$MOD_TARGET' 9462306a36Sopenharmony_ci$MOD_LIVEPATCH: pre_patch_callback: $MOD_TARGET -> [MODULE_STATE_COMING] Full formed, running module_init 9562306a36Sopenharmony_ci$MOD_LIVEPATCH: post_patch_callback: $MOD_TARGET -> [MODULE_STATE_COMING] Full formed, running module_init 9662306a36Sopenharmony_ci$MOD_TARGET: ${MOD_TARGET}_init 9762306a36Sopenharmony_ci% echo 0 > /sys/kernel/livepatch/$MOD_LIVEPATCH/enabled 9862306a36Sopenharmony_cilivepatch: '$MOD_LIVEPATCH': initializing unpatching transition 9962306a36Sopenharmony_ci$MOD_LIVEPATCH: pre_unpatch_callback: vmlinux 10062306a36Sopenharmony_ci$MOD_LIVEPATCH: pre_unpatch_callback: $MOD_TARGET -> [MODULE_STATE_LIVE] Normal state 10162306a36Sopenharmony_cilivepatch: '$MOD_LIVEPATCH': starting unpatching transition 10262306a36Sopenharmony_cilivepatch: '$MOD_LIVEPATCH': completing unpatching transition 10362306a36Sopenharmony_ci$MOD_LIVEPATCH: post_unpatch_callback: vmlinux 10462306a36Sopenharmony_ci$MOD_LIVEPATCH: post_unpatch_callback: $MOD_TARGET -> [MODULE_STATE_LIVE] Normal state 10562306a36Sopenharmony_cilivepatch: '$MOD_LIVEPATCH': unpatching complete 10662306a36Sopenharmony_ci% rmmod $MOD_LIVEPATCH 10762306a36Sopenharmony_ci% rmmod $MOD_TARGET 10862306a36Sopenharmony_ci$MOD_TARGET: ${MOD_TARGET}_exit" 10962306a36Sopenharmony_ci 11062306a36Sopenharmony_ci 11162306a36Sopenharmony_ci# Test loading the livepatch after a targeted kernel module, then unload 11262306a36Sopenharmony_ci# the kernel module before disabling the livepatch. This tests the 11362306a36Sopenharmony_ci# livepatch core's module_going handler. 11462306a36Sopenharmony_ci# 11562306a36Sopenharmony_ci# - First load a target module, then the livepatch. 11662306a36Sopenharmony_ci# 11762306a36Sopenharmony_ci# - When a target module is unloaded, the livepatch is only reverted 11862306a36Sopenharmony_ci# from that klp_object ($MOD_TARGET). As such, only its pre and 11962306a36Sopenharmony_ci# post-unpatch callbacks are executed when this occurs. 12062306a36Sopenharmony_ci# 12162306a36Sopenharmony_ci# - When the livepatch is disabled, pre and post-unpatch callbacks are 12262306a36Sopenharmony_ci# run for the remaining klp_object, vmlinux. 12362306a36Sopenharmony_ci 12462306a36Sopenharmony_cistart_test "module_going notifier" 12562306a36Sopenharmony_ci 12662306a36Sopenharmony_ciload_mod $MOD_TARGET 12762306a36Sopenharmony_ciload_lp $MOD_LIVEPATCH 12862306a36Sopenharmony_ciunload_mod $MOD_TARGET 12962306a36Sopenharmony_cidisable_lp $MOD_LIVEPATCH 13062306a36Sopenharmony_ciunload_lp $MOD_LIVEPATCH 13162306a36Sopenharmony_ci 13262306a36Sopenharmony_cicheck_result "% modprobe $MOD_TARGET 13362306a36Sopenharmony_ci$MOD_TARGET: ${MOD_TARGET}_init 13462306a36Sopenharmony_ci% modprobe $MOD_LIVEPATCH 13562306a36Sopenharmony_cilivepatch: enabling patch '$MOD_LIVEPATCH' 13662306a36Sopenharmony_cilivepatch: '$MOD_LIVEPATCH': initializing patching transition 13762306a36Sopenharmony_ci$MOD_LIVEPATCH: pre_patch_callback: vmlinux 13862306a36Sopenharmony_ci$MOD_LIVEPATCH: pre_patch_callback: $MOD_TARGET -> [MODULE_STATE_LIVE] Normal state 13962306a36Sopenharmony_cilivepatch: '$MOD_LIVEPATCH': starting patching transition 14062306a36Sopenharmony_cilivepatch: '$MOD_LIVEPATCH': completing patching transition 14162306a36Sopenharmony_ci$MOD_LIVEPATCH: post_patch_callback: vmlinux 14262306a36Sopenharmony_ci$MOD_LIVEPATCH: post_patch_callback: $MOD_TARGET -> [MODULE_STATE_LIVE] Normal state 14362306a36Sopenharmony_cilivepatch: '$MOD_LIVEPATCH': patching complete 14462306a36Sopenharmony_ci% rmmod $MOD_TARGET 14562306a36Sopenharmony_ci$MOD_TARGET: ${MOD_TARGET}_exit 14662306a36Sopenharmony_ci$MOD_LIVEPATCH: pre_unpatch_callback: $MOD_TARGET -> [MODULE_STATE_GOING] Going away 14762306a36Sopenharmony_cilivepatch: reverting patch '$MOD_LIVEPATCH' on unloading module '$MOD_TARGET' 14862306a36Sopenharmony_ci$MOD_LIVEPATCH: post_unpatch_callback: $MOD_TARGET -> [MODULE_STATE_GOING] Going away 14962306a36Sopenharmony_ci% echo 0 > /sys/kernel/livepatch/$MOD_LIVEPATCH/enabled 15062306a36Sopenharmony_cilivepatch: '$MOD_LIVEPATCH': initializing unpatching transition 15162306a36Sopenharmony_ci$MOD_LIVEPATCH: pre_unpatch_callback: vmlinux 15262306a36Sopenharmony_cilivepatch: '$MOD_LIVEPATCH': starting unpatching transition 15362306a36Sopenharmony_cilivepatch: '$MOD_LIVEPATCH': completing unpatching transition 15462306a36Sopenharmony_ci$MOD_LIVEPATCH: post_unpatch_callback: vmlinux 15562306a36Sopenharmony_cilivepatch: '$MOD_LIVEPATCH': unpatching complete 15662306a36Sopenharmony_ci% rmmod $MOD_LIVEPATCH" 15762306a36Sopenharmony_ci 15862306a36Sopenharmony_ci 15962306a36Sopenharmony_ci# This test is similar to the previous test, however the livepatch is 16062306a36Sopenharmony_ci# loaded first. This tests the livepatch core's module_coming and 16162306a36Sopenharmony_ci# module_going handlers. 16262306a36Sopenharmony_ci# 16362306a36Sopenharmony_ci# - First load the livepatch. 16462306a36Sopenharmony_ci# 16562306a36Sopenharmony_ci# - When a targeted kernel module is subsequently loaded, only its 16662306a36Sopenharmony_ci# pre/post-patch callbacks are executed. 16762306a36Sopenharmony_ci# 16862306a36Sopenharmony_ci# - When the target module is unloaded, the livepatch is only reverted 16962306a36Sopenharmony_ci# from the $MOD_TARGET klp_object. As such, only pre and 17062306a36Sopenharmony_ci# post-unpatch callbacks are executed when this occurs. 17162306a36Sopenharmony_ci 17262306a36Sopenharmony_cistart_test "module_coming and module_going notifiers" 17362306a36Sopenharmony_ci 17462306a36Sopenharmony_ciload_lp $MOD_LIVEPATCH 17562306a36Sopenharmony_ciload_mod $MOD_TARGET 17662306a36Sopenharmony_ciunload_mod $MOD_TARGET 17762306a36Sopenharmony_cidisable_lp $MOD_LIVEPATCH 17862306a36Sopenharmony_ciunload_lp $MOD_LIVEPATCH 17962306a36Sopenharmony_ci 18062306a36Sopenharmony_cicheck_result "% modprobe $MOD_LIVEPATCH 18162306a36Sopenharmony_cilivepatch: enabling patch '$MOD_LIVEPATCH' 18262306a36Sopenharmony_cilivepatch: '$MOD_LIVEPATCH': initializing patching transition 18362306a36Sopenharmony_ci$MOD_LIVEPATCH: pre_patch_callback: vmlinux 18462306a36Sopenharmony_cilivepatch: '$MOD_LIVEPATCH': starting patching transition 18562306a36Sopenharmony_cilivepatch: '$MOD_LIVEPATCH': completing patching transition 18662306a36Sopenharmony_ci$MOD_LIVEPATCH: post_patch_callback: vmlinux 18762306a36Sopenharmony_cilivepatch: '$MOD_LIVEPATCH': patching complete 18862306a36Sopenharmony_ci% modprobe $MOD_TARGET 18962306a36Sopenharmony_cilivepatch: applying patch '$MOD_LIVEPATCH' to loading module '$MOD_TARGET' 19062306a36Sopenharmony_ci$MOD_LIVEPATCH: pre_patch_callback: $MOD_TARGET -> [MODULE_STATE_COMING] Full formed, running module_init 19162306a36Sopenharmony_ci$MOD_LIVEPATCH: post_patch_callback: $MOD_TARGET -> [MODULE_STATE_COMING] Full formed, running module_init 19262306a36Sopenharmony_ci$MOD_TARGET: ${MOD_TARGET}_init 19362306a36Sopenharmony_ci% rmmod $MOD_TARGET 19462306a36Sopenharmony_ci$MOD_TARGET: ${MOD_TARGET}_exit 19562306a36Sopenharmony_ci$MOD_LIVEPATCH: pre_unpatch_callback: $MOD_TARGET -> [MODULE_STATE_GOING] Going away 19662306a36Sopenharmony_cilivepatch: reverting patch '$MOD_LIVEPATCH' on unloading module '$MOD_TARGET' 19762306a36Sopenharmony_ci$MOD_LIVEPATCH: post_unpatch_callback: $MOD_TARGET -> [MODULE_STATE_GOING] Going away 19862306a36Sopenharmony_ci% echo 0 > /sys/kernel/livepatch/$MOD_LIVEPATCH/enabled 19962306a36Sopenharmony_cilivepatch: '$MOD_LIVEPATCH': initializing unpatching transition 20062306a36Sopenharmony_ci$MOD_LIVEPATCH: pre_unpatch_callback: vmlinux 20162306a36Sopenharmony_cilivepatch: '$MOD_LIVEPATCH': starting unpatching transition 20262306a36Sopenharmony_cilivepatch: '$MOD_LIVEPATCH': completing unpatching transition 20362306a36Sopenharmony_ci$MOD_LIVEPATCH: post_unpatch_callback: vmlinux 20462306a36Sopenharmony_cilivepatch: '$MOD_LIVEPATCH': unpatching complete 20562306a36Sopenharmony_ci% rmmod $MOD_LIVEPATCH" 20662306a36Sopenharmony_ci 20762306a36Sopenharmony_ci 20862306a36Sopenharmony_ci# A simple test of loading a livepatch without one of its patch target 20962306a36Sopenharmony_ci# klp_objects ever loaded ($MOD_TARGET). 21062306a36Sopenharmony_ci# 21162306a36Sopenharmony_ci# - Load the livepatch. 21262306a36Sopenharmony_ci# 21362306a36Sopenharmony_ci# - As expected, only pre/post-(un)patch handlers are executed for 21462306a36Sopenharmony_ci# vmlinux. 21562306a36Sopenharmony_ci 21662306a36Sopenharmony_cistart_test "target module not present" 21762306a36Sopenharmony_ci 21862306a36Sopenharmony_ciload_lp $MOD_LIVEPATCH 21962306a36Sopenharmony_cidisable_lp $MOD_LIVEPATCH 22062306a36Sopenharmony_ciunload_lp $MOD_LIVEPATCH 22162306a36Sopenharmony_ci 22262306a36Sopenharmony_cicheck_result "% modprobe $MOD_LIVEPATCH 22362306a36Sopenharmony_cilivepatch: enabling patch '$MOD_LIVEPATCH' 22462306a36Sopenharmony_cilivepatch: '$MOD_LIVEPATCH': initializing patching transition 22562306a36Sopenharmony_ci$MOD_LIVEPATCH: pre_patch_callback: vmlinux 22662306a36Sopenharmony_cilivepatch: '$MOD_LIVEPATCH': starting patching transition 22762306a36Sopenharmony_cilivepatch: '$MOD_LIVEPATCH': completing patching transition 22862306a36Sopenharmony_ci$MOD_LIVEPATCH: post_patch_callback: vmlinux 22962306a36Sopenharmony_cilivepatch: '$MOD_LIVEPATCH': patching complete 23062306a36Sopenharmony_ci% echo 0 > /sys/kernel/livepatch/$MOD_LIVEPATCH/enabled 23162306a36Sopenharmony_cilivepatch: '$MOD_LIVEPATCH': initializing unpatching transition 23262306a36Sopenharmony_ci$MOD_LIVEPATCH: pre_unpatch_callback: vmlinux 23362306a36Sopenharmony_cilivepatch: '$MOD_LIVEPATCH': starting unpatching transition 23462306a36Sopenharmony_cilivepatch: '$MOD_LIVEPATCH': completing unpatching transition 23562306a36Sopenharmony_ci$MOD_LIVEPATCH: post_unpatch_callback: vmlinux 23662306a36Sopenharmony_cilivepatch: '$MOD_LIVEPATCH': unpatching complete 23762306a36Sopenharmony_ci% rmmod $MOD_LIVEPATCH" 23862306a36Sopenharmony_ci 23962306a36Sopenharmony_ci 24062306a36Sopenharmony_ci# Test a scenario where a vmlinux pre-patch callback returns a non-zero 24162306a36Sopenharmony_ci# status (ie, failure). 24262306a36Sopenharmony_ci# 24362306a36Sopenharmony_ci# - First load a target module. 24462306a36Sopenharmony_ci# 24562306a36Sopenharmony_ci# - Load the livepatch module, setting its 'pre_patch_ret' value to -19 24662306a36Sopenharmony_ci# (-ENODEV). When its vmlinux pre-patch callback executes, this 24762306a36Sopenharmony_ci# status code will propagate back to the module-loading subsystem. 24862306a36Sopenharmony_ci# The result is that the insmod command refuses to load the livepatch 24962306a36Sopenharmony_ci# module. 25062306a36Sopenharmony_ci 25162306a36Sopenharmony_cistart_test "pre-patch callback -ENODEV" 25262306a36Sopenharmony_ci 25362306a36Sopenharmony_ciload_mod $MOD_TARGET 25462306a36Sopenharmony_ciload_failing_mod $MOD_LIVEPATCH pre_patch_ret=-19 25562306a36Sopenharmony_ciunload_mod $MOD_TARGET 25662306a36Sopenharmony_ci 25762306a36Sopenharmony_cicheck_result "% modprobe $MOD_TARGET 25862306a36Sopenharmony_ci$MOD_TARGET: ${MOD_TARGET}_init 25962306a36Sopenharmony_ci% modprobe $MOD_LIVEPATCH pre_patch_ret=-19 26062306a36Sopenharmony_cilivepatch: enabling patch '$MOD_LIVEPATCH' 26162306a36Sopenharmony_cilivepatch: '$MOD_LIVEPATCH': initializing patching transition 26262306a36Sopenharmony_citest_klp_callbacks_demo: pre_patch_callback: vmlinux 26362306a36Sopenharmony_cilivepatch: pre-patch callback failed for object 'vmlinux' 26462306a36Sopenharmony_cilivepatch: failed to enable patch '$MOD_LIVEPATCH' 26562306a36Sopenharmony_cilivepatch: '$MOD_LIVEPATCH': canceling patching transition, going to unpatch 26662306a36Sopenharmony_cilivepatch: '$MOD_LIVEPATCH': completing unpatching transition 26762306a36Sopenharmony_cilivepatch: '$MOD_LIVEPATCH': unpatching complete 26862306a36Sopenharmony_cimodprobe: ERROR: could not insert '$MOD_LIVEPATCH': No such device 26962306a36Sopenharmony_ci% rmmod $MOD_TARGET 27062306a36Sopenharmony_ci$MOD_TARGET: ${MOD_TARGET}_exit" 27162306a36Sopenharmony_ci 27262306a36Sopenharmony_ci 27362306a36Sopenharmony_ci# Similar to the previous test, setup a livepatch such that its vmlinux 27462306a36Sopenharmony_ci# pre-patch callback returns success. However, when a targeted kernel 27562306a36Sopenharmony_ci# module is later loaded, have the livepatch return a failing status 27662306a36Sopenharmony_ci# code. 27762306a36Sopenharmony_ci# 27862306a36Sopenharmony_ci# - Load the livepatch, vmlinux pre-patch callback succeeds. 27962306a36Sopenharmony_ci# 28062306a36Sopenharmony_ci# - Set a trap so subsequent pre-patch callbacks to this livepatch will 28162306a36Sopenharmony_ci# return -ENODEV. 28262306a36Sopenharmony_ci# 28362306a36Sopenharmony_ci# - The livepatch pre-patch callback for subsequently loaded target 28462306a36Sopenharmony_ci# modules will return failure, so the module loader refuses to load 28562306a36Sopenharmony_ci# the kernel module. No post-patch or pre/post-unpatch callbacks are 28662306a36Sopenharmony_ci# executed for this klp_object. 28762306a36Sopenharmony_ci# 28862306a36Sopenharmony_ci# - Pre/post-unpatch callbacks are run for the vmlinux klp_object. 28962306a36Sopenharmony_ci 29062306a36Sopenharmony_cistart_test "module_coming + pre-patch callback -ENODEV" 29162306a36Sopenharmony_ci 29262306a36Sopenharmony_ciload_lp $MOD_LIVEPATCH 29362306a36Sopenharmony_ciset_pre_patch_ret $MOD_LIVEPATCH -19 29462306a36Sopenharmony_ciload_failing_mod $MOD_TARGET 29562306a36Sopenharmony_cidisable_lp $MOD_LIVEPATCH 29662306a36Sopenharmony_ciunload_lp $MOD_LIVEPATCH 29762306a36Sopenharmony_ci 29862306a36Sopenharmony_cicheck_result "% modprobe $MOD_LIVEPATCH 29962306a36Sopenharmony_cilivepatch: enabling patch '$MOD_LIVEPATCH' 30062306a36Sopenharmony_cilivepatch: '$MOD_LIVEPATCH': initializing patching transition 30162306a36Sopenharmony_ci$MOD_LIVEPATCH: pre_patch_callback: vmlinux 30262306a36Sopenharmony_cilivepatch: '$MOD_LIVEPATCH': starting patching transition 30362306a36Sopenharmony_cilivepatch: '$MOD_LIVEPATCH': completing patching transition 30462306a36Sopenharmony_ci$MOD_LIVEPATCH: post_patch_callback: vmlinux 30562306a36Sopenharmony_cilivepatch: '$MOD_LIVEPATCH': patching complete 30662306a36Sopenharmony_ci% echo -19 > /sys/module/$MOD_LIVEPATCH/parameters/pre_patch_ret 30762306a36Sopenharmony_ci% modprobe $MOD_TARGET 30862306a36Sopenharmony_cilivepatch: applying patch '$MOD_LIVEPATCH' to loading module '$MOD_TARGET' 30962306a36Sopenharmony_ci$MOD_LIVEPATCH: pre_patch_callback: $MOD_TARGET -> [MODULE_STATE_COMING] Full formed, running module_init 31062306a36Sopenharmony_cilivepatch: pre-patch callback failed for object '$MOD_TARGET' 31162306a36Sopenharmony_cilivepatch: patch '$MOD_LIVEPATCH' failed for module '$MOD_TARGET', refusing to load module '$MOD_TARGET' 31262306a36Sopenharmony_cimodprobe: ERROR: could not insert '$MOD_TARGET': No such device 31362306a36Sopenharmony_ci% echo 0 > /sys/kernel/livepatch/$MOD_LIVEPATCH/enabled 31462306a36Sopenharmony_cilivepatch: '$MOD_LIVEPATCH': initializing unpatching transition 31562306a36Sopenharmony_ci$MOD_LIVEPATCH: pre_unpatch_callback: vmlinux 31662306a36Sopenharmony_cilivepatch: '$MOD_LIVEPATCH': starting unpatching transition 31762306a36Sopenharmony_cilivepatch: '$MOD_LIVEPATCH': completing unpatching transition 31862306a36Sopenharmony_ci$MOD_LIVEPATCH: post_unpatch_callback: vmlinux 31962306a36Sopenharmony_cilivepatch: '$MOD_LIVEPATCH': unpatching complete 32062306a36Sopenharmony_ci% rmmod $MOD_LIVEPATCH" 32162306a36Sopenharmony_ci 32262306a36Sopenharmony_ci 32362306a36Sopenharmony_ci# Test loading multiple targeted kernel modules. This test-case is 32462306a36Sopenharmony_ci# mainly for comparing with the next test-case. 32562306a36Sopenharmony_ci# 32662306a36Sopenharmony_ci# - Load a target "busy" kernel module which kicks off a worker function 32762306a36Sopenharmony_ci# that immediately exits. 32862306a36Sopenharmony_ci# 32962306a36Sopenharmony_ci# - Proceed with loading the livepatch and another ordinary target 33062306a36Sopenharmony_ci# module. Post-patch callbacks are executed and the transition 33162306a36Sopenharmony_ci# completes quickly. 33262306a36Sopenharmony_ci 33362306a36Sopenharmony_cistart_test "multiple target modules" 33462306a36Sopenharmony_ci 33562306a36Sopenharmony_ciload_mod $MOD_TARGET_BUSY block_transition=N 33662306a36Sopenharmony_ciload_lp $MOD_LIVEPATCH 33762306a36Sopenharmony_ciload_mod $MOD_TARGET 33862306a36Sopenharmony_ciunload_mod $MOD_TARGET 33962306a36Sopenharmony_cidisable_lp $MOD_LIVEPATCH 34062306a36Sopenharmony_ciunload_lp $MOD_LIVEPATCH 34162306a36Sopenharmony_ciunload_mod $MOD_TARGET_BUSY 34262306a36Sopenharmony_ci 34362306a36Sopenharmony_cicheck_result "% modprobe $MOD_TARGET_BUSY block_transition=N 34462306a36Sopenharmony_ci$MOD_TARGET_BUSY: ${MOD_TARGET_BUSY}_init 34562306a36Sopenharmony_ci$MOD_TARGET_BUSY: busymod_work_func enter 34662306a36Sopenharmony_ci$MOD_TARGET_BUSY: busymod_work_func exit 34762306a36Sopenharmony_ci% modprobe $MOD_LIVEPATCH 34862306a36Sopenharmony_cilivepatch: enabling patch '$MOD_LIVEPATCH' 34962306a36Sopenharmony_cilivepatch: '$MOD_LIVEPATCH': initializing patching transition 35062306a36Sopenharmony_ci$MOD_LIVEPATCH: pre_patch_callback: vmlinux 35162306a36Sopenharmony_ci$MOD_LIVEPATCH: pre_patch_callback: $MOD_TARGET_BUSY -> [MODULE_STATE_LIVE] Normal state 35262306a36Sopenharmony_cilivepatch: '$MOD_LIVEPATCH': starting patching transition 35362306a36Sopenharmony_cilivepatch: '$MOD_LIVEPATCH': completing patching transition 35462306a36Sopenharmony_ci$MOD_LIVEPATCH: post_patch_callback: vmlinux 35562306a36Sopenharmony_ci$MOD_LIVEPATCH: post_patch_callback: $MOD_TARGET_BUSY -> [MODULE_STATE_LIVE] Normal state 35662306a36Sopenharmony_cilivepatch: '$MOD_LIVEPATCH': patching complete 35762306a36Sopenharmony_ci% modprobe $MOD_TARGET 35862306a36Sopenharmony_cilivepatch: applying patch '$MOD_LIVEPATCH' to loading module '$MOD_TARGET' 35962306a36Sopenharmony_ci$MOD_LIVEPATCH: pre_patch_callback: $MOD_TARGET -> [MODULE_STATE_COMING] Full formed, running module_init 36062306a36Sopenharmony_ci$MOD_LIVEPATCH: post_patch_callback: $MOD_TARGET -> [MODULE_STATE_COMING] Full formed, running module_init 36162306a36Sopenharmony_ci$MOD_TARGET: ${MOD_TARGET}_init 36262306a36Sopenharmony_ci% rmmod $MOD_TARGET 36362306a36Sopenharmony_ci$MOD_TARGET: ${MOD_TARGET}_exit 36462306a36Sopenharmony_ci$MOD_LIVEPATCH: pre_unpatch_callback: $MOD_TARGET -> [MODULE_STATE_GOING] Going away 36562306a36Sopenharmony_cilivepatch: reverting patch '$MOD_LIVEPATCH' on unloading module '$MOD_TARGET' 36662306a36Sopenharmony_ci$MOD_LIVEPATCH: post_unpatch_callback: $MOD_TARGET -> [MODULE_STATE_GOING] Going away 36762306a36Sopenharmony_ci% echo 0 > /sys/kernel/livepatch/$MOD_LIVEPATCH/enabled 36862306a36Sopenharmony_cilivepatch: '$MOD_LIVEPATCH': initializing unpatching transition 36962306a36Sopenharmony_ci$MOD_LIVEPATCH: pre_unpatch_callback: vmlinux 37062306a36Sopenharmony_ci$MOD_LIVEPATCH: pre_unpatch_callback: $MOD_TARGET_BUSY -> [MODULE_STATE_LIVE] Normal state 37162306a36Sopenharmony_cilivepatch: '$MOD_LIVEPATCH': starting unpatching transition 37262306a36Sopenharmony_cilivepatch: '$MOD_LIVEPATCH': completing unpatching transition 37362306a36Sopenharmony_ci$MOD_LIVEPATCH: post_unpatch_callback: vmlinux 37462306a36Sopenharmony_ci$MOD_LIVEPATCH: post_unpatch_callback: $MOD_TARGET_BUSY -> [MODULE_STATE_LIVE] Normal state 37562306a36Sopenharmony_cilivepatch: '$MOD_LIVEPATCH': unpatching complete 37662306a36Sopenharmony_ci% rmmod $MOD_LIVEPATCH 37762306a36Sopenharmony_ci% rmmod $MOD_TARGET_BUSY 37862306a36Sopenharmony_ci$MOD_TARGET_BUSY: ${MOD_TARGET_BUSY}_exit" 37962306a36Sopenharmony_ci 38062306a36Sopenharmony_ci 38162306a36Sopenharmony_ci# A similar test as the previous one, but force the "busy" kernel module 38262306a36Sopenharmony_ci# to block the livepatch transition. 38362306a36Sopenharmony_ci# 38462306a36Sopenharmony_ci# The livepatching core will refuse to patch a task that is currently 38562306a36Sopenharmony_ci# executing a to-be-patched function -- the consistency model stalls the 38662306a36Sopenharmony_ci# current patch transition until this safety-check is met. Test a 38762306a36Sopenharmony_ci# scenario where one of a livepatch's target klp_objects sits on such a 38862306a36Sopenharmony_ci# function for a long time. Meanwhile, load and unload other target 38962306a36Sopenharmony_ci# kernel modules while the livepatch transition is in progress. 39062306a36Sopenharmony_ci# 39162306a36Sopenharmony_ci# - Load the "busy" kernel module, this time make its work function loop 39262306a36Sopenharmony_ci# 39362306a36Sopenharmony_ci# - Meanwhile, the livepatch is loaded. Notice that the patch 39462306a36Sopenharmony_ci# transition does not complete as the targeted "busy" module is 39562306a36Sopenharmony_ci# sitting on a to-be-patched function. 39662306a36Sopenharmony_ci# 39762306a36Sopenharmony_ci# - Load a second target module (this one is an ordinary idle kernel 39862306a36Sopenharmony_ci# module). Note that *no* post-patch callbacks will be executed while 39962306a36Sopenharmony_ci# the livepatch is still in transition. 40062306a36Sopenharmony_ci# 40162306a36Sopenharmony_ci# - Request an unload of the simple kernel module. The patch is still 40262306a36Sopenharmony_ci# transitioning, so its pre-unpatch callbacks are skipped. 40362306a36Sopenharmony_ci# 40462306a36Sopenharmony_ci# - Finally the livepatch is disabled. Since none of the patch's 40562306a36Sopenharmony_ci# klp_object's post-patch callbacks executed, the remaining 40662306a36Sopenharmony_ci# klp_object's pre-unpatch callbacks are skipped. 40762306a36Sopenharmony_ci 40862306a36Sopenharmony_cistart_test "busy target module" 40962306a36Sopenharmony_ci 41062306a36Sopenharmony_ciload_mod $MOD_TARGET_BUSY block_transition=Y 41162306a36Sopenharmony_ciload_lp_nowait $MOD_LIVEPATCH 41262306a36Sopenharmony_ci 41362306a36Sopenharmony_ci# Wait until the livepatch reports in-transition state, i.e. that it's 41462306a36Sopenharmony_ci# stalled on $MOD_TARGET_BUSY::busymod_work_func() 41562306a36Sopenharmony_ciloop_until 'grep -q '^1$' /sys/kernel/livepatch/$MOD_LIVEPATCH/transition' || 41662306a36Sopenharmony_ci die "failed to stall transition" 41762306a36Sopenharmony_ci 41862306a36Sopenharmony_ciload_mod $MOD_TARGET 41962306a36Sopenharmony_ciunload_mod $MOD_TARGET 42062306a36Sopenharmony_cidisable_lp $MOD_LIVEPATCH 42162306a36Sopenharmony_ciunload_lp $MOD_LIVEPATCH 42262306a36Sopenharmony_ciunload_mod $MOD_TARGET_BUSY 42362306a36Sopenharmony_ci 42462306a36Sopenharmony_cicheck_result "% modprobe $MOD_TARGET_BUSY block_transition=Y 42562306a36Sopenharmony_ci$MOD_TARGET_BUSY: ${MOD_TARGET_BUSY}_init 42662306a36Sopenharmony_ci$MOD_TARGET_BUSY: busymod_work_func enter 42762306a36Sopenharmony_ci% modprobe $MOD_LIVEPATCH 42862306a36Sopenharmony_cilivepatch: enabling patch '$MOD_LIVEPATCH' 42962306a36Sopenharmony_cilivepatch: '$MOD_LIVEPATCH': initializing patching transition 43062306a36Sopenharmony_ci$MOD_LIVEPATCH: pre_patch_callback: vmlinux 43162306a36Sopenharmony_ci$MOD_LIVEPATCH: pre_patch_callback: $MOD_TARGET_BUSY -> [MODULE_STATE_LIVE] Normal state 43262306a36Sopenharmony_cilivepatch: '$MOD_LIVEPATCH': starting patching transition 43362306a36Sopenharmony_ci% modprobe $MOD_TARGET 43462306a36Sopenharmony_cilivepatch: applying patch '$MOD_LIVEPATCH' to loading module '$MOD_TARGET' 43562306a36Sopenharmony_ci$MOD_LIVEPATCH: pre_patch_callback: $MOD_TARGET -> [MODULE_STATE_COMING] Full formed, running module_init 43662306a36Sopenharmony_ci$MOD_TARGET: ${MOD_TARGET}_init 43762306a36Sopenharmony_ci% rmmod $MOD_TARGET 43862306a36Sopenharmony_ci$MOD_TARGET: ${MOD_TARGET}_exit 43962306a36Sopenharmony_cilivepatch: reverting patch '$MOD_LIVEPATCH' on unloading module '$MOD_TARGET' 44062306a36Sopenharmony_ci$MOD_LIVEPATCH: post_unpatch_callback: $MOD_TARGET -> [MODULE_STATE_GOING] Going away 44162306a36Sopenharmony_ci% echo 0 > /sys/kernel/livepatch/$MOD_LIVEPATCH/enabled 44262306a36Sopenharmony_cilivepatch: '$MOD_LIVEPATCH': reversing transition from patching to unpatching 44362306a36Sopenharmony_cilivepatch: '$MOD_LIVEPATCH': starting unpatching transition 44462306a36Sopenharmony_cilivepatch: '$MOD_LIVEPATCH': completing unpatching transition 44562306a36Sopenharmony_ci$MOD_LIVEPATCH: post_unpatch_callback: vmlinux 44662306a36Sopenharmony_ci$MOD_LIVEPATCH: post_unpatch_callback: $MOD_TARGET_BUSY -> [MODULE_STATE_LIVE] Normal state 44762306a36Sopenharmony_cilivepatch: '$MOD_LIVEPATCH': unpatching complete 44862306a36Sopenharmony_ci% rmmod $MOD_LIVEPATCH 44962306a36Sopenharmony_ci% rmmod $MOD_TARGET_BUSY 45062306a36Sopenharmony_ci$MOD_TARGET_BUSY: busymod_work_func exit 45162306a36Sopenharmony_ci$MOD_TARGET_BUSY: ${MOD_TARGET_BUSY}_exit" 45262306a36Sopenharmony_ci 45362306a36Sopenharmony_ci 45462306a36Sopenharmony_ci# Test loading multiple livepatches. This test-case is mainly for comparing 45562306a36Sopenharmony_ci# with the next test-case. 45662306a36Sopenharmony_ci# 45762306a36Sopenharmony_ci# - Load and unload two livepatches, pre and post (un)patch callbacks 45862306a36Sopenharmony_ci# execute as each patch progresses through its (un)patching 45962306a36Sopenharmony_ci# transition. 46062306a36Sopenharmony_ci 46162306a36Sopenharmony_cistart_test "multiple livepatches" 46262306a36Sopenharmony_ci 46362306a36Sopenharmony_ciload_lp $MOD_LIVEPATCH 46462306a36Sopenharmony_ciload_lp $MOD_LIVEPATCH2 46562306a36Sopenharmony_cidisable_lp $MOD_LIVEPATCH2 46662306a36Sopenharmony_cidisable_lp $MOD_LIVEPATCH 46762306a36Sopenharmony_ciunload_lp $MOD_LIVEPATCH2 46862306a36Sopenharmony_ciunload_lp $MOD_LIVEPATCH 46962306a36Sopenharmony_ci 47062306a36Sopenharmony_cicheck_result "% modprobe $MOD_LIVEPATCH 47162306a36Sopenharmony_cilivepatch: enabling patch '$MOD_LIVEPATCH' 47262306a36Sopenharmony_cilivepatch: '$MOD_LIVEPATCH': initializing patching transition 47362306a36Sopenharmony_ci$MOD_LIVEPATCH: pre_patch_callback: vmlinux 47462306a36Sopenharmony_cilivepatch: '$MOD_LIVEPATCH': starting patching transition 47562306a36Sopenharmony_cilivepatch: '$MOD_LIVEPATCH': completing patching transition 47662306a36Sopenharmony_ci$MOD_LIVEPATCH: post_patch_callback: vmlinux 47762306a36Sopenharmony_cilivepatch: '$MOD_LIVEPATCH': patching complete 47862306a36Sopenharmony_ci% modprobe $MOD_LIVEPATCH2 47962306a36Sopenharmony_cilivepatch: enabling patch '$MOD_LIVEPATCH2' 48062306a36Sopenharmony_cilivepatch: '$MOD_LIVEPATCH2': initializing patching transition 48162306a36Sopenharmony_ci$MOD_LIVEPATCH2: pre_patch_callback: vmlinux 48262306a36Sopenharmony_cilivepatch: '$MOD_LIVEPATCH2': starting patching transition 48362306a36Sopenharmony_cilivepatch: '$MOD_LIVEPATCH2': completing patching transition 48462306a36Sopenharmony_ci$MOD_LIVEPATCH2: post_patch_callback: vmlinux 48562306a36Sopenharmony_cilivepatch: '$MOD_LIVEPATCH2': patching complete 48662306a36Sopenharmony_ci% echo 0 > /sys/kernel/livepatch/$MOD_LIVEPATCH2/enabled 48762306a36Sopenharmony_cilivepatch: '$MOD_LIVEPATCH2': initializing unpatching transition 48862306a36Sopenharmony_ci$MOD_LIVEPATCH2: pre_unpatch_callback: vmlinux 48962306a36Sopenharmony_cilivepatch: '$MOD_LIVEPATCH2': starting unpatching transition 49062306a36Sopenharmony_cilivepatch: '$MOD_LIVEPATCH2': completing unpatching transition 49162306a36Sopenharmony_ci$MOD_LIVEPATCH2: post_unpatch_callback: vmlinux 49262306a36Sopenharmony_cilivepatch: '$MOD_LIVEPATCH2': unpatching complete 49362306a36Sopenharmony_ci% echo 0 > /sys/kernel/livepatch/$MOD_LIVEPATCH/enabled 49462306a36Sopenharmony_cilivepatch: '$MOD_LIVEPATCH': initializing unpatching transition 49562306a36Sopenharmony_ci$MOD_LIVEPATCH: pre_unpatch_callback: vmlinux 49662306a36Sopenharmony_cilivepatch: '$MOD_LIVEPATCH': starting unpatching transition 49762306a36Sopenharmony_cilivepatch: '$MOD_LIVEPATCH': completing unpatching transition 49862306a36Sopenharmony_ci$MOD_LIVEPATCH: post_unpatch_callback: vmlinux 49962306a36Sopenharmony_cilivepatch: '$MOD_LIVEPATCH': unpatching complete 50062306a36Sopenharmony_ci% rmmod $MOD_LIVEPATCH2 50162306a36Sopenharmony_ci% rmmod $MOD_LIVEPATCH" 50262306a36Sopenharmony_ci 50362306a36Sopenharmony_ci 50462306a36Sopenharmony_ci# Load multiple livepatches, but the second as an 'atomic-replace' 50562306a36Sopenharmony_ci# patch. When the latter loads, the original livepatch should be 50662306a36Sopenharmony_ci# disabled and *none* of its pre/post-unpatch callbacks executed. On 50762306a36Sopenharmony_ci# the other hand, when the atomic-replace livepatch is disabled, its 50862306a36Sopenharmony_ci# pre/post-unpatch callbacks *should* be executed. 50962306a36Sopenharmony_ci# 51062306a36Sopenharmony_ci# - Load and unload two livepatches, the second of which has its 51162306a36Sopenharmony_ci# .replace flag set true. 51262306a36Sopenharmony_ci# 51362306a36Sopenharmony_ci# - Pre and post patch callbacks are executed for both livepatches. 51462306a36Sopenharmony_ci# 51562306a36Sopenharmony_ci# - Once the atomic replace module is loaded, only its pre and post 51662306a36Sopenharmony_ci# unpatch callbacks are executed. 51762306a36Sopenharmony_ci 51862306a36Sopenharmony_cistart_test "atomic replace" 51962306a36Sopenharmony_ci 52062306a36Sopenharmony_ciload_lp $MOD_LIVEPATCH 52162306a36Sopenharmony_ciload_lp $MOD_LIVEPATCH2 replace=1 52262306a36Sopenharmony_cidisable_lp $MOD_LIVEPATCH2 52362306a36Sopenharmony_ciunload_lp $MOD_LIVEPATCH2 52462306a36Sopenharmony_ciunload_lp $MOD_LIVEPATCH 52562306a36Sopenharmony_ci 52662306a36Sopenharmony_cicheck_result "% modprobe $MOD_LIVEPATCH 52762306a36Sopenharmony_cilivepatch: enabling patch '$MOD_LIVEPATCH' 52862306a36Sopenharmony_cilivepatch: '$MOD_LIVEPATCH': initializing patching transition 52962306a36Sopenharmony_ci$MOD_LIVEPATCH: pre_patch_callback: vmlinux 53062306a36Sopenharmony_cilivepatch: '$MOD_LIVEPATCH': starting patching transition 53162306a36Sopenharmony_cilivepatch: '$MOD_LIVEPATCH': completing patching transition 53262306a36Sopenharmony_ci$MOD_LIVEPATCH: post_patch_callback: vmlinux 53362306a36Sopenharmony_cilivepatch: '$MOD_LIVEPATCH': patching complete 53462306a36Sopenharmony_ci% modprobe $MOD_LIVEPATCH2 replace=1 53562306a36Sopenharmony_cilivepatch: enabling patch '$MOD_LIVEPATCH2' 53662306a36Sopenharmony_cilivepatch: '$MOD_LIVEPATCH2': initializing patching transition 53762306a36Sopenharmony_ci$MOD_LIVEPATCH2: pre_patch_callback: vmlinux 53862306a36Sopenharmony_cilivepatch: '$MOD_LIVEPATCH2': starting patching transition 53962306a36Sopenharmony_cilivepatch: '$MOD_LIVEPATCH2': completing patching transition 54062306a36Sopenharmony_ci$MOD_LIVEPATCH2: post_patch_callback: vmlinux 54162306a36Sopenharmony_cilivepatch: '$MOD_LIVEPATCH2': patching complete 54262306a36Sopenharmony_ci% echo 0 > /sys/kernel/livepatch/$MOD_LIVEPATCH2/enabled 54362306a36Sopenharmony_cilivepatch: '$MOD_LIVEPATCH2': initializing unpatching transition 54462306a36Sopenharmony_ci$MOD_LIVEPATCH2: pre_unpatch_callback: vmlinux 54562306a36Sopenharmony_cilivepatch: '$MOD_LIVEPATCH2': starting unpatching transition 54662306a36Sopenharmony_cilivepatch: '$MOD_LIVEPATCH2': completing unpatching transition 54762306a36Sopenharmony_ci$MOD_LIVEPATCH2: post_unpatch_callback: vmlinux 54862306a36Sopenharmony_cilivepatch: '$MOD_LIVEPATCH2': unpatching complete 54962306a36Sopenharmony_ci% rmmod $MOD_LIVEPATCH2 55062306a36Sopenharmony_ci% rmmod $MOD_LIVEPATCH" 55162306a36Sopenharmony_ci 55262306a36Sopenharmony_ci 55362306a36Sopenharmony_ciexit 0 554