From 0e0cee369acd9ae6f26722353f8a4507808a9a35 Mon Sep 17 00:00:00 2001 From: Artem Savkov Date: Mon, 12 Aug 2019 14:36:16 +0200 Subject: [PATCH] test/integration: add rhel-7.7 rebased patches Added integration-test patches rebased against rhel-7.7 GA kernel. No conflicts, some fuzz. Signed-off-by: Artem Savkov --- .../rhel-7.7/bug-table-section.patch | 13 ++ .../rhel-7.7/cmdline-string-LOADED.test | 3 + .../integration/rhel-7.7/cmdline-string.patch | 13 ++ .../integration/rhel-7.7/data-new-LOADED.test | 3 + test/integration/rhel-7.7/data-new.patch | 29 +++ .../rhel-7.7/data-read-mostly.patch | 12 ++ test/integration/rhel-7.7/fixup-section.patch | 12 ++ .../rhel-7.7/gcc-constprop.patch.disabled | 13 ++ test/integration/rhel-7.7/gcc-isra.patch | 12 ++ test/integration/rhel-7.7/gcc-mangled-3.patch | 14 ++ .../rhel-7.7/gcc-static-local-var-2.patch | 14 ++ .../rhel-7.7/gcc-static-local-var-3.patch | 20 +++ .../rhel-7.7/gcc-static-local-var-4.patch | 21 +++ .../rhel-7.7/gcc-static-local-var-4.test | 7 + .../rhel-7.7/gcc-static-local-var-5.patch | 46 +++++ .../rhel-7.7/gcc-static-local-var-6.patch | 23 +++ .../rhel-7.7/macro-callbacks.patch | 166 ++++++++++++++++++ test/integration/rhel-7.7/macro-printk.patch | 151 ++++++++++++++++ .../rhel-7.7/meminfo-init-FAIL.patch | 12 ++ .../rhel-7.7/meminfo-init2-FAIL.patch | 20 +++ .../rhel-7.7/meminfo-string-LOADED.test | 3 + .../integration/rhel-7.7/meminfo-string.patch | 13 ++ .../rhel-7.7/module-call-external.patch | 35 ++++ test/integration/rhel-7.7/multiple.test | 65 +++++++ test/integration/rhel-7.7/new-function.patch | 26 +++ test/integration/rhel-7.7/new-globals.patch | 36 ++++ .../rhel-7.7/parainstructions-section.patch | 12 ++ .../rhel-7.7/shadow-newpid-LOADED.test | 3 + test/integration/rhel-7.7/shadow-newpid.patch | 72 ++++++++ .../rhel-7.7/smp-locks-section.patch | 15 ++ .../integration/rhel-7.7/special-static.patch | 23 +++ .../rhel-7.7/tracepoints-section.patch | 14 ++ .../rhel-7.7/warn-detect-FAIL.patch | 9 + 33 files changed, 930 insertions(+) create mode 100644 test/integration/rhel-7.7/bug-table-section.patch create mode 100755 test/integration/rhel-7.7/cmdline-string-LOADED.test create mode 100644 test/integration/rhel-7.7/cmdline-string.patch create mode 100755 test/integration/rhel-7.7/data-new-LOADED.test create mode 100644 test/integration/rhel-7.7/data-new.patch create mode 100644 test/integration/rhel-7.7/data-read-mostly.patch create mode 100644 test/integration/rhel-7.7/fixup-section.patch create mode 100644 test/integration/rhel-7.7/gcc-constprop.patch.disabled create mode 100644 test/integration/rhel-7.7/gcc-isra.patch create mode 100644 test/integration/rhel-7.7/gcc-mangled-3.patch create mode 100644 test/integration/rhel-7.7/gcc-static-local-var-2.patch create mode 100644 test/integration/rhel-7.7/gcc-static-local-var-3.patch create mode 100644 test/integration/rhel-7.7/gcc-static-local-var-4.patch create mode 100755 test/integration/rhel-7.7/gcc-static-local-var-4.test create mode 100644 test/integration/rhel-7.7/gcc-static-local-var-5.patch create mode 100644 test/integration/rhel-7.7/gcc-static-local-var-6.patch create mode 100644 test/integration/rhel-7.7/macro-callbacks.patch create mode 100644 test/integration/rhel-7.7/macro-printk.patch create mode 100644 test/integration/rhel-7.7/meminfo-init-FAIL.patch create mode 100644 test/integration/rhel-7.7/meminfo-init2-FAIL.patch create mode 100755 test/integration/rhel-7.7/meminfo-string-LOADED.test create mode 100644 test/integration/rhel-7.7/meminfo-string.patch create mode 100644 test/integration/rhel-7.7/module-call-external.patch create mode 100755 test/integration/rhel-7.7/multiple.test create mode 100644 test/integration/rhel-7.7/new-function.patch create mode 100644 test/integration/rhel-7.7/new-globals.patch create mode 100644 test/integration/rhel-7.7/parainstructions-section.patch create mode 100755 test/integration/rhel-7.7/shadow-newpid-LOADED.test create mode 100644 test/integration/rhel-7.7/shadow-newpid.patch create mode 100644 test/integration/rhel-7.7/smp-locks-section.patch create mode 100644 test/integration/rhel-7.7/special-static.patch create mode 100644 test/integration/rhel-7.7/tracepoints-section.patch create mode 100644 test/integration/rhel-7.7/warn-detect-FAIL.patch diff --git a/test/integration/rhel-7.7/bug-table-section.patch b/test/integration/rhel-7.7/bug-table-section.patch new file mode 100644 index 0000000..34342c0 --- /dev/null +++ b/test/integration/rhel-7.7/bug-table-section.patch @@ -0,0 +1,13 @@ +Index: kernel/fs/proc/proc_sysctl.c +=================================================================== +--- kernel.orig/fs/proc/proc_sysctl.c ++++ kernel/fs/proc/proc_sysctl.c +@@ -301,6 +301,8 @@ void sysctl_head_put(struct ctl_table_he + + 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-7.7/cmdline-string-LOADED.test b/test/integration/rhel-7.7/cmdline-string-LOADED.test new file mode 100755 index 0000000..a8e0a08 --- /dev/null +++ b/test/integration/rhel-7.7/cmdline-string-LOADED.test @@ -0,0 +1,3 @@ +#!/bin/bash + +grep kpatch=1 /proc/cmdline diff --git a/test/integration/rhel-7.7/cmdline-string.patch b/test/integration/rhel-7.7/cmdline-string.patch new file mode 100644 index 0000000..f1f12b3 --- /dev/null +++ b/test/integration/rhel-7.7/cmdline-string.patch @@ -0,0 +1,13 @@ +Index: kernel/fs/proc/cmdline.c +=================================================================== +--- kernel.orig/fs/proc/cmdline.c ++++ kernel/fs/proc/cmdline.c +@@ -5,7 +5,7 @@ + + static int cmdline_proc_show(struct seq_file *m, void *v) + { +- seq_printf(m, "%s\n", saved_command_line); ++ seq_printf(m, "%s kpatch=1\n", saved_command_line); + return 0; + } + diff --git a/test/integration/rhel-7.7/data-new-LOADED.test b/test/integration/rhel-7.7/data-new-LOADED.test new file mode 100755 index 0000000..598b6bb --- /dev/null +++ b/test/integration/rhel-7.7/data-new-LOADED.test @@ -0,0 +1,3 @@ +#!/bin/bash + +grep "kpatch: 5" /proc/meminfo diff --git a/test/integration/rhel-7.7/data-new.patch b/test/integration/rhel-7.7/data-new.patch new file mode 100644 index 0000000..4f9abcf --- /dev/null +++ b/test/integration/rhel-7.7/data-new.patch @@ -0,0 +1,29 @@ +Index: kernel/fs/proc/meminfo.c +=================================================================== +--- kernel.orig/fs/proc/meminfo.c ++++ kernel/fs/proc/meminfo.c +@@ -20,6 +20,8 @@ void __attribute__((weak)) arch_report_m + { + } + ++static int foo = 5; ++ + static int meminfo_proc_show(struct seq_file *m, void *v) + { + struct sysinfo i; +@@ -110,6 +112,7 @@ static int meminfo_proc_show(struct seq_ + "CmaTotal: %8lu kB\n" + "CmaFree: %8lu kB\n" + #endif ++ "kpatch: %d" + , + K(i.totalram), + K(i.freeram), +@@ -175,6 +178,7 @@ static int meminfo_proc_show(struct seq_ + , K(totalcma_pages) + , K(global_page_state(NR_FREE_CMA_PAGES)) + #endif ++ ,foo + ); + + hugetlb_report_meminfo(m); diff --git a/test/integration/rhel-7.7/data-read-mostly.patch b/test/integration/rhel-7.7/data-read-mostly.patch new file mode 100644 index 0000000..5e55826 --- /dev/null +++ b/test/integration/rhel-7.7/data-read-mostly.patch @@ -0,0 +1,12 @@ +Index: kernel/net/core/dev.c +=================================================================== +--- kernel.orig/net/core/dev.c ++++ kernel/net/core/dev.c +@@ -4327,6 +4327,7 @@ skip_classify: + case RX_HANDLER_PASS: + break; + default: ++ printk("BUG!\n"); + BUG(); + } + } diff --git a/test/integration/rhel-7.7/fixup-section.patch b/test/integration/rhel-7.7/fixup-section.patch new file mode 100644 index 0000000..27c01cf --- /dev/null +++ b/test/integration/rhel-7.7/fixup-section.patch @@ -0,0 +1,12 @@ +Index: kernel/fs/readdir.c +=================================================================== +--- kernel.orig/fs/readdir.c ++++ kernel/fs/readdir.c +@@ -176,6 +176,7 @@ static int filldir(void * __buf, const c + 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-7.7/gcc-constprop.patch.disabled b/test/integration/rhel-7.7/gcc-constprop.patch.disabled new file mode 100644 index 0000000..63ba45d --- /dev/null +++ b/test/integration/rhel-7.7/gcc-constprop.patch.disabled @@ -0,0 +1,13 @@ +diff -Nupr src.orig/kernel/time/timekeeping.c src/kernel/time/timekeeping.c +--- src.orig/kernel/time/timekeeping.c 2017-09-22 15:27:21.602055778 -0400 ++++ src/kernel/time/timekeeping.c 2017-09-22 15:27:27.522080292 -0400 +@@ -877,6 +877,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-7.7/gcc-isra.patch b/test/integration/rhel-7.7/gcc-isra.patch new file mode 100644 index 0000000..ce5434a --- /dev/null +++ b/test/integration/rhel-7.7/gcc-isra.patch @@ -0,0 +1,12 @@ +Index: kernel/fs/proc/proc_sysctl.c +=================================================================== +--- kernel.orig/fs/proc/proc_sysctl.c ++++ kernel/fs/proc/proc_sysctl.c +@@ -46,6 +46,7 @@ void proc_sys_poll_notify(struct ctl_tab + 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-7.7/gcc-mangled-3.patch b/test/integration/rhel-7.7/gcc-mangled-3.patch new file mode 100644 index 0000000..7dbfc62 --- /dev/null +++ b/test/integration/rhel-7.7/gcc-mangled-3.patch @@ -0,0 +1,14 @@ +Index: kernel/mm/slub.c +=================================================================== +--- kernel.orig/mm/slub.c ++++ kernel/mm/slub.c +@@ -5675,6 +5675,9 @@ void get_slabinfo(struct kmem_cache *s, + unsigned long nr_free = 0; + int node; + ++ if (!jiffies) ++ printk("slabinfo\n"); ++ + for_each_online_node(node) { + struct kmem_cache_node *n = get_node(s, node); + diff --git a/test/integration/rhel-7.7/gcc-static-local-var-2.patch b/test/integration/rhel-7.7/gcc-static-local-var-2.patch new file mode 100644 index 0000000..d1b70f1 --- /dev/null +++ b/test/integration/rhel-7.7/gcc-static-local-var-2.patch @@ -0,0 +1,14 @@ +Index: kernel/mm/mmap.c +=================================================================== +--- kernel.orig/mm/mmap.c ++++ kernel/mm/mmap.c +@@ -1716,6 +1716,9 @@ unsigned long mmap_region(struct file *f + 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, len >> PAGE_SHIFT)) { + unsigned long nr_pages; diff --git a/test/integration/rhel-7.7/gcc-static-local-var-3.patch b/test/integration/rhel-7.7/gcc-static-local-var-3.patch new file mode 100644 index 0000000..584c869 --- /dev/null +++ b/test/integration/rhel-7.7/gcc-static-local-var-3.patch @@ -0,0 +1,20 @@ +Index: kernel/kernel/sys.c +=================================================================== +--- kernel.orig/kernel/sys.c ++++ kernel/kernel/sys.c +@@ -559,8 +559,15 @@ SYSCALL_DEFINE4(reboot, int, magic1, int + 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-7.7/gcc-static-local-var-4.patch b/test/integration/rhel-7.7/gcc-static-local-var-4.patch new file mode 100644 index 0000000..85e4df5 --- /dev/null +++ b/test/integration/rhel-7.7/gcc-static-local-var-4.patch @@ -0,0 +1,21 @@ +Index: kernel/fs/aio.c +=================================================================== +--- kernel.orig/fs/aio.c ++++ kernel/fs/aio.c +@@ -223,9 +223,16 @@ 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; ++ kpatch_aio_foo(); + if (aio_ring_file) { + truncate_setsize(aio_ring_file->f_inode, 0); + diff --git a/test/integration/rhel-7.7/gcc-static-local-var-4.test b/test/integration/rhel-7.7/gcc-static-local-var-4.test new file mode 100755 index 0000000..5c6f030 --- /dev/null +++ b/test/integration/rhel-7.7/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-7.7/gcc-static-local-var-5.patch b/test/integration/rhel-7.7/gcc-static-local-var-5.patch new file mode 100644 index 0000000..3028676 --- /dev/null +++ b/test/integration/rhel-7.7/gcc-static-local-var-5.patch @@ -0,0 +1,46 @@ +Index: kernel/kernel/audit.c +=================================================================== +--- kernel.orig/kernel/audit.c ++++ kernel/kernel/audit.c +@@ -205,6 +205,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; +@@ -215,6 +221,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); +@@ -234,6 +241,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 +@@ -282,6 +294,8 @@ static int audit_log_config_change(char + 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-7.7/gcc-static-local-var-6.patch b/test/integration/rhel-7.7/gcc-static-local-var-6.patch new file mode 100644 index 0000000..53c3946 --- /dev/null +++ b/test/integration/rhel-7.7/gcc-static-local-var-6.patch @@ -0,0 +1,23 @@ +Index: kernel/net/ipv6/netfilter.c +=================================================================== +--- kernel.orig/net/ipv6/netfilter.c ++++ kernel/net/ipv6/netfilter.c +@@ -112,6 +112,8 @@ static int nf_ip6_reroute(struct sk_buff + return 0; + } + ++#include "kpatch-macros.h" ++ + static int nf_ip6_route(struct net *net, struct dst_entry **dst, + struct flowi *fl, bool strict) + { +@@ -125,6 +127,9 @@ static int nf_ip6_route(struct net *net, + 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-7.7/macro-callbacks.patch b/test/integration/rhel-7.7/macro-callbacks.patch new file mode 100644 index 0000000..d6757e0 --- /dev/null +++ b/test/integration/rhel-7.7/macro-callbacks.patch @@ -0,0 +1,166 @@ +kpatch/livepatch callback test patch: + + vmlinux + pcspkr (mod) + joydev (mod) + +Note: update joydev's pre-patch callback to return -ENODEV to test failure path + +Index: kernel/fs/aio.c +=================================================================== +--- kernel.orig/fs/aio.c ++++ kernel/fs/aio.c +@@ -42,6 +42,50 @@ + #include + #include + ++#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 +Index: kernel/drivers/input/joydev.c +=================================================================== +--- kernel.orig/drivers/input/joydev.c ++++ kernel/drivers/input/joydev.c +@@ -954,3 +954,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); +Index: kernel/drivers/input/misc/pcspkr.c +=================================================================== +--- kernel.orig/drivers/input/misc/pcspkr.c ++++ kernel/drivers/input/misc/pcspkr.c +@@ -136,3 +136,46 @@ static struct platform_driver pcspkr_pla + }; + 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/test/integration/rhel-7.7/macro-printk.patch b/test/integration/rhel-7.7/macro-printk.patch new file mode 100644 index 0000000..a4ff62c --- /dev/null +++ b/test/integration/rhel-7.7/macro-printk.patch @@ -0,0 +1,151 @@ +Index: kernel/net/ipv4/fib_frontend.c +=================================================================== +--- kernel.orig/net/ipv4/fib_frontend.c ++++ kernel/net/ipv4/fib_frontend.c +@@ -686,6 +686,7 @@ errout: + return err; + } + ++#include "kpatch-macros.h" + static int inet_rtm_newroute(struct sk_buff *skb, struct nlmsghdr *nlh) + { + struct net *net = sock_net(skb->sk); +@@ -704,6 +705,7 @@ static int inet_rtm_newroute(struct sk_b + } + + err = fib_table_insert(net, tb, &cfg); ++ KPATCH_PRINTK("[inet_rtm_newroute]: err is %d\n", err); + errout: + return err; + } +Index: kernel/net/ipv4/fib_semantics.c +=================================================================== +--- kernel.orig/net/ipv4/fib_semantics.c ++++ kernel/net/ipv4/fib_semantics.c +@@ -985,6 +985,7 @@ fib_convert_metrics(struct fib_info *fi, + return 0; + } + ++#include "kpatch-macros.h" + struct fib_info *fib_create_info(struct fib_config *cfg) + { + int err; +@@ -1009,6 +1010,7 @@ struct fib_info *fib_create_info(struct + #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; +@@ -1029,6 +1031,7 @@ struct fib_info *fib_create_info(struct + 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 == NULL) +@@ -1044,6 +1047,8 @@ struct fib_info *fib_create_info(struct + 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; +@@ -1059,8 +1064,10 @@ struct fib_info *fib_create_info(struct + 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; + +@@ -1111,6 +1118,7 @@ struct fib_info *fib_create_info(struct + 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) +@@ -1128,6 +1136,7 @@ struct fib_info *fib_create_info(struct + goto err_inval; + } + } ++ KPATCH_PRINTK("[fib_create_info]: 7 create error err is %d\n",err); + + if (cfg->fc_scope > RT_SCOPE_HOST) + goto err_inval; +@@ -1150,6 +1159,7 @@ struct fib_info *fib_create_info(struct + goto failure; + } endfor_nexthops(fi) + } ++ KPATCH_PRINTK("[fib_create_info]: 8 create error err is %d\n",err); + + if (fi->fib_prefsrc) { + if (cfg->fc_type != RTN_LOCAL || !cfg->fc_dst || +@@ -1162,6 +1172,7 @@ struct fib_info *fib_create_info(struct + fib_info_update_nh_saddr(net, nexthop_nh); + fib_add_weight(fi, nexthop_nh); + } endfor_nexthops(fi) ++ KPATCH_PRINTK("[fib_create_info]: 9 create error err is %d\n",err); + + fib_rebalance(fi); + +@@ -1173,6 +1184,7 @@ link_it: + ofi->fib_treeref++; + return ofi; + } ++ KPATCH_PRINTK("[fib_create_info]: 10 create error err is %d\n",err); + + fi->fib_treeref++; + atomic_inc(&fi->fib_clntref); +@@ -1196,6 +1208,7 @@ link_it: + 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: +@@ -1206,6 +1219,7 @@ failure: + 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); + } +Index: kernel/net/ipv4/fib_trie.c +=================================================================== +--- kernel.orig/net/ipv4/fib_trie.c ++++ kernel/net/ipv4/fib_trie.c +@@ -1105,6 +1105,7 @@ static int fib_insert_alias(struct trie + } + + /* Caller must hold RTNL. */ ++#include "kpatch-macros.h" + int fib_table_insert(struct net *net, struct fib_table *tb, + struct fib_config *cfg) + { +@@ -1130,11 +1131,14 @@ int fib_table_insert(struct net *net, st + if ((plen < KEYLENGTH) && (key << plen)) + return -EINVAL; + ++ KPATCH_PRINTK("[fib_table_insert]: start\n"); + fi = fib_create_info(cfg); + 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-7.7/meminfo-init-FAIL.patch b/test/integration/rhel-7.7/meminfo-init-FAIL.patch new file mode 100644 index 0000000..f3e6c73 --- /dev/null +++ b/test/integration/rhel-7.7/meminfo-init-FAIL.patch @@ -0,0 +1,12 @@ +Index: kernel/fs/proc/meminfo.c +=================================================================== +--- kernel.orig/fs/proc/meminfo.c ++++ kernel/fs/proc/meminfo.c +@@ -199,6 +199,7 @@ static const struct file_operations memi + + static int __init proc_meminfo_init(void) + { ++ printk("a\n"); + proc_create("meminfo", 0, NULL, &meminfo_proc_fops); + return 0; + } diff --git a/test/integration/rhel-7.7/meminfo-init2-FAIL.patch b/test/integration/rhel-7.7/meminfo-init2-FAIL.patch new file mode 100644 index 0000000..e225294 --- /dev/null +++ b/test/integration/rhel-7.7/meminfo-init2-FAIL.patch @@ -0,0 +1,20 @@ +Index: kernel/fs/proc/meminfo.c +=================================================================== +--- kernel.orig/fs/proc/meminfo.c ++++ kernel/fs/proc/meminfo.c +@@ -30,6 +30,7 @@ static int meminfo_proc_show(struct seq_ + unsigned long pages[NR_LRU_LISTS]; + int lru; + ++ printk("a\n"); + /* + * display in kilobytes. + */ +@@ -199,6 +200,7 @@ static const struct file_operations memi + + static int __init proc_meminfo_init(void) + { ++ printk("a\n"); + proc_create("meminfo", 0, NULL, &meminfo_proc_fops); + return 0; + } diff --git a/test/integration/rhel-7.7/meminfo-string-LOADED.test b/test/integration/rhel-7.7/meminfo-string-LOADED.test new file mode 100755 index 0000000..10dc20b --- /dev/null +++ b/test/integration/rhel-7.7/meminfo-string-LOADED.test @@ -0,0 +1,3 @@ +#!/bin/bash + +grep VMALLOCCHUNK /proc/meminfo diff --git a/test/integration/rhel-7.7/meminfo-string.patch b/test/integration/rhel-7.7/meminfo-string.patch new file mode 100644 index 0000000..23ff7a7 --- /dev/null +++ b/test/integration/rhel-7.7/meminfo-string.patch @@ -0,0 +1,13 @@ +Index: kernel/fs/proc/meminfo.c +=================================================================== +--- kernel.orig/fs/proc/meminfo.c ++++ kernel/fs/proc/meminfo.c +@@ -99,7 +99,7 @@ static int meminfo_proc_show(struct seq_ + "Committed_AS: %8lu kB\n" + "VmallocTotal: %8lu kB\n" + "VmallocUsed: %8lu kB\n" +- "VmallocChunk: %8lu kB\n" ++ "VMALLOCCHUNK: %8lu kB\n" + #ifdef CONFIG_MEMORY_FAILURE + "HardwareCorrupted: %5lu kB\n" + #endif diff --git a/test/integration/rhel-7.7/module-call-external.patch b/test/integration/rhel-7.7/module-call-external.patch new file mode 100644 index 0000000..f43d190 --- /dev/null +++ b/test/integration/rhel-7.7/module-call-external.patch @@ -0,0 +1,35 @@ +Index: kernel/fs/nfsd/export.c +=================================================================== +--- kernel.orig/fs/nfsd/export.c ++++ kernel/fs/nfsd/export.c +@@ -1184,6 +1184,8 @@ static void exp_flags(struct seq_file *m + } + } + ++extern char *kpatch_string(void); ++ + static int e_show(struct seq_file *m, void *p) + { + struct cache_head *cp = p; +@@ -1193,6 +1195,7 @@ static int e_show(struct seq_file *m, vo + 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; + } + +Index: kernel/net/netlink/af_netlink.c +=================================================================== +--- kernel.orig/net/netlink/af_netlink.c ++++ kernel/net/netlink/af_netlink.c +@@ -2568,4 +2568,9 @@ panic: + 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-7.7/multiple.test b/test/integration/rhel-7.7/multiple.test new file mode 100755 index 0000000..cd36a25 --- /dev/null +++ b/test/integration/rhel-7.7/multiple.test @@ -0,0 +1,65 @@ +#!/bin/bash + +SCRIPTDIR="$(readlink -f $(dirname $(type -p $0)))" +ROOTDIR="$(readlink -f $SCRIPTDIR/../..)" +KPATCH="sudo $ROOTDIR/kpatch/kpatch" + +MODULE_PREFIX="test-" +MODULE_POSTFIX=".ko" +TEST_POSTFIX="-LOADED.test" + +set -o errexit + +die() { + echo "ERROR: $@" >&2 + exit 1 +} + +ko_to_test() { + tmp=${1%${MODULE_POSTFIX}}${TEST_POSTFIX} + echo ${tmp#${MODULE_PREFIX}} +} + +# make sure any modules added here are disjoint +declare -a modules +declare -a blacklist=(meminfo-string-LOADED.test) + +for file in "${SCRIPTDIR}"/*"${TEST_POSTFIX}"; do + name=$(basename ${file}) + skip=0 + for bname in "${blacklist[@]}"; do + if [ "${bname}" == "${name}" ]; then + skip=1 + break + fi + done + if [ ${skip} -eq 0 ]; then + modules+=(${MODULE_PREFIX}${name%${TEST_POSTFIX}}${MODULE_POSTFIX}) + fi +done + +for mod in "${modules[@]}"; do + testprog=$(ko_to_test $mod) + $SCRIPTDIR/$testprog && die "$SCRIPTDIR/$testprog succeeded before loading any modules" +done + +for mod in "${modules[@]}"; do + $KPATCH load $mod +done + +for mod in "${modules[@]}"; do + testprog=$(ko_to_test $mod) + $SCRIPTDIR/$testprog || die "$SCRIPTDIR/$testprog failed after loading modules" +done + +for ((idx=${#modules[@]}-1 ; idx>=0 ; idx--)); do + mod=${modules[idx]} + $KPATCH unload $mod +done + +for mod in "${modules[@]}"; do + testprog=$(ko_to_test $mod) + $SCRIPTDIR/$testprog && die "$SCRIPTDIR/$testprog succeeded after unloading modules" +done + +exit 0 diff --git a/test/integration/rhel-7.7/new-function.patch b/test/integration/rhel-7.7/new-function.patch new file mode 100644 index 0000000..604dbe5 --- /dev/null +++ b/test/integration/rhel-7.7/new-function.patch @@ -0,0 +1,26 @@ +Index: kernel/drivers/tty/n_tty.c +=================================================================== +--- kernel.orig/drivers/tty/n_tty.c ++++ kernel/drivers/tty/n_tty.c +@@ -2175,7 +2175,7 @@ do_it_again: + * 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; +@@ -2264,6 +2264,12 @@ break_out: + return (b - buf) ? b - buf : retval; + } + ++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); ++} ++ + /** + * n_tty_poll - poll method for N_TTY + * @tty: terminal device diff --git a/test/integration/rhel-7.7/new-globals.patch b/test/integration/rhel-7.7/new-globals.patch new file mode 100644 index 0000000..e18d09d --- /dev/null +++ b/test/integration/rhel-7.7/new-globals.patch @@ -0,0 +1,36 @@ +Index: kernel/fs/proc/cmdline.c +=================================================================== +--- kernel.orig/fs/proc/cmdline.c ++++ kernel/fs/proc/cmdline.c +@@ -27,3 +27,10 @@ static int __init proc_cmdline_init(void + return 0; + } + module_init(proc_cmdline_init); ++ ++#include ++void kpatch_print_message(void) ++{ ++ if (!jiffies) ++ printk("hello there!\n"); ++} +Index: kernel/fs/proc/meminfo.c +=================================================================== +--- kernel.orig/fs/proc/meminfo.c ++++ kernel/fs/proc/meminfo.c +@@ -16,6 +16,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_ + /* + * Tagged format, for easy grepping and expansion. + */ ++ kpatch_print_message(); + seq_printf(m, + "MemTotal: %8lu kB\n" + "MemFree: %8lu kB\n" diff --git a/test/integration/rhel-7.7/parainstructions-section.patch b/test/integration/rhel-7.7/parainstructions-section.patch new file mode 100644 index 0000000..151d263 --- /dev/null +++ b/test/integration/rhel-7.7/parainstructions-section.patch @@ -0,0 +1,12 @@ +Index: kernel/fs/proc/generic.c +=================================================================== +--- kernel.orig/fs/proc/generic.c ++++ kernel/fs/proc/generic.c +@@ -194,6 +194,7 @@ int proc_alloc_inum(unsigned int *inum) + unsigned int i; + int error; + ++ printk("kpatch-test: testing change to .parainstructions section\n"); + retry: + if (!ida_pre_get(&proc_inum_ida, GFP_KERNEL)) + return -ENOMEM; diff --git a/test/integration/rhel-7.7/shadow-newpid-LOADED.test b/test/integration/rhel-7.7/shadow-newpid-LOADED.test new file mode 100755 index 0000000..c07d112 --- /dev/null +++ b/test/integration/rhel-7.7/shadow-newpid-LOADED.test @@ -0,0 +1,3 @@ +#!/bin/bash + +grep -q newpid: /proc/$$/status diff --git a/test/integration/rhel-7.7/shadow-newpid.patch b/test/integration/rhel-7.7/shadow-newpid.patch new file mode 100644 index 0000000..cae690d --- /dev/null +++ b/test/integration/rhel-7.7/shadow-newpid.patch @@ -0,0 +1,72 @@ +Index: kernel/fs/proc/array.c +=================================================================== +--- kernel.orig/fs/proc/array.c ++++ kernel/fs/proc/array.c +@@ -395,13 +395,20 @@ static inline void task_seccomp(struct s + seq_putc(m, '\n'); + } + ++#include + static inline void task_context_switch_counts(struct seq_file *m, + struct task_struct *p) + { ++ int *newpid; ++ + seq_printf(m, "voluntary_ctxt_switches:\t%lu\n" + "nonvoluntary_ctxt_switches:\t%lu\n", + p->nvcsw, + p->nivcsw); ++ ++ 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) +Index: kernel/kernel/exit.c +=================================================================== +--- kernel.orig/kernel/exit.c ++++ kernel/kernel/exit.c +@@ -791,6 +791,7 @@ static void check_stack_usage(void) + static inline void check_stack_usage(void) {} + #endif + ++#include + void do_exit(long code) + { + struct task_struct *tsk = current; +@@ -888,6 +889,8 @@ void do_exit(long code) + check_stack_usage(); + exit_thread(); + ++ klp_shadow_free(tsk, 0, NULL); ++ + /* + * Flush inherited counters to the parent - before the parent + * gets woken up by child-exit notifications. +Index: kernel/kernel/fork.c +=================================================================== +--- kernel.orig/kernel/fork.c ++++ kernel/kernel/fork.c +@@ -1760,6 +1760,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, +@@ -1797,6 +1798,13 @@ long do_fork(unsigned long clone_flags, + if (!IS_ERR(p)) { + struct completion vfork; + struct pid *pid; ++ int *newpid; ++ static int ctr = 0; ++ ++ newpid = klp_shadow_get_or_alloc(p, 0, sizeof(*newpid), GFP_KERNEL, ++ NULL, NULL); ++ if (newpid) ++ *newpid = ctr++; + + trace_sched_process_fork(current, p); + diff --git a/test/integration/rhel-7.7/smp-locks-section.patch b/test/integration/rhel-7.7/smp-locks-section.patch new file mode 100644 index 0000000..7aa1c31 --- /dev/null +++ b/test/integration/rhel-7.7/smp-locks-section.patch @@ -0,0 +1,15 @@ +Index: kernel/drivers/tty/tty_buffer.c +=================================================================== +--- kernel.orig/drivers/tty/tty_buffer.c ++++ kernel/drivers/tty/tty_buffer.c +@@ -217,6 +217,10 @@ int tty_buffer_request_room(struct tty_p + /* OPTIMISATION: We could keep a per tty "zero" sized buffer to + remove this conditional if its worth it. This would be invisible + to the callers */ ++ ++ if (!size) ++ printk("kpatch-test: testing .smp_locks section changes\n"); ++ + b = buf->tail; + if (b != NULL) + left = b->size - b->used; diff --git a/test/integration/rhel-7.7/special-static.patch b/test/integration/rhel-7.7/special-static.patch new file mode 100644 index 0000000..8a757ba --- /dev/null +++ b/test/integration/rhel-7.7/special-static.patch @@ -0,0 +1,23 @@ +Index: kernel/kernel/fork.c +=================================================================== +--- kernel.orig/kernel/fork.c ++++ kernel/kernel/fork.c +@@ -1146,10 +1146,18 @@ static void posix_cpu_timers_init_group( + INIT_LIST_HEAD(&sig->cpu_timers[2]); + } + ++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-7.7/tracepoints-section.patch b/test/integration/rhel-7.7/tracepoints-section.patch new file mode 100644 index 0000000..b992e14 --- /dev/null +++ b/test/integration/rhel-7.7/tracepoints-section.patch @@ -0,0 +1,14 @@ +Index: kernel/kernel/timer.c +=================================================================== +--- kernel.orig/kernel/timer.c ++++ kernel/kernel/timer.c +@@ -1454,6 +1454,9 @@ static void run_timer_softirq(struct sof + { + struct tvec_base *base = __this_cpu_read(tvec_bases); + ++ if (!base) ++ printk("kpatch-test: testing __tracepoints section changes\n"); ++ + if (time_after_eq(jiffies, base->timer_jiffies)) + __run_timers(base); + } diff --git a/test/integration/rhel-7.7/warn-detect-FAIL.patch b/test/integration/rhel-7.7/warn-detect-FAIL.patch new file mode 100644 index 0000000..801fa4c --- /dev/null +++ b/test/integration/rhel-7.7/warn-detect-FAIL.patch @@ -0,0 +1,9 @@ +Index: kernel/arch/x86/kvm/x86.c +=================================================================== +--- kernel.orig/arch/x86/kvm/x86.c ++++ kernel/arch/x86/kvm/x86.c +@@ -1,3 +1,4 @@ ++ + /* + * Kernel-based Virtual Machine driver for Linux + *