From e921c557f9f531cf4ad1104c2cb15065e461e089 Mon Sep 17 00:00:00 2001 From: Joe Lawrence Date: Wed, 13 Jul 2022 08:25:37 -0400 Subject: [PATCH] macros: tweak syscall patching macros Kernel version specific __KPATCH_SYSCALL_DEFINEx macros were added to kpatch-syscall.h for x86, but only single versions for other arches. This works out for s390x, but not ppc64le for which kpatch-build support goes back to kernel versions that require slightly different macros. Reorder the __KPATCH_SYSCALL_DEFINEx macros to define the arch-specific ones first (arch/.../include/asm/syscall_wrapper.h) and then fall back to using generic ones (include/linux/syscalls.h versions). Fixes: #1278 Fixes: 9c0b678621b9 ("macros: add syscall patching macros") Signed-off-by: Joe Lawrence --- kmod/patch/kpatch-syscall.h | 115 ++++++++++++++++++++++-------------- 1 file changed, 70 insertions(+), 45 deletions(-) diff --git a/kmod/patch/kpatch-syscall.h b/kmod/patch/kpatch-syscall.h index 07a1cec..e69f3c1 100644 --- a/kmod/patch/kpatch-syscall.h +++ b/kmod/patch/kpatch-syscall.h @@ -38,9 +38,11 @@ #ifdef CONFIG_X86_64 -#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 7, 0) +/* x86/include/asm/syscall_wrapper.h versions */ -#define __KPATCH_SYSCALL_DEFINEx(x, name, ...) \ +# if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 7, 0) + +# define __KPATCH_SYSCALL_DEFINEx(x, name, ...) \ static long __se_sys##name(__MAP(x,__SC_LONG,__VA_ARGS__)); \ static inline long __kpatch_do_sys##name(__MAP(x,__SC_DECL,__VA_ARGS__));\ __X64_SYS_STUBx(x, name, __VA_ARGS__) \ @@ -54,9 +56,9 @@ } \ static inline long __kpatch_do_sys##name(__MAP(x,__SC_DECL,__VA_ARGS__)) -#elif LINUX_VERSION_CODE >= KERNEL_VERSION(4, 17, 0) +# elif LINUX_VERSION_CODE >= KERNEL_VERSION(4, 17, 0) -#define __KPATCH_SYSCALL_DEFINEx(x, name, ...) \ +# define __KPATCH_SYSCALL_DEFINEx(x, name, ...) \ asmlinkage long __x64_sys##name(const struct pt_regs *regs); \ ALLOW_ERROR_INJECTION(__x64_sys##name, ERRNO); \ static long __se_sys##name(__MAP(x,__SC_LONG,__VA_ARGS__)); \ @@ -75,49 +77,12 @@ } \ static inline long __kpatch_do_sys##name(__MAP(x,__SC_DECL,__VA_ARGS__)) -#else /* LINUX_VERSION_CODE < KERNEL_VERSION(4, 17, 0) */ - -#define __KPATCH_SYSCALL_DEFINEx(x, name, ...) \ - asmlinkage long sys##name(__MAP(x,__SC_DECL,__VA_ARGS__)); \ - static inline long __kpatch_SYSC##name(__MAP(x,__SC_DECL,__VA_ARGS__));\ - asmlinkage long SyS##name(__MAP(x,__SC_LONG,__VA_ARGS__)) \ - { \ - long ret = __kpatch_SYSC##name(__MAP(x,__SC_CAST,__VA_ARGS__));\ - __MAP(x,__SC_TEST,__VA_ARGS__); \ - __PROTECT(x, ret,__MAP(x,__SC_ARGS,__VA_ARGS__)); \ - return ret; \ - } \ - SYSCALL_ALIAS(sys##name, SyS##name); \ - static inline long __kpatch_SYSC##name(__MAP(x,__SC_DECL,__VA_ARGS__)) - -#endif /* LINUX_VERSION_CODE */ - - -#elif defined(CONFIG_PPC64) - -#define __KPATCH_SYSCALL_DEFINEx(x, name, ...) \ - __diag_push(); \ - __diag_ignore(GCC, 8, "-Wattribute-alias", \ - "Type aliasing is used to sanitize syscall arguments");\ - asmlinkage long sys##name(__MAP(x,__SC_DECL,__VA_ARGS__)) \ - __attribute__((alias(__stringify(__se_sys##name)))); \ - ALLOW_ERROR_INJECTION(sys##name, ERRNO); \ - static inline long __kpatch_do_sys##name(__MAP(x,__SC_DECL,__VA_ARGS__));\ - asmlinkage long __se_sys##name(__MAP(x,__SC_LONG,__VA_ARGS__)); \ - asmlinkage long __attribute__((optimize("-fno-optimize-sibling-calls")))\ - __se_sys##name(__MAP(x,__SC_LONG,__VA_ARGS__)) \ - { \ - long ret = __kpatch_do_sys##name(__MAP(x,__SC_CAST,__VA_ARGS__));\ - __MAP(x,__SC_TEST,__VA_ARGS__); \ - __PROTECT(x, ret,__MAP(x,__SC_ARGS,__VA_ARGS__)); \ - return ret; \ - } \ - __diag_pop(); \ - static inline long __kpatch_do_sys##name(__MAP(x,__SC_DECL,__VA_ARGS__)) - +# endif /* LINUX_VERSION_CODE */ #elif defined(CONFIG_S390) +/* s390/include/asm/syscall_wrapper.h versions */ + #define __KPATCH_S390_SYS_STUBx(x, name, ...) \ long __s390_sys##name(struct pt_regs *regs); \ ALLOW_ERROR_INJECTION(__s390_sys##name, ERRNO); \ @@ -149,7 +114,67 @@ __diag_pop(); \ static inline long __kpatch_do_sys##name(__MAP(x,__SC_DECL,__VA_ARGS__)) - #endif /* CONFIG_X86_64 */ + +#ifndef __KPATCH_SYSCALL_DEFINEx + +/* include/linux/syscalls.h versions */ + +# if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 18, 0) +# define __KPATCH_SYSCALL_DEFINEx(x, name, ...) \ + __diag_push(); \ + __diag_ignore(GCC, 8, "-Wattribute-alias", \ + "Type aliasing is used to sanitize syscall arguments");\ + asmlinkage long sys##name(__MAP(x,__SC_DECL,__VA_ARGS__)) \ + __attribute__((alias(__stringify(__se_sys##name)))); \ + ALLOW_ERROR_INJECTION(sys##name, ERRNO); \ + static inline long __kpatch_do_sys##name(__MAP(x,__SC_DECL,__VA_ARGS__));\ + asmlinkage long __se_sys##name(__MAP(x,__SC_LONG,__VA_ARGS__)); \ + asmlinkage long __attribute__((optimize("-fno-optimize-sibling-calls")))\ + __se_sys##name(__MAP(x,__SC_LONG,__VA_ARGS__)) \ + { \ + long ret = __kpatch_do_sys##name(__MAP(x,__SC_CAST,__VA_ARGS__));\ + __MAP(x,__SC_TEST,__VA_ARGS__); \ + __PROTECT(x, ret,__MAP(x,__SC_ARGS,__VA_ARGS__)); \ + return ret; \ + } \ + __diag_pop(); \ + static inline long __kpatch_do_sys##name(__MAP(x,__SC_DECL,__VA_ARGS__)) + +# elif LINUX_VERSION_CODE >= KERNEL_VERSION(4, 17, 0) +# define __KPATCH_SYSCALL_DEFINEx(x, name, ...) \ + asmlinkage long sys##name(__MAP(x,__SC_DECL,__VA_ARGS__)) \ + __attribute__((alias(__stringify(__se_sys##name)))); \ + ALLOW_ERROR_INJECTION(sys##name, ERRNO); \ + static inline long __kpatch_do_sys##name(__MAP(x,__SC_DECL,__VA_ARGS__));\ + asmlinkage long __se_sys##name(__MAP(x,__SC_LONG,__VA_ARGS__)); \ + asmlinkage long __se_sys##name(__MAP(x,__SC_LONG,__VA_ARGS__)) \ + { \ + long ret = __kpatch_do_sys##name(__MAP(x,__SC_CAST,__VA_ARGS__));\ + __MAP(x,__SC_TEST,__VA_ARGS__); \ + __PROTECT(x, ret,__MAP(x,__SC_ARGS,__VA_ARGS__)); \ + return ret; \ + } \ + static inline long __kpatch_do_sys##name(__MAP(x,__SC_DECL,__VA_ARGS__)) + +# else +# define __KPATCH_SYSCALL_DEFINEx(x, name, ...) \ + asmlinkage long sys##name(__MAP(x,__SC_DECL,__VA_ARGS__)) \ + __attribute__((alias(__stringify(SyS##name)))); \ + static inline long __kpatch_SYSC##name(__MAP(x,__SC_DECL,__VA_ARGS__)); \ + asmlinkage long SyS##name(__MAP(x,__SC_LONG,__VA_ARGS__)); \ + asmlinkage long SyS##name(__MAP(x,__SC_LONG,__VA_ARGS__)) \ + { \ + long ret = __kpatch_SYSC##name(__MAP(x,__SC_CAST,__VA_ARGS__)); \ + __MAP(x,__SC_TEST,__VA_ARGS__); \ + __PROTECT(x, ret,__MAP(x,__SC_ARGS,__VA_ARGS__)); \ + return ret; \ + } \ + static inline long __kpatch_SYSC##name(__MAP(x,__SC_DECL,__VA_ARGS__)) + +# endif + +#endif /* __KPATCH_SYSCALL_DEFINEx */ + #endif /* __KPATCH_SYSCALL_H_ */