From 4aa909eb8fb499097a9fa90b75bc04e9b71f64e5 Mon Sep 17 00:00:00 2001 From: Julien Thierry Date: Tue, 8 Oct 2019 08:43:06 +0100 Subject: [PATCH 1/6] test/integration: Skip disabled tests in multiple.test Tests intentionaly disabled should be skipped by multiple.test Signed-off-by: Julien Thierry --- test/integration/common/multiple.template | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/test/integration/common/multiple.template b/test/integration/common/multiple.template index 003f9d9..678279c 100755 --- a/test/integration/common/multiple.template +++ b/test/integration/common/multiple.template @@ -5,6 +5,8 @@ KPATCH="sudo $ROOTDIR/kpatch/kpatch" MODULE_PREFIX="test-" MODULE_POSTFIX=".ko" TEST_POSTFIX="-LOADED.test" +PATCH_POSTFIX=".patch" +DISABLED_POSTFIX="${PATCH_POSTFIX}.disabled" set -o errexit @@ -44,6 +46,10 @@ for file in "${SCRIPTDIR}"/*"${TEST_POSTFIX}"; do break fi done + if ! [ -e ${file/${TEST_POSTFIX}/${PATCH_POSTFIX}} ] && \ + [ -e ${file/${TEST_POSTFIX}/${DISABLED_POSTFIX}} ]; then + skip=1 + fi if [ ${skip} -eq 0 ]; then modules+=(${MODULE_PREFIX}${name%${TEST_POSTFIX}}${MODULE_POSTFIX}) fi From 0f648b8056094d3a49b6f549d7e002f85c6ae341 Mon Sep 17 00:00:00 2001 From: Julien Thierry Date: Thu, 31 Oct 2019 11:08:20 +0000 Subject: [PATCH 2/6] test/integration: Skip disabled tests for combined test Disabled patches won't trigger a build, but the combined load test will still attempt to run their associated LOADED.test script. The combined test will fail due to voluntarily disabled tests. Do not run tests scripts associated with disabled tests. Signed-off-by: Julien Thierry --- test/integration/kpatch-test | 1 + 1 file changed, 1 insertion(+) diff --git a/test/integration/kpatch-test b/test/integration/kpatch-test index 16019da..a781eee 100755 --- a/test/integration/kpatch-test +++ b/test/integration/kpatch-test @@ -260,6 +260,7 @@ run_combined_test() { for testprog in "${TEST_LIST[@]}"; do [[ $testprog != *-LOADED.test ]] && continue + [ -e ${testprog/"-LOADED.test"/".patch.disabled"} ] && continue if ! $testprog >> $LOG 2>&1; then error "combined: $testprog failed after kpatch load" fi From f42a4127f575d8489a23be432d9cc838870eb7f2 Mon Sep 17 00:00:00 2001 From: Kamalesh Babulal Date: Fri, 12 Jul 2019 18:24:48 +0530 Subject: [PATCH 3/6] test/integration: Rebase to RHEL 8.0 Rebase the integration test cases on top of RHEL 8.0 kernel version 4.18.0-80.el8. Suggested-by: Joe Lawrence Signed-off-by: Kamalesh Babulal [JT: adapt data-new-LOADED to new meminfo format, use common template for multiple.test] Signed-off-by: Julien Thierry --- test/integration/rhel-8.0/README | 1 + .../rhel-8.0/bug-table-section.patch | 13 ++ .../rhel-8.0/cmdline-string-LOADED.test | 3 + .../integration/rhel-8.0/cmdline-string.patch | 14 ++ .../integration/rhel-8.0/data-new-LOADED.test | 3 + test/integration/rhel-8.0/data-new.patch | 21 +++ .../rhel-8.0/data-read-mostly.patch | 12 ++ test/integration/rhel-8.0/fixup-section.patch | 12 ++ .../rhel-8.0/gcc-constprop.patch.disabled | 14 ++ test/integration/rhel-8.0/gcc-isra.patch | 12 ++ test/integration/rhel-8.0/gcc-mangled-3.patch | 14 ++ .../rhel-8.0/gcc-static-local-var-2.patch | 14 ++ .../rhel-8.0/gcc-static-local-var-3.patch | 20 +++ .../rhel-8.0/gcc-static-local-var-4.patch | 23 +++ .../rhel-8.0/gcc-static-local-var-4.test | 7 + .../rhel-8.0/gcc-static-local-var-5.patch | 46 +++++ .../rhel-8.0/gcc-static-local-var-6.patch | 23 +++ .../rhel-8.0/macro-callbacks.patch | 158 ++++++++++++++++++ test/integration/rhel-8.0/macro-printk.patch | 151 +++++++++++++++++ .../rhel-8.0/meminfo-init-FAIL.patch | 12 ++ .../rhel-8.0/meminfo-init2-FAIL.patch | 20 +++ .../rhel-8.0/meminfo-string-LOADED.test | 3 + .../integration/rhel-8.0/meminfo-string.patch | 13 ++ .../rhel-8.0/module-call-external.patch | 35 ++++ test/integration/rhel-8.0/multiple.test | 7 + test/integration/rhel-8.0/new-function.patch | 26 +++ test/integration/rhel-8.0/new-globals.patch | 36 ++++ .../rhel-8.0/parainstructions-section.patch | 12 ++ .../rhel-8.0/shadow-newpid-LOADED.test | 3 + test/integration/rhel-8.0/shadow-newpid.patch | 78 +++++++++ .../rhel-8.0/smp-locks-section.patch | 14 ++ .../integration/rhel-8.0/special-static.patch | 23 +++ .../rhel-8.0/tracepoints-section.patch | 14 ++ .../rhel-8.0/warn-detect-FAIL.patch | 9 + 34 files changed, 866 insertions(+) create mode 100644 test/integration/rhel-8.0/README create mode 100644 test/integration/rhel-8.0/bug-table-section.patch create mode 100755 test/integration/rhel-8.0/cmdline-string-LOADED.test create mode 100644 test/integration/rhel-8.0/cmdline-string.patch create mode 100755 test/integration/rhel-8.0/data-new-LOADED.test create mode 100644 test/integration/rhel-8.0/data-new.patch create mode 100644 test/integration/rhel-8.0/data-read-mostly.patch create mode 100644 test/integration/rhel-8.0/fixup-section.patch create mode 100644 test/integration/rhel-8.0/gcc-constprop.patch.disabled create mode 100644 test/integration/rhel-8.0/gcc-isra.patch create mode 100644 test/integration/rhel-8.0/gcc-mangled-3.patch create mode 100644 test/integration/rhel-8.0/gcc-static-local-var-2.patch create mode 100644 test/integration/rhel-8.0/gcc-static-local-var-3.patch create mode 100644 test/integration/rhel-8.0/gcc-static-local-var-4.patch create mode 100755 test/integration/rhel-8.0/gcc-static-local-var-4.test create mode 100644 test/integration/rhel-8.0/gcc-static-local-var-5.patch create mode 100644 test/integration/rhel-8.0/gcc-static-local-var-6.patch create mode 100644 test/integration/rhel-8.0/macro-callbacks.patch create mode 100644 test/integration/rhel-8.0/macro-printk.patch create mode 100644 test/integration/rhel-8.0/meminfo-init-FAIL.patch create mode 100644 test/integration/rhel-8.0/meminfo-init2-FAIL.patch create mode 100755 test/integration/rhel-8.0/meminfo-string-LOADED.test create mode 100644 test/integration/rhel-8.0/meminfo-string.patch create mode 100644 test/integration/rhel-8.0/module-call-external.patch create mode 100755 test/integration/rhel-8.0/multiple.test create mode 100644 test/integration/rhel-8.0/new-function.patch create mode 100644 test/integration/rhel-8.0/new-globals.patch create mode 100644 test/integration/rhel-8.0/parainstructions-section.patch create mode 100755 test/integration/rhel-8.0/shadow-newpid-LOADED.test create mode 100644 test/integration/rhel-8.0/shadow-newpid.patch create mode 100644 test/integration/rhel-8.0/smp-locks-section.patch create mode 100644 test/integration/rhel-8.0/special-static.patch create mode 100644 test/integration/rhel-8.0/tracepoints-section.patch create mode 100644 test/integration/rhel-8.0/warn-detect-FAIL.patch diff --git a/test/integration/rhel-8.0/README b/test/integration/rhel-8.0/README new file mode 100644 index 0000000..d46fbcb --- /dev/null +++ b/test/integration/rhel-8.0/README @@ -0,0 +1 @@ +4.18.0-80.el8 diff --git a/test/integration/rhel-8.0/bug-table-section.patch b/test/integration/rhel-8.0/bug-table-section.patch new file mode 100644 index 0000000..842ae4a --- /dev/null +++ b/test/integration/rhel-8.0/bug-table-section.patch @@ -0,0 +1,13 @@ +diff --git a/fs/proc/proc_sysctl.c b/fs/proc/proc_sysctl.c +index 89921a0..ac129b6 100644 +--- a/fs/proc/proc_sysctl.c ++++ b/fs/proc/proc_sysctl.c +@@ -333,6 +333,8 @@ static void start_unregistering(struct ctl_table_header *p) + + static struct ctl_table_header *sysctl_head_grab(struct ctl_table_header *head) + { ++ if (jiffies == 0) ++ printk("kpatch-test: testing __bug_table section changes\n"); + BUG_ON(!head); + spin_lock(&sysctl_lock); + if (!use_table(head)) diff --git a/test/integration/rhel-8.0/cmdline-string-LOADED.test b/test/integration/rhel-8.0/cmdline-string-LOADED.test new file mode 100755 index 0000000..a8e0a08 --- /dev/null +++ b/test/integration/rhel-8.0/cmdline-string-LOADED.test @@ -0,0 +1,3 @@ +#!/bin/bash + +grep kpatch=1 /proc/cmdline diff --git a/test/integration/rhel-8.0/cmdline-string.patch b/test/integration/rhel-8.0/cmdline-string.patch new file mode 100644 index 0000000..665c763 --- /dev/null +++ b/test/integration/rhel-8.0/cmdline-string.patch @@ -0,0 +1,14 @@ +diff --git a/fs/proc/cmdline.c b/fs/proc/cmdline.c +index fa762c5..bd66027 100644 +--- a/fs/proc/cmdline.c ++++ b/fs/proc/cmdline.c +@@ -6,8 +6,7 @@ + + static int cmdline_proc_show(struct seq_file *m, void *v) + { +- seq_puts(m, saved_command_line); +- seq_putc(m, '\n'); ++ seq_printf(m, "%s kpatch=1\n", saved_command_line); + return 0; + } + diff --git a/test/integration/rhel-8.0/data-new-LOADED.test b/test/integration/rhel-8.0/data-new-LOADED.test new file mode 100755 index 0000000..9f25744 --- /dev/null +++ b/test/integration/rhel-8.0/data-new-LOADED.test @@ -0,0 +1,3 @@ +#!/bin/bash + +grep "kpatch: 5" /proc/meminfo diff --git a/test/integration/rhel-8.0/data-new.patch b/test/integration/rhel-8.0/data-new.patch new file mode 100644 index 0000000..78d1b97 --- /dev/null +++ b/test/integration/rhel-8.0/data-new.patch @@ -0,0 +1,21 @@ +diff --git a/fs/proc/meminfo.c b/fs/proc/meminfo.c +index 2fb0484..79ead86 100644 +--- a/fs/proc/meminfo.c ++++ b/fs/proc/meminfo.c +@@ -30,6 +30,8 @@ static void show_val_kb(struct seq_file *m, const char *s, unsigned long num) + seq_write(m, " kB\n", 4); + } + ++static int foo = 5; ++ + static int meminfo_proc_show(struct seq_file *m, void *v) + { + struct sysinfo i; +@@ -141,6 +143,7 @@ static int meminfo_proc_show(struct seq_file *m, void *v) + show_val_kb(m, "CmaFree: ", + global_zone_page_state(NR_FREE_CMA_PAGES)); + #endif ++ seq_printf(m, "kpatch: %d\n", foo); + + hugetlb_report_meminfo(m); + diff --git a/test/integration/rhel-8.0/data-read-mostly.patch b/test/integration/rhel-8.0/data-read-mostly.patch new file mode 100644 index 0000000..af69900 --- /dev/null +++ b/test/integration/rhel-8.0/data-read-mostly.patch @@ -0,0 +1,12 @@ +diff --git a/net/core/dev.c b/net/core/dev.c +index b6f9647..b376a48 100644 +--- a/net/core/dev.c ++++ b/net/core/dev.c +@@ -4858,6 +4858,7 @@ static int __netif_receive_skb_core(struct sk_buff *skb, bool pfmemalloc) + case RX_HANDLER_PASS: + break; + default: ++ printk("BUG!\n"); + BUG(); + } + } diff --git a/test/integration/rhel-8.0/fixup-section.patch b/test/integration/rhel-8.0/fixup-section.patch new file mode 100644 index 0000000..78ab6dd --- /dev/null +++ b/test/integration/rhel-8.0/fixup-section.patch @@ -0,0 +1,12 @@ +diff --git a/fs/readdir.c b/fs/readdir.c +index d97f548..58863b6 100644 +--- a/fs/readdir.c ++++ b/fs/readdir.c +@@ -189,6 +189,7 @@ static int filldir(struct dir_context *ctx, const char *name, int namlen, + goto efault; + } + dirent = buf->current_dir; ++ asm("nop"); + if (__put_user(d_ino, &dirent->d_ino)) + goto efault; + if (__put_user(reclen, &dirent->d_reclen)) diff --git a/test/integration/rhel-8.0/gcc-constprop.patch.disabled b/test/integration/rhel-8.0/gcc-constprop.patch.disabled new file mode 100644 index 0000000..3fbc577 --- /dev/null +++ b/test/integration/rhel-8.0/gcc-constprop.patch.disabled @@ -0,0 +1,14 @@ +diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c +index 4786df9..c73a687 100644 +--- a/kernel/time/timekeeping.c ++++ b/kernel/time/timekeeping.c +@@ -1211,6 +1211,9 @@ void do_gettimeofday(struct timeval *tv) + { + struct timespec64 now; + ++ if (!tv) ++ return; ++ + getnstimeofday64(&now); + tv->tv_sec = now.tv_sec; + tv->tv_usec = now.tv_nsec/1000; diff --git a/test/integration/rhel-8.0/gcc-isra.patch b/test/integration/rhel-8.0/gcc-isra.patch new file mode 100644 index 0000000..0903f24 --- /dev/null +++ b/test/integration/rhel-8.0/gcc-isra.patch @@ -0,0 +1,12 @@ +diff --git a/fs/proc/proc_sysctl.c b/fs/proc/proc_sysctl.c +index 89921a0..199b1d7 100644 +--- a/fs/proc/proc_sysctl.c ++++ b/fs/proc/proc_sysctl.c +@@ -48,6 +48,7 @@ void proc_sys_poll_notify(struct ctl_table_poll *poll) + if (!poll) + return; + ++ printk("kpatch-test: testing gcc .isra function name mangling\n"); + atomic_inc(&poll->event); + wake_up_interruptible(&poll->wait); + } diff --git a/test/integration/rhel-8.0/gcc-mangled-3.patch b/test/integration/rhel-8.0/gcc-mangled-3.patch new file mode 100644 index 0000000..bcb5e62 --- /dev/null +++ b/test/integration/rhel-8.0/gcc-mangled-3.patch @@ -0,0 +1,14 @@ +diff --git a/mm/slub.c b/mm/slub.c +index 51258ef..3cb5264 100644 +--- a/mm/slub.c ++++ b/mm/slub.c +@@ -5852,6 +5852,9 @@ void get_slabinfo(struct kmem_cache *s, struct slabinfo *sinfo) + int node; + struct kmem_cache_node *n; + ++ if (!jiffies) ++ printk("slabinfo\n"); ++ + for_each_kmem_cache_node(s, node, n) { + nr_slabs += node_nr_slabs(n); + nr_objs += node_nr_objs(n); diff --git a/test/integration/rhel-8.0/gcc-static-local-var-2.patch b/test/integration/rhel-8.0/gcc-static-local-var-2.patch new file mode 100644 index 0000000..a884bfa --- /dev/null +++ b/test/integration/rhel-8.0/gcc-static-local-var-2.patch @@ -0,0 +1,14 @@ +diff --git a/mm/mmap.c b/mm/mmap.c +index bf46096..4bc085c 100644 +--- a/mm/mmap.c ++++ b/mm/mmap.c +@@ -1684,6 +1684,9 @@ unsigned long mmap_region(struct file *file, unsigned long addr, + struct rb_node **rb_link, *rb_parent; + unsigned long charged = 0; + ++ if (!jiffies) ++ printk("kpatch mmap foo\n"); ++ + /* Check against address space limit. */ + if (!may_expand_vm(mm, vm_flags, len >> PAGE_SHIFT)) { + unsigned long nr_pages; diff --git a/test/integration/rhel-8.0/gcc-static-local-var-3.patch b/test/integration/rhel-8.0/gcc-static-local-var-3.patch new file mode 100644 index 0000000..da2acc0 --- /dev/null +++ b/test/integration/rhel-8.0/gcc-static-local-var-3.patch @@ -0,0 +1,20 @@ +diff --git a/kernel/reboot.c b/kernel/reboot.c +index e4ced88..0c0b5a2 100644 +--- a/kernel/reboot.c ++++ b/kernel/reboot.c +@@ -393,8 +393,15 @@ void kernel_power_off(void) + return ret; + } + ++void kpatch_bar(void) ++{ ++ if (!jiffies) ++ printk("kpatch_foo\n"); ++} ++ + static void deferred_cad(struct work_struct *dummy) + { ++ kpatch_bar(); + kernel_restart(NULL); + } + diff --git a/test/integration/rhel-8.0/gcc-static-local-var-4.patch b/test/integration/rhel-8.0/gcc-static-local-var-4.patch new file mode 100644 index 0000000..b52d6e4 --- /dev/null +++ b/test/integration/rhel-8.0/gcc-static-local-var-4.patch @@ -0,0 +1,23 @@ +diff --git a/fs/aio.c b/fs/aio.c +index e1f8f01..4dfb05c 100644 +--- a/fs/aio.c ++++ b/fs/aio.c +@@ -263,11 +263,18 @@ static int __init aio_setup(void) + } + __initcall(aio_setup); + ++void kpatch_aio_foo(void) ++{ ++ if (!jiffies) ++ printk("kpatch aio foo\n"); ++} ++ + static void put_aio_ring_file(struct kioctx *ctx) + { + struct file *aio_ring_file = ctx->aio_ring_file; + struct address_space *i_mapping; + ++ kpatch_aio_foo(); + if (aio_ring_file) { + truncate_setsize(file_inode(aio_ring_file), 0); + diff --git a/test/integration/rhel-8.0/gcc-static-local-var-4.test b/test/integration/rhel-8.0/gcc-static-local-var-4.test new file mode 100755 index 0000000..5c6f030 --- /dev/null +++ b/test/integration/rhel-8.0/gcc-static-local-var-4.test @@ -0,0 +1,7 @@ +#!/bin/bash + +if $(nm test-gcc-static-local-var-4.ko | grep -q free_ioctx); then + exit 1 +else + exit 0 +fi diff --git a/test/integration/rhel-8.0/gcc-static-local-var-5.patch b/test/integration/rhel-8.0/gcc-static-local-var-5.patch new file mode 100644 index 0000000..0e3e2d3 --- /dev/null +++ b/test/integration/rhel-8.0/gcc-static-local-var-5.patch @@ -0,0 +1,46 @@ +diff --git a/kernel/audit.c b/kernel/audit.c +index e7478cb..ed2546a 100644 +--- a/kernel/audit.c ++++ b/kernel/audit.c +@@ -325,6 +325,12 @@ void audit_panic(const char *message) + } + } + ++void kpatch_audit_foo(void) ++{ ++ if (!jiffies) ++ printk("kpatch audit foo\n"); ++} ++ + static inline int audit_rate_check(void) + { + static unsigned long last_check = 0; +@@ -335,6 +341,7 @@ static inline int audit_rate_check(void) + unsigned long elapsed; + int retval = 0; + ++ kpatch_audit_foo(); + if (!audit_rate_limit) return 1; + + spin_lock_irqsave(&lock, flags); +@@ -354,6 +361,11 @@ static inline int audit_rate_check(void) + return retval; + } + ++noinline void kpatch_audit_check(void) ++{ ++ audit_rate_check(); ++} ++ + /** + * audit_log_lost - conditionally log lost audit message event + * @message: the message stating reason for lost audit message +@@ -400,6 +412,8 @@ static int audit_log_config_change(char *function_name, u32 new, u32 old, + struct audit_buffer *ab; + int rc = 0; + ++ kpatch_audit_check(); ++ + ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE); + if (unlikely(!ab)) + return rc; diff --git a/test/integration/rhel-8.0/gcc-static-local-var-6.patch b/test/integration/rhel-8.0/gcc-static-local-var-6.patch new file mode 100644 index 0000000..91c72b6 --- /dev/null +++ b/test/integration/rhel-8.0/gcc-static-local-var-6.patch @@ -0,0 +1,23 @@ +diff --git a/net/ipv6/netfilter.c b/net/ipv6/netfilter.c +index 531d695..a536c74 100644 +--- a/net/ipv6/netfilter.c ++++ b/net/ipv6/netfilter.c +@@ -84,6 +84,8 @@ static int nf_ip6_reroute(struct sk_buff *skb, + return 0; + } + ++#include "kpatch-macros.h" ++ + static int nf_ip6_route(struct net *net, struct dst_entry **dst, + struct flowi *fl, bool strict) + { +@@ -97,6 +99,9 @@ static int nf_ip6_route(struct net *net, struct dst_entry **dst, + struct dst_entry *result; + int err; + ++ if (!jiffies) ++ printk("kpatch nf_ip6_route foo\n"); ++ + result = ip6_route_output(net, sk, &fl->u.ip6); + err = result->error; + if (err) diff --git a/test/integration/rhel-8.0/macro-callbacks.patch b/test/integration/rhel-8.0/macro-callbacks.patch new file mode 100644 index 0000000..b7f0077 --- /dev/null +++ b/test/integration/rhel-8.0/macro-callbacks.patch @@ -0,0 +1,158 @@ +diff --git a/drivers/input/joydev.c b/drivers/input/joydev.c +index 4c1e427..7e46aaf 100644 +--- a/drivers/input/joydev.c ++++ b/drivers/input/joydev.c +@@ -1068,3 +1068,47 @@ static void __exit joydev_exit(void) + + module_init(joydev_init); + module_exit(joydev_exit); ++ ++#include ++#include "kpatch-macros.h" ++ ++static const char *const module_state[] = { ++ [MODULE_STATE_LIVE] = "[MODULE_STATE_LIVE] Normal state", ++ [MODULE_STATE_COMING] = "[MODULE_STATE_COMING] Full formed, running module_init", ++ [MODULE_STATE_GOING] = "[MODULE_STATE_GOING] Going away", ++ [MODULE_STATE_UNFORMED] = "[MODULE_STATE_UNFORMED] Still setting it up", ++}; ++ ++static void callback_info(const char *callback, patch_object *obj) ++{ ++ if (obj->mod) ++ pr_info("%s: %s -> %s\n", callback, obj->mod->name, ++ module_state[obj->mod->state]); ++ else ++ pr_info("%s: vmlinux\n", callback); ++} ++ ++static int pre_patch_callback(patch_object *obj) ++{ ++ callback_info(__func__, obj); ++ return 0; /* return -ENODEV; */ ++} ++KPATCH_PRE_PATCH_CALLBACK(pre_patch_callback); ++ ++static void post_patch_callback(patch_object *obj) ++{ ++ callback_info(__func__, obj); ++} ++KPATCH_POST_PATCH_CALLBACK(post_patch_callback); ++ ++static void pre_unpatch_callback(patch_object *obj) ++{ ++ callback_info(__func__, obj); ++} ++KPATCH_PRE_UNPATCH_CALLBACK(pre_unpatch_callback); ++ ++static void post_unpatch_callback(patch_object *obj) ++{ ++ callback_info(__func__, obj); ++} ++KPATCH_POST_UNPATCH_CALLBACK(post_unpatch_callback); +diff --git a/drivers/input/misc/pcspkr.c b/drivers/input/misc/pcspkr.c +index 56ddba2..d188b12 100644 +--- a/drivers/input/misc/pcspkr.c ++++ b/drivers/input/misc/pcspkr.c +@@ -138,3 +138,46 @@ static void pcspkr_shutdown(struct platform_device *dev) + }; + module_platform_driver(pcspkr_platform_driver); + ++#include ++#include "kpatch-macros.h" ++ ++static const char *const module_state[] = { ++ [MODULE_STATE_LIVE] = "[MODULE_STATE_LIVE] Normal state", ++ [MODULE_STATE_COMING] = "[MODULE_STATE_COMING] Full formed, running module_init", ++ [MODULE_STATE_GOING] = "[MODULE_STATE_GOING] Going away", ++ [MODULE_STATE_UNFORMED] = "[MODULE_STATE_UNFORMED] Still setting it up", ++}; ++ ++static void callback_info(const char *callback, patch_object *obj) ++{ ++ if (obj->mod) ++ pr_info("%s: %s -> %s\n", callback, obj->mod->name, ++ module_state[obj->mod->state]); ++ else ++ pr_info("%s: vmlinux\n", callback); ++} ++ ++static int pre_patch_callback(patch_object *obj) ++{ ++ callback_info(__func__, obj); ++ return 0; ++} ++KPATCH_PRE_PATCH_CALLBACK(pre_patch_callback); ++ ++static void post_patch_callback(patch_object *obj) ++{ ++ callback_info(__func__, obj); ++} ++KPATCH_POST_PATCH_CALLBACK(post_patch_callback); ++ ++static void pre_unpatch_callback(patch_object *obj) ++{ ++ callback_info(__func__, obj); ++} ++KPATCH_PRE_UNPATCH_CALLBACK(pre_unpatch_callback); ++ ++static void post_unpatch_callback(patch_object *obj) ++{ ++ callback_info(__func__, obj); ++} ++KPATCH_POST_UNPATCH_CALLBACK(post_unpatch_callback); +diff --git a/fs/aio.c b/fs/aio.c +index e1f8f01..5efe496 100644 +--- a/fs/aio.c ++++ b/fs/aio.c +@@ -49,6 +49,50 @@ + + #define KIOCB_KEY 0 + ++#include ++#include "kpatch-macros.h" ++ ++static const char *const module_state[] = { ++ [MODULE_STATE_LIVE] = "[MODULE_STATE_LIVE] Normal state", ++ [MODULE_STATE_COMING] = "[MODULE_STATE_COMING] Full formed, running module_init", ++ [MODULE_STATE_GOING] = "[MODULE_STATE_GOING] Going away", ++ [MODULE_STATE_UNFORMED] = "[MODULE_STATE_UNFORMED] Still setting it up", ++}; ++ ++static void callback_info(const char *callback, patch_object *obj) ++{ ++ if (obj->mod) ++ pr_info("%s: %s -> %s\n", callback, obj->mod->name, ++ module_state[obj->mod->state]); ++ else ++ pr_info("%s: vmlinux\n", callback); ++} ++ ++static int pre_patch_callback(patch_object *obj) ++{ ++ callback_info(__func__, obj); ++ return 0; ++} ++KPATCH_PRE_PATCH_CALLBACK(pre_patch_callback); ++ ++static void post_patch_callback(patch_object *obj) ++{ ++ callback_info(__func__, obj); ++} ++KPATCH_POST_PATCH_CALLBACK(post_patch_callback); ++ ++static void pre_unpatch_callback(patch_object *obj) ++{ ++ callback_info(__func__, obj); ++} ++KPATCH_PRE_UNPATCH_CALLBACK(pre_unpatch_callback); ++ ++static void post_unpatch_callback(patch_object *obj) ++{ ++ callback_info(__func__, obj); ++} ++KPATCH_POST_UNPATCH_CALLBACK(post_unpatch_callback); ++ + #define AIO_RING_MAGIC 0xa10a10a1 + #define AIO_RING_COMPAT_FEATURES 1 + #define AIO_RING_INCOMPAT_FEATURES 0 diff --git a/test/integration/rhel-8.0/macro-printk.patch b/test/integration/rhel-8.0/macro-printk.patch new file mode 100644 index 0000000..dfe0586 --- /dev/null +++ b/test/integration/rhel-8.0/macro-printk.patch @@ -0,0 +1,151 @@ +diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c +index 0113993..0ea4967 100644 +--- a/net/ipv4/fib_frontend.c ++++ b/net/ipv4/fib_frontend.c +@@ -767,6 +767,7 @@ static int inet_rtm_delroute(struct sk_buff *skb, struct nlmsghdr *nlh, + return err; + } + ++#include "kpatch-macros.h" + static int inet_rtm_newroute(struct sk_buff *skb, struct nlmsghdr *nlh, + struct netlink_ext_ack *extack) + { +@@ -788,6 +789,7 @@ static int inet_rtm_newroute(struct sk_buff *skb, struct nlmsghdr *nlh, + err = fib_table_insert(net, tb, &cfg, extack); + if (!err && cfg.fc_type == RTN_LOCAL) + net->ipv4.fib_has_custom_local_routes = true; ++ KPATCH_PRINTK("[inet_rtm_newroute]: err is %d\n", err); + errout: + return err; + } +diff --git a/net/ipv4/fib_semantics.c b/net/ipv4/fib_semantics.c +index 446204c..5b73a01 100644 +--- a/net/ipv4/fib_semantics.c ++++ b/net/ipv4/fib_semantics.c +@@ -1025,6 +1025,7 @@ static bool fib_valid_prefsrc(struct fib_config *cfg, __be32 fib_prefsrc) + fi->fib_metrics->metrics); + } + ++#include "kpatch-macros.h" + struct fib_info *fib_create_info(struct fib_config *cfg, + struct netlink_ext_ack *extack) + { +@@ -1058,6 +1059,7 @@ struct fib_info *fib_create_info(struct fib_config *cfg, + #endif + + err = -ENOBUFS; ++ KPATCH_PRINTK("[fib_create_info]: create error err is %d\n",err); + if (fib_info_cnt >= fib_info_hash_size) { + unsigned int new_size = fib_info_hash_size << 1; + struct hlist_head *new_info_hash; +@@ -1078,6 +1080,7 @@ struct fib_info *fib_create_info(struct fib_config *cfg, + if (!fib_info_hash_size) + goto failure; + } ++ KPATCH_PRINTK("[fib_create_info]: 2 create error err is %d\n",err); + + fi = kzalloc(sizeof(*fi)+nhs*sizeof(struct fib_nh), GFP_KERNEL); + if (!fi) +@@ -1093,6 +1096,8 @@ struct fib_info *fib_create_info(struct fib_config *cfg, + fi->fib_metrics = (struct dst_metrics *)&dst_default_metrics; + } + fib_info_cnt++; ++ KPATCH_PRINTK("[fib_create_info]: 3 create error err is %d\n",err); ++ + fi->fib_net = net; + fi->fib_protocol = cfg->fc_protocol; + fi->fib_scope = cfg->fc_scope; +@@ -1109,8 +1114,10 @@ struct fib_info *fib_create_info(struct fib_config *cfg, + if (!nexthop_nh->nh_pcpu_rth_output) + goto failure; + } endfor_nexthops(fi) ++ KPATCH_PRINTK("[fib_create_info]: 4 create error err is %d\n",err); + + err = fib_convert_metrics(fi, cfg); ++ KPATCH_PRINTK("[fib_create_info]: 5 create error err is %d\n",err); + if (err) + goto failure; + +@@ -1172,6 +1179,7 @@ struct fib_info *fib_create_info(struct fib_config *cfg, + nh->nh_weight = 1; + #endif + } ++ KPATCH_PRINTK("[fib_create_info]: 6 create error err is %d\n",err); + + if (fib_props[cfg->fc_type].error) { + if (cfg->fc_gw || cfg->fc_oif || cfg->fc_mp) { +@@ -1193,6 +1201,7 @@ struct fib_info *fib_create_info(struct fib_config *cfg, + goto err_inval; + } + } ++ KPATCH_PRINTK("[fib_create_info]: 7 create error err is %d\n",err); + + if (cfg->fc_scope > RT_SCOPE_HOST) { + NL_SET_ERR_MSG(extack, "Invalid scope"); +@@ -1231,6 +1240,7 @@ struct fib_info *fib_create_info(struct fib_config *cfg, + if (linkdown == fi->fib_nhs) + fi->fib_flags |= RTNH_F_LINKDOWN; + } ++ KPATCH_PRINTK("[fib_create_info]: 8 create error err is %d\n",err); + + if (fi->fib_prefsrc && !fib_valid_prefsrc(cfg, fi->fib_prefsrc)) { + NL_SET_ERR_MSG(extack, "Invalid prefsrc address"); +@@ -1240,6 +1250,7 @@ struct fib_info *fib_create_info(struct fib_config *cfg, + change_nexthops(fi) { + fib_info_update_nh_saddr(net, nexthop_nh); + } endfor_nexthops(fi) ++ KPATCH_PRINTK("[fib_create_info]: 9 create error err is %d\n",err); + + fib_rebalance(fi); + +@@ -1251,6 +1262,7 @@ struct fib_info *fib_create_info(struct fib_config *cfg, + ofi->fib_treeref++; + return ofi; + } ++ KPATCH_PRINTK("[fib_create_info]: 10 create error err is %d\n",err); + + fi->fib_treeref++; + refcount_set(&fi->fib_clntref, 1); +@@ -1274,6 +1286,7 @@ struct fib_info *fib_create_info(struct fib_config *cfg, + hlist_add_head(&nexthop_nh->nh_hash, head); + } endfor_nexthops(fi) + spin_unlock_bh(&fib_info_lock); ++ KPATCH_PRINTK("[fib_create_info]: 11 create error err is %d\n",err); + return fi; + + err_inval: +@@ -1284,6 +1297,7 @@ struct fib_info *fib_create_info(struct fib_config *cfg, + fi->fib_dead = 1; + free_fib_info(fi); + } ++ KPATCH_PRINTK("[fib_create_info]: 12 create error err is %d\n",err); + + return ERR_PTR(err); + } +diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c +index 5bc0c89..d57b327 100644 +--- a/net/ipv4/fib_trie.c ++++ b/net/ipv4/fib_trie.c +@@ -1121,6 +1121,7 @@ static bool fib_valid_key_len(u32 key, u8 plen, struct netlink_ext_ack *extack) + } + + /* Caller must hold RTNL. */ ++#include "kpatch-macros.h" + int fib_table_insert(struct net *net, struct fib_table *tb, + struct fib_config *cfg, struct netlink_ext_ack *extack) + { +@@ -1143,11 +1144,14 @@ int fib_table_insert(struct net *net, struct fib_table *tb, + + pr_debug("Insert table=%u %08x/%d\n", tb->tb_id, key, plen); + ++ KPATCH_PRINTK("[fib_table_insert]: start\n"); + fi = fib_create_info(cfg, extack); + if (IS_ERR(fi)) { + err = PTR_ERR(fi); ++ KPATCH_PRINTK("[fib_table_insert]: create error err is %d\n",err); + goto err; + } ++ KPATCH_PRINTK("[fib_table_insert]: cross\n"); + + l = fib_find_node(t, &tp, key); + fa = l ? fib_find_alias(&l->leaf, slen, tos, fi->fib_priority, diff --git a/test/integration/rhel-8.0/meminfo-init-FAIL.patch b/test/integration/rhel-8.0/meminfo-init-FAIL.patch new file mode 100644 index 0000000..a3361ed --- /dev/null +++ b/test/integration/rhel-8.0/meminfo-init-FAIL.patch @@ -0,0 +1,12 @@ +diff --git a/fs/proc/meminfo.c b/fs/proc/meminfo.c +index 2fb0484..b981fab 100644 +--- a/fs/proc/meminfo.c ++++ b/fs/proc/meminfo.c +@@ -151,6 +151,7 @@ static int meminfo_proc_show(struct seq_file *m, void *v) + + static int __init proc_meminfo_init(void) + { ++ printk("a\n"); + proc_create_single("meminfo", 0, NULL, meminfo_proc_show); + return 0; + } diff --git a/test/integration/rhel-8.0/meminfo-init2-FAIL.patch b/test/integration/rhel-8.0/meminfo-init2-FAIL.patch new file mode 100644 index 0000000..28f8445 --- /dev/null +++ b/test/integration/rhel-8.0/meminfo-init2-FAIL.patch @@ -0,0 +1,20 @@ +diff --git a/fs/proc/meminfo.c b/fs/proc/meminfo.c +index 2fb0484..eb61884 100644 +--- a/fs/proc/meminfo.c ++++ b/fs/proc/meminfo.c +@@ -39,6 +39,7 @@ static int meminfo_proc_show(struct seq_file *m, void *v) + unsigned long pages[NR_LRU_LISTS]; + int lru; + ++ printk("a\n"); + si_meminfo(&i); + si_swapinfo(&i); + committed = percpu_counter_read_positive(&vm_committed_as); +@@ -151,6 +152,7 @@ static int meminfo_proc_show(struct seq_file *m, void *v) + + static int __init proc_meminfo_init(void) + { ++ printk("a\n"); + proc_create_single("meminfo", 0, NULL, meminfo_proc_show); + return 0; + } diff --git a/test/integration/rhel-8.0/meminfo-string-LOADED.test b/test/integration/rhel-8.0/meminfo-string-LOADED.test new file mode 100755 index 0000000..10dc20b --- /dev/null +++ b/test/integration/rhel-8.0/meminfo-string-LOADED.test @@ -0,0 +1,3 @@ +#!/bin/bash + +grep VMALLOCCHUNK /proc/meminfo diff --git a/test/integration/rhel-8.0/meminfo-string.patch b/test/integration/rhel-8.0/meminfo-string.patch new file mode 100644 index 0000000..e20210f --- /dev/null +++ b/test/integration/rhel-8.0/meminfo-string.patch @@ -0,0 +1,13 @@ +diff --git a/fs/proc/meminfo.c b/fs/proc/meminfo.c +index 2fb0484..804bc35 100644 +--- a/fs/proc/meminfo.c ++++ b/fs/proc/meminfo.c +@@ -120,7 +120,7 @@ static int meminfo_proc_show(struct seq_file *m, void *v) + seq_printf(m, "VmallocTotal: %8lu kB\n", + (unsigned long)VMALLOC_TOTAL >> 10); + show_val_kb(m, "VmallocUsed: ", 0ul); +- show_val_kb(m, "VmallocChunk: ", 0ul); ++ show_val_kb(m, "VMALLOCCHUNK: ", 0ul); + + #ifdef CONFIG_MEMORY_FAILURE + seq_printf(m, "HardwareCorrupted: %5lu kB\n", diff --git a/test/integration/rhel-8.0/module-call-external.patch b/test/integration/rhel-8.0/module-call-external.patch new file mode 100644 index 0000000..44e546f --- /dev/null +++ b/test/integration/rhel-8.0/module-call-external.patch @@ -0,0 +1,35 @@ +diff --git a/fs/nfsd/export.c b/fs/nfsd/export.c +index a1143f7..950403a 100644 +--- a/fs/nfsd/export.c ++++ b/fs/nfsd/export.c +@@ -1196,6 +1196,8 @@ static void exp_flags(struct seq_file *m, int flag, int fsid, + } + } + ++extern char *kpatch_string(void); ++ + static int e_show(struct seq_file *m, void *p) + { + struct cache_head *cp = p; +@@ -1205,6 +1207,7 @@ static int e_show(struct seq_file *m, void *p) + if (p == SEQ_START_TOKEN) { + seq_puts(m, "# Version 1.1\n"); + seq_puts(m, "# Path Client(Flags) # IPs\n"); ++ seq_puts(m, kpatch_string()); + return 0; + } + +diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c +index 56704d9..851d41d 100644 +--- a/net/netlink/af_netlink.c ++++ b/net/netlink/af_netlink.c +@@ -2779,4 +2779,9 @@ static int __init netlink_proto_init(void) + panic("netlink_init: Cannot allocate nl_table\n"); + } + ++char *kpatch_string(void) ++{ ++ return "# kpatch\n"; ++} ++ + core_initcall(netlink_proto_init); diff --git a/test/integration/rhel-8.0/multiple.test b/test/integration/rhel-8.0/multiple.test new file mode 100755 index 0000000..7e4b352 --- /dev/null +++ b/test/integration/rhel-8.0/multiple.test @@ -0,0 +1,7 @@ +#!/bin/bash + +SCRIPTDIR="$(readlink -f $(dirname $(type -p $0)))" + +declare -a blacklist=(meminfo-string-LOADED.test) + +source ${SCRIPTDIR}/../common/multiple.template diff --git a/test/integration/rhel-8.0/new-function.patch b/test/integration/rhel-8.0/new-function.patch new file mode 100644 index 0000000..d935205 --- /dev/null +++ b/test/integration/rhel-8.0/new-function.patch @@ -0,0 +1,26 @@ +diff --git a/drivers/tty/n_tty.c b/drivers/tty/n_tty.c +index 3ad4602..f3cda7e 100644 +--- a/drivers/tty/n_tty.c ++++ b/drivers/tty/n_tty.c +@@ -2296,7 +2296,7 @@ static ssize_t n_tty_read(struct tty_struct *tty, struct file *file, + * lock themselves) + */ + +-static ssize_t n_tty_write(struct tty_struct *tty, struct file *file, ++static ssize_t noinline kpatch_n_tty_write(struct tty_struct *tty, struct file *file, + const unsigned char *buf, size_t nr) + { + const unsigned char *b = buf; +@@ -2383,6 +2383,12 @@ static ssize_t n_tty_write(struct tty_struct *tty, struct file *file, + return (b - buf) ? b - buf : retval; + } + ++static ssize_t n_tty_write(struct tty_struct *tty, struct file *file, ++ const unsigned char *buf, size_t nr) ++{ ++ return kpatch_n_tty_write(tty, file, buf, nr); ++} ++ + /** + * n_tty_poll - poll method for N_TTY + * @tty: terminal device diff --git a/test/integration/rhel-8.0/new-globals.patch b/test/integration/rhel-8.0/new-globals.patch new file mode 100644 index 0000000..38892a4 --- /dev/null +++ b/test/integration/rhel-8.0/new-globals.patch @@ -0,0 +1,36 @@ +diff --git a/fs/proc/cmdline.c b/fs/proc/cmdline.c +index fa762c5..cc67970 100644 +--- a/fs/proc/cmdline.c ++++ b/fs/proc/cmdline.c +@@ -17,3 +17,10 @@ static int __init proc_cmdline_init(void) + return 0; + } + fs_initcall(proc_cmdline_init); ++ ++#include ++void kpatch_print_message(void) ++{ ++ if (!jiffies) ++ printk("hello there!\n"); ++} +diff --git a/fs/proc/meminfo.c b/fs/proc/meminfo.c +index 2fb0484..7dd8350 100644 +--- a/fs/proc/meminfo.c ++++ b/fs/proc/meminfo.c +@@ -20,6 +20,8 @@ + #include + #include "internal.h" + ++void kpatch_print_message(void); ++ + void __attribute__((weak)) arch_report_meminfo(struct seq_file *m) + { + } +@@ -53,6 +55,7 @@ static int meminfo_proc_show(struct seq_file *m, void *v) + + available = si_mem_available(); + ++ kpatch_print_message(); + show_val_kb(m, "MemTotal: ", i.totalram); + show_val_kb(m, "MemFree: ", i.freeram); + show_val_kb(m, "MemAvailable: ", available); diff --git a/test/integration/rhel-8.0/parainstructions-section.patch b/test/integration/rhel-8.0/parainstructions-section.patch new file mode 100644 index 0000000..d3af7a6 --- /dev/null +++ b/test/integration/rhel-8.0/parainstructions-section.patch @@ -0,0 +1,12 @@ +diff --git a/fs/proc/generic.c b/fs/proc/generic.c +index bb1c162..2b3f7ec 100644 +--- a/fs/proc/generic.c ++++ b/fs/proc/generic.c +@@ -205,6 +205,7 @@ int proc_alloc_inum(unsigned int *inum) + { + int i; + ++ printk("kpatch-test: testing change to .parainstructions section\n"); + i = ida_simple_get(&proc_inum_ida, 0, UINT_MAX - PROC_DYNAMIC_FIRST + 1, + GFP_KERNEL); + if (i < 0) diff --git a/test/integration/rhel-8.0/shadow-newpid-LOADED.test b/test/integration/rhel-8.0/shadow-newpid-LOADED.test new file mode 100755 index 0000000..c07d112 --- /dev/null +++ b/test/integration/rhel-8.0/shadow-newpid-LOADED.test @@ -0,0 +1,3 @@ +#!/bin/bash + +grep -q newpid: /proc/$$/status diff --git a/test/integration/rhel-8.0/shadow-newpid.patch b/test/integration/rhel-8.0/shadow-newpid.patch new file mode 100644 index 0000000..dfe2e39 --- /dev/null +++ b/test/integration/rhel-8.0/shadow-newpid.patch @@ -0,0 +1,78 @@ +diff --git a/fs/proc/array.c b/fs/proc/array.c +index 0ceb3b6..1b44c7f 100644 +--- a/fs/proc/array.c ++++ b/fs/proc/array.c +@@ -370,12 +370,19 @@ static inline void task_seccomp(struct seq_file *m, struct task_struct *p) + seq_putc(m, '\n'); + } + ++#include + static inline void task_context_switch_counts(struct seq_file *m, + struct task_struct *p) + { ++ int *newpid; ++ + seq_put_decimal_ull(m, "voluntary_ctxt_switches:\t", p->nvcsw); + seq_put_decimal_ull(m, "\nnonvoluntary_ctxt_switches:\t", p->nivcsw); + seq_putc(m, '\n'); ++ ++ newpid = klp_shadow_get(p, 0); ++ if (newpid) ++ seq_printf(m, "newpid:\t%d\n", *newpid); + } + + static void task_cpus_allowed(struct seq_file *m, struct task_struct *task) +diff --git a/kernel/exit.c b/kernel/exit.c +index deaa53a..01f5776 100644 +--- a/kernel/exit.c ++++ b/kernel/exit.c +@@ -760,6 +760,7 @@ static void check_stack_usage(void) + static inline void check_stack_usage(void) {} + #endif + ++#include + void __noreturn do_exit(long code) + { + struct task_struct *tsk = current; +@@ -865,6 +866,8 @@ void __noreturn do_exit(long code) + exit_task_work(tsk); + exit_thread(tsk); + ++ klp_shadow_free(tsk, 0, NULL); ++ + /* + * Flush inherited counters to the parent - before the parent + * gets woken up by child-exit notifications. +diff --git a/kernel/fork.c b/kernel/fork.c +index 3311231..2c12c1a 100644 +--- a/kernel/fork.c ++++ b/kernel/fork.c +@@ -2093,6 +2093,7 @@ struct task_struct *fork_idle(int cpu) + * It copies the process, and if successful kick-starts + * it and waits for it to finish using the VM if required. + */ ++#include + long _do_fork(unsigned long clone_flags, + unsigned long stack_start, + unsigned long stack_size, +@@ -2105,6 +2106,8 @@ long _do_fork(unsigned long clone_flags, + struct task_struct *p; + int trace = 0; + long nr; ++ int *newpid; ++ static int ctr = 0; + + /* + * Determine whether and which event to report to ptracer. When +@@ -2131,6 +2134,11 @@ long _do_fork(unsigned long clone_flags, + if (IS_ERR(p)) + return PTR_ERR(p); + ++ newpid = klp_shadow_get_or_alloc(p, 0, sizeof(*newpid), GFP_KERNEL, ++ NULL, NULL); ++ if (newpid) ++ *newpid = ctr++; ++ + /* + * Do this prior waking up the new thread - the thread pointer + * might get invalid after that point, if the thread exits quickly. diff --git a/test/integration/rhel-8.0/smp-locks-section.patch b/test/integration/rhel-8.0/smp-locks-section.patch new file mode 100644 index 0000000..5166614 --- /dev/null +++ b/test/integration/rhel-8.0/smp-locks-section.patch @@ -0,0 +1,14 @@ +diff --git a/drivers/tty/tty_buffer.c b/drivers/tty/tty_buffer.c +index ae3ce33..37727fe 100644 +--- a/drivers/tty/tty_buffer.c ++++ b/drivers/tty/tty_buffer.c +@@ -256,6 +256,9 @@ static int __tty_buffer_request_room(struct tty_port *port, size_t size, + struct tty_buffer *b, *n; + int left, change; + ++ if (!size) ++ printk("kpatch-test: testing .smp_locks section changes\n"); ++ + b = buf->tail; + if (b->flags & TTYB_NORMAL) + left = 2 * b->size - b->used; diff --git a/test/integration/rhel-8.0/special-static.patch b/test/integration/rhel-8.0/special-static.patch new file mode 100644 index 0000000..22502df --- /dev/null +++ b/test/integration/rhel-8.0/special-static.patch @@ -0,0 +1,23 @@ +diff --git a/kernel/fork.c b/kernel/fork.c +index 3311231..f6e66b7 100644 +--- a/kernel/fork.c ++++ b/kernel/fork.c +@@ -1461,10 +1461,18 @@ static void posix_cpu_timers_init_group(struct signal_struct *sig) + static inline void posix_cpu_timers_init_group(struct signal_struct *sig) { } + #endif + ++void kpatch_foo(void) ++{ ++ if (!jiffies) ++ printk("kpatch copy signal\n"); ++} ++ + static int copy_signal(unsigned long clone_flags, struct task_struct *tsk) + { + struct signal_struct *sig; + ++ kpatch_foo(); ++ + if (clone_flags & CLONE_THREAD) + return 0; + diff --git a/test/integration/rhel-8.0/tracepoints-section.patch b/test/integration/rhel-8.0/tracepoints-section.patch new file mode 100644 index 0000000..0dfea0c --- /dev/null +++ b/test/integration/rhel-8.0/tracepoints-section.patch @@ -0,0 +1,14 @@ +diff --git a/kernel/time/timer.c b/kernel/time/timer.c +index 786f8c0..1105697 100644 +--- a/kernel/time/timer.c ++++ b/kernel/time/timer.c +@@ -1692,6 +1692,9 @@ static __latent_entropy void run_timer_softirq(struct softirq_action *h) + { + struct timer_base *base = this_cpu_ptr(&timer_bases[BASE_STD]); + ++ if (!base) ++ printk("kpatch-test: testing __tracepoints section changes\n"); ++ + __run_timers(base); + if (IS_ENABLED(CONFIG_NO_HZ_COMMON)) + __run_timers(this_cpu_ptr(&timer_bases[BASE_DEF])); diff --git a/test/integration/rhel-8.0/warn-detect-FAIL.patch b/test/integration/rhel-8.0/warn-detect-FAIL.patch new file mode 100644 index 0000000..f57bd0e --- /dev/null +++ b/test/integration/rhel-8.0/warn-detect-FAIL.patch @@ -0,0 +1,9 @@ +diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c +index 4fa858b..ef1a710 100644 +--- a/arch/x86/kvm/x86.c ++++ b/arch/x86/kvm/x86.c +@@ -1,3 +1,4 @@ ++ + /* + * Kernel-based Virtual Machine driver for Linux + * From 4710df3c78b316fecb739bd19d9e90f2811d9638 Mon Sep 17 00:00:00 2001 From: Julien Thierry Date: Mon, 16 Sep 2019 16:57:21 +0100 Subject: [PATCH 4/6] test/integration: Disable RHEL-8.0 tests using jump labels Jump labels are unsupported, so tests modifying functions using them are expected to fail. So disable them, for now... Signed-off-by: Julien Thierry --- .../{data-read-mostly.patch => data-read-mostly.patch.disabled} | 2 ++ .../{shadow-newpid.patch => shadow-newpid.patch.disabled} | 2 ++ 2 files changed, 4 insertions(+) rename test/integration/rhel-8.0/{data-read-mostly.patch => data-read-mostly.patch.disabled} (82%) rename test/integration/rhel-8.0/{shadow-newpid.patch => shadow-newpid.patch.disabled} (97%) diff --git a/test/integration/rhel-8.0/data-read-mostly.patch b/test/integration/rhel-8.0/data-read-mostly.patch.disabled similarity index 82% rename from test/integration/rhel-8.0/data-read-mostly.patch rename to test/integration/rhel-8.0/data-read-mostly.patch.disabled index af69900..ed4eef0 100644 --- a/test/integration/rhel-8.0/data-read-mostly.patch +++ b/test/integration/rhel-8.0/data-read-mostly.patch.disabled @@ -1,3 +1,5 @@ +Disabled due to https://github.com/dynup/kpatch/issues/940 +--- diff --git a/net/core/dev.c b/net/core/dev.c index b6f9647..b376a48 100644 --- a/net/core/dev.c diff --git a/test/integration/rhel-8.0/shadow-newpid.patch b/test/integration/rhel-8.0/shadow-newpid.patch.disabled similarity index 97% rename from test/integration/rhel-8.0/shadow-newpid.patch rename to test/integration/rhel-8.0/shadow-newpid.patch.disabled index dfe2e39..19109a3 100644 --- a/test/integration/rhel-8.0/shadow-newpid.patch +++ b/test/integration/rhel-8.0/shadow-newpid.patch.disabled @@ -1,3 +1,5 @@ +Disabled due to https://github.com/dynup/kpatch/issues/940 +--- diff --git a/fs/proc/array.c b/fs/proc/array.c index 0ceb3b6..1b44c7f 100644 --- a/fs/proc/array.c From 6943128cebef8dcf8e068b98455df57313d58c67 Mon Sep 17 00:00:00 2001 From: Julien Thierry Date: Tue, 8 Oct 2019 13:55:45 +0100 Subject: [PATCH 5/6] test/integration: Disable test affecting jump label on ppcle64 On ppcle64, test gcc-static-local-var-4 impacts a jump label reference which is currently unsupported. Signed-off-by: Julien Thierry --- ...-local-var-4.patch => gcc-static-local-var-4.patch.disabled} | 2 ++ 1 file changed, 2 insertions(+) rename test/integration/rhel-8.0/{gcc-static-local-var-4.patch => gcc-static-local-var-4.patch.disabled} (88%) diff --git a/test/integration/rhel-8.0/gcc-static-local-var-4.patch b/test/integration/rhel-8.0/gcc-static-local-var-4.patch.disabled similarity index 88% rename from test/integration/rhel-8.0/gcc-static-local-var-4.patch rename to test/integration/rhel-8.0/gcc-static-local-var-4.patch.disabled index b52d6e4..17e269d 100644 --- a/test/integration/rhel-8.0/gcc-static-local-var-4.patch +++ b/test/integration/rhel-8.0/gcc-static-local-var-4.patch.disabled @@ -1,3 +1,5 @@ +Disabled due to https://github.com/dynup/kpatch/issues/940 +--- diff --git a/fs/aio.c b/fs/aio.c index e1f8f01..4dfb05c 100644 --- a/fs/aio.c From 0c96fd0968de6fff7556d815f3a6225b3c08dd3e Mon Sep 17 00:00:00 2001 From: Julien Thierry Date: Tue, 17 Sep 2019 13:57:56 +0100 Subject: [PATCH 6/6] test/integration: Fix RHEL-8 test new-function for ppc64le new-function test fails on ppc64le with the following message: create-diff-object: ERROR: n_tty.o: kpatch_no_sibling_calls_ppc64le: 3445: Found an unsupported sibling call at n_tty_write()+0x20. Add __attribute__((optimize("-fno-optimize-sibling-calls"))) to n_tty_write() definition. Add the suggested attribute, as was done for rhel-7.[5-7] versions of the test. Signed-off-by: Julien Thierry --- test/integration/rhel-8.0/new-function.patch | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/integration/rhel-8.0/new-function.patch b/test/integration/rhel-8.0/new-function.patch index d935205..f1f21a7 100644 --- a/test/integration/rhel-8.0/new-function.patch +++ b/test/integration/rhel-8.0/new-function.patch @@ -15,8 +15,8 @@ index 3ad4602..f3cda7e 100644 return (b - buf) ? b - buf : retval; } -+static ssize_t n_tty_write(struct tty_struct *tty, struct file *file, -+ const unsigned char *buf, size_t nr) ++static ssize_t __attribute__((optimize("-fno-optimize-sibling-calls"))) n_tty_write(struct tty_struct *tty, struct file *file, ++ const unsigned char *buf, size_t nr) +{ + return kpatch_n_tty_write(tty, file, buf, nr); +}