Skip to content

Commit

Permalink
kmod: maintain syscall metadata sections in kpatch syscall macros
Browse files Browse the repository at this point in the history
The KPATCH_SYSCALL_DEFINEn macros in kpatch-syscall.h do not provide the
same syscall metadata (saved in the __syscalls_metadata and
_ftrace_events ELF sections) as the kernel.  These same macros also
instruct kpatch-build to ignore changes to these sections.  This works
fine as long as there are other unmodified syscalls present in the
object file.  However, if not, the kpatch syscall macros may result in
either metadata ELF sections not appearing in the patched object file.
The create-diff-object program expects to encounter any ELF section that
has been marked by KPATCH_IGNORE_SECTION in the patched object file.

To avoid this limitation, create dummy __syscalls_metadata and
_ftrace_events entries for the kpatch-modified syscall.  The specific
values shouldn't matter since their sections will still be marked with
KPATCH_IGNORE_SECTION and now their presence will be guarenteed for
create-diff-object.

Closes: #1375 ("kpatch-build error when modifying an object file's only syscall")
Signed-off-by: Joe Lawrence <[email protected]>
  • Loading branch information
joe-lawrence committed Feb 29, 2024
1 parent 0edd6e4 commit 906bb8f
Showing 1 changed file with 14 additions and 4 deletions.
18 changes: 14 additions & 4 deletions kmod/patch/kpatch-syscall.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,24 @@
* being a 'kpatch' prefix added to the __do_sys##name() function name. This
* causes kpatch-build to treat it as a new function (due to
* its new name), and its caller __se_sys##name() function is inlined by its own
* caller __x64_sys##name() function, which has an fentry hook.
* caller __x64_sys##name() function, which has an fentry hook. Since the
* kpatch versions do not provide SYSCALL_METADATA, specifically entries in the
* __syscalls_metadata and _ftrace_events sections, provide dummy values in
* these sections and instruct kpatch-build to ignore changes to them.
*
* To patch a syscall, just replace the use of the SYSCALL_DEFINE1 (or similar)
* macro with the "KPATCH_" prefixed version.
*/

#define KPATCH_IGNORE_SYSCALL_SECTIONS \
#define KPATCH_SYSCALL_METADATA(sname) \
static struct syscall_metadata __used \
__section("__syscalls_metadata") \
*__p_syscall_meta_##sname = NULL; \
KPATCH_IGNORE_SECTION("__syscalls_metadata"); \
\
static struct trace_event_call __used \
__section("_ftrace_events") \
*__event_enter_##sname = NULL; \
KPATCH_IGNORE_SECTION("_ftrace_events")

#define KPATCH_SYSCALL_DEFINE1(name, ...) KPATCH_SYSCALL_DEFINEx(1, _##name, __VA_ARGS__)
Expand All @@ -33,7 +43,7 @@
#define KPATCH_SYSCALL_DEFINE6(name, ...) KPATCH_SYSCALL_DEFINEx(6, _##name, __VA_ARGS__)

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

#ifdef CONFIG_X86_64
Expand Down

0 comments on commit 906bb8f

Please sign in to comment.