dynup / kpatch

kpatch - live kernel patching
GNU General Public License v2.0
1.49k stars 304 forks source link

kpatch-build error when modifying an object file's only syscall #1375

Closed joe-lawrence closed 8 months ago

joe-lawrence commented 8 months ago

Repro:

Try building a kpatch like the following, which modifies the only syscall in the resulting object file:

diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c
index f1f9ce9b23f6..b8aaea260673 100644
--- a/kernel/printk/printk.c
+++ b/kernel/printk/printk.c
@@ -1903,8 +1903,10 @@ int do_syslog(int type, char __user *buf, int len, int source)
    return error;
 }

-SYSCALL_DEFINE3(syslog, int, type, char __user *, buf, int, len)
+#include "kpatch-syscall.h"
+KPATCH_SYSCALL_DEFINE3(syslog, int, type, char __user *, buf, int, len)
 {
+   asm("nop");
    return do_syslog(type, buf, len, SYSLOG_FROM_READER);
 }

kpatch-build will error out:

create-diff-object: ERROR: printk.o: kpatch_mark_ignored_sections: 2895: KPATCH_IGNORE_SECTION: can't find __syscalls_metadata
printk.o: ignoring section: _ftrace_events

Cause:

The kpatch-syscall.h macros specifically call out __syscalls_metadata and _ftrace_events as sections for kpatch-build to ignore:

#define KPATCH_IGNORE_SYSCALL_SECTIONS                  \
    KPATCH_IGNORE_SECTION("__syscalls_metadata");           \
    KPATCH_IGNORE_SECTION("_ftrace_events")

#define KPATCH_SYSCALL_DEFINE1(name, ...) KPATCH_SYSCALL_DEFINEx(1, _##name, __VA_ARGS__)

...

#define KPATCH_SYSCALL_DEFINEx(x, sname, ...)               \
    KPATCH_IGNORE_SYSCALL_SECTIONS;                 \
    __KPATCH_SYSCALL_DEFINEx(x, sname, __VA_ARGS__)

However, create-diff-object's kpatch_mark_ignored_sections() code to ignore such sections also requires that the sections are found in the object file, else it will error out with the above warning.

Object file sections from the repro patch build:

[root@hpe-bl460cgen10-01 kpatch]# readelf --wide --sections ~/.kpatch/tmp/orig/kernel/printk/printk.o | grep -w -e '_ftrace_events' -e '__syscalls_metadata'
  [504] __syscalls_metadata PROGBITS        0000000000000000 00b6b0 000008 00  WA  0   0  8
  [506] _ftrace_events      PROGBITS        0000000000000000 00b6b8 000018 00  WA  0   0  8
[root@hpe-bl460cgen10-01 kpatch]# readelf --wide --sections ~/.kpatch/tmp/patched/kernel/printk/printk.o | grep -w -e '_ftrace_events' -e '__syscalls_metadata'
  [530] _ftrace_events      PROGBITS        0000000000000000 38bc20 000008 00  WA  0   0  8