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 <joe.lawrence@redhat.com>
This commit is contained in:
Joe Lawrence 2022-07-13 08:25:37 -04:00
parent dc7e5cb03d
commit e921c557f9
1 changed files with 70 additions and 45 deletions

View File

@ -38,9 +38,11 @@
#ifdef CONFIG_X86_64 #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 long __se_sys##name(__MAP(x,__SC_LONG,__VA_ARGS__)); \
static inline long __kpatch_do_sys##name(__MAP(x,__SC_DECL,__VA_ARGS__));\ static inline long __kpatch_do_sys##name(__MAP(x,__SC_DECL,__VA_ARGS__));\
__X64_SYS_STUBx(x, name, __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__)) 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); \ asmlinkage long __x64_sys##name(const struct pt_regs *regs); \
ALLOW_ERROR_INJECTION(__x64_sys##name, ERRNO); \ ALLOW_ERROR_INJECTION(__x64_sys##name, ERRNO); \
static long __se_sys##name(__MAP(x,__SC_LONG,__VA_ARGS__)); \ 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__)) static inline long __kpatch_do_sys##name(__MAP(x,__SC_DECL,__VA_ARGS__))
#else /* LINUX_VERSION_CODE < KERNEL_VERSION(4, 17, 0) */ # endif /* LINUX_VERSION_CODE */
#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__))
#elif defined(CONFIG_S390) #elif defined(CONFIG_S390)
/* s390/include/asm/syscall_wrapper.h versions */
#define __KPATCH_S390_SYS_STUBx(x, name, ...) \ #define __KPATCH_S390_SYS_STUBx(x, name, ...) \
long __s390_sys##name(struct pt_regs *regs); \ long __s390_sys##name(struct pt_regs *regs); \
ALLOW_ERROR_INJECTION(__s390_sys##name, ERRNO); \ ALLOW_ERROR_INJECTION(__s390_sys##name, ERRNO); \
@ -149,7 +114,67 @@
__diag_pop(); \ __diag_pop(); \
static inline long __kpatch_do_sys##name(__MAP(x,__SC_DECL,__VA_ARGS__)) static inline long __kpatch_do_sys##name(__MAP(x,__SC_DECL,__VA_ARGS__))
#endif /* CONFIG_X86_64 */ #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_ */ #endif /* __KPATCH_SYSCALL_H_ */