Skip to content

Commit 2ca408d

Browse files
Brian Gerstsuryasaimadhu
authored andcommitted
fanotify: Fix sys_fanotify_mark() on native x86-32
Commit 121b32a ("x86/entry/32: Use IA32-specific wrappers for syscalls taking 64-bit arguments") converted native x86-32 which take 64-bit arguments to use the compat handlers to allow conversion to passing args via pt_regs. sys_fanotify_mark() was however missed, as it has a general compat handler. Add a config option that will use the syscall wrapper that takes the split args for native 32-bit. [ bp: Fix typo in Kconfig help text. ] Fixes: 121b32a ("x86/entry/32: Use IA32-specific wrappers for syscalls taking 64-bit arguments") Reported-by: Paweł Jasiak <[email protected]> Signed-off-by: Brian Gerst <[email protected]> Signed-off-by: Borislav Petkov <[email protected]> Acked-by: Jan Kara <[email protected]> Acked-by: Andy Lutomirski <[email protected]> Link: https://lkml.kernel.org/r/[email protected]
1 parent 5c8fe58 commit 2ca408d

File tree

4 files changed

+38
-10
lines changed

4 files changed

+38
-10
lines changed

arch/Kconfig

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1105,6 +1105,12 @@ config HAVE_ARCH_PFN_VALID
11051105
config ARCH_SUPPORTS_DEBUG_PAGEALLOC
11061106
bool
11071107

1108+
config ARCH_SPLIT_ARG64
1109+
bool
1110+
help
1111+
If a 32-bit architecture requires 64-bit arguments to be split into
1112+
pairs of 32-bit arguments, select this option.
1113+
11081114
source "kernel/gcov/Kconfig"
11091115

11101116
source "scripts/gcc-plugins/Kconfig"

arch/x86/Kconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ config X86_32
1919
select KMAP_LOCAL
2020
select MODULES_USE_ELF_REL
2121
select OLD_SIGACTION
22+
select ARCH_SPLIT_ARG64
2223

2324
config X86_64
2425
def_bool y

fs/notify/fanotify/fanotify_user.c

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1285,26 +1285,23 @@ static int do_fanotify_mark(int fanotify_fd, unsigned int flags, __u64 mask,
12851285
return ret;
12861286
}
12871287

1288+
#ifndef CONFIG_ARCH_SPLIT_ARG64
12881289
SYSCALL_DEFINE5(fanotify_mark, int, fanotify_fd, unsigned int, flags,
12891290
__u64, mask, int, dfd,
12901291
const char __user *, pathname)
12911292
{
12921293
return do_fanotify_mark(fanotify_fd, flags, mask, dfd, pathname);
12931294
}
1295+
#endif
12941296

1295-
#ifdef CONFIG_COMPAT
1296-
COMPAT_SYSCALL_DEFINE6(fanotify_mark,
1297+
#if defined(CONFIG_ARCH_SPLIT_ARG64) || defined(CONFIG_COMPAT)
1298+
SYSCALL32_DEFINE6(fanotify_mark,
12971299
int, fanotify_fd, unsigned int, flags,
1298-
__u32, mask0, __u32, mask1, int, dfd,
1300+
SC_ARG64(mask), int, dfd,
12991301
const char __user *, pathname)
13001302
{
1301-
return do_fanotify_mark(fanotify_fd, flags,
1302-
#ifdef __BIG_ENDIAN
1303-
((__u64)mask0 << 32) | mask1,
1304-
#else
1305-
((__u64)mask1 << 32) | mask0,
1306-
#endif
1307-
dfd, pathname);
1303+
return do_fanotify_mark(fanotify_fd, flags, SC_VAL64(__u64, mask),
1304+
dfd, pathname);
13081305
}
13091306
#endif
13101307

include/linux/syscalls.h

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -251,6 +251,30 @@ static inline int is_syscall_trace_event(struct trace_event_call *tp_event)
251251
static inline long __do_sys##name(__MAP(x,__SC_DECL,__VA_ARGS__))
252252
#endif /* __SYSCALL_DEFINEx */
253253

254+
/* For split 64-bit arguments on 32-bit architectures */
255+
#ifdef __LITTLE_ENDIAN
256+
#define SC_ARG64(name) u32, name##_lo, u32, name##_hi
257+
#else
258+
#define SC_ARG64(name) u32, name##_hi, u32, name##_lo
259+
#endif
260+
#define SC_VAL64(type, name) ((type) name##_hi << 32 | name##_lo)
261+
262+
#ifdef CONFIG_COMPAT
263+
#define SYSCALL32_DEFINE1 COMPAT_SYSCALL_DEFINE1
264+
#define SYSCALL32_DEFINE2 COMPAT_SYSCALL_DEFINE2
265+
#define SYSCALL32_DEFINE3 COMPAT_SYSCALL_DEFINE3
266+
#define SYSCALL32_DEFINE4 COMPAT_SYSCALL_DEFINE4
267+
#define SYSCALL32_DEFINE5 COMPAT_SYSCALL_DEFINE5
268+
#define SYSCALL32_DEFINE6 COMPAT_SYSCALL_DEFINE6
269+
#else
270+
#define SYSCALL32_DEFINE1 SYSCALL_DEFINE1
271+
#define SYSCALL32_DEFINE2 SYSCALL_DEFINE2
272+
#define SYSCALL32_DEFINE3 SYSCALL_DEFINE3
273+
#define SYSCALL32_DEFINE4 SYSCALL_DEFINE4
274+
#define SYSCALL32_DEFINE5 SYSCALL_DEFINE5
275+
#define SYSCALL32_DEFINE6 SYSCALL_DEFINE6
276+
#endif
277+
254278
/*
255279
* Called before coming back to user-mode. Returning to user-mode with an
256280
* address limit different than USER_DS can allow to overwrite kernel memory.

0 commit comments

Comments
 (0)