On 23/06/2023 15:33, Tudor Cretu wrote:
The aio_context_t represents a token that allows the userspace to query a specific aio context. It can also be used as a pointer to the userspace mapping of aio_ring buffer. In some userspace software, including libaio, it's used directly to access the aio_ring. Therefore, aio_context_t must be able to hold a full capability. As __kernel_ulong_t type is not large enough to fit a user pointer in the PCuABI, change the aio_context_t type to void __user *.
As aio_context_t is still mainly used as a token id, it should not be modified in any way by the kernel. Therefore, make a full capability
s/the kernel/userspace/
comparison in lookup_ioctx() to match the aio_context_t.
Signed-off-by: Tudor Cretu tudor.cretu@arm.com
[...]
@@ -1464,7 +1479,9 @@ COMPAT_SYSCALL_DEFINE2(io_setup, unsigned, nr_events, compat_aio_context_t __use */ SYSCALL_DEFINE1(io_destroy, aio_context_t, ctx) {
- struct kioctx *ioctx = lookup_ioctx(ctx);
- struct kioctx *ioctx;
- ioctx = lookup_ioctx(ctx);
That diff looks like a leftover.
if (likely(NULL != ioctx)) { struct ctx_rq_wait wait; int ret; @@ -2188,7 +2205,7 @@ COMPAT_SYSCALL_DEFINE3(io_submit, compat_aio_context_t, ctx_id, if (unlikely(nr < 0)) return -EINVAL;
- ctx = lookup_ioctx(ctx_id);
- ctx = lookup_ioctx(compat_ptr(ctx_id)); if (unlikely(!ctx)) { pr_debug("EINVAL: invalid context id\n"); return -EINVAL;
@@ -2409,7 +2426,7 @@ SYSCALL_DEFINE6(io_pgetevents_time32, #if defined(CONFIG_COMPAT_32BIT_TIME) -SYSCALL_DEFINE5(io_getevents_time32, __u32, ctx_id, +SYSCALL_DEFINE5(io_getevents_time32, aio_context_t, ctx_id, __s32, min_nr, __s32, nr, struct io_event __user *, events, @@ -2461,7 +2478,7 @@ COMPAT_SYSCALL_DEFINE6(io_pgetevents, if (ret) return ret;
- ret = do_io_getevents(ctx_id, min_nr, nr, events, timeout ? &t : NULL);
- ret = do_io_getevents(compat_ptr(ctx_id), min_nr, nr, events, timeout ? &t : NULL);
interrupted = signal_pending(current); restore_saved_sigmask_unless(interrupted); @@ -2496,7 +2513,7 @@ COMPAT_SYSCALL_DEFINE6(io_pgetevents_time64, if (ret) return ret;
- ret = do_io_getevents(ctx_id, min_nr, nr, events, timeout ? &t : NULL);
- ret = do_io_getevents(compat_ptr(ctx_id), min_nr, nr, events, timeout ? &t : NULL);
interrupted = signal_pending(current); restore_saved_sigmask_unless(interrupted); diff --git a/include/asm-generic/compat.h b/include/asm-generic/compat.h index f4ef0518470e..af572c063143 100644 --- a/include/asm-generic/compat.h +++ b/include/asm-generic/compat.h @@ -56,7 +56,6 @@ typedef s64 compat_long_t; typedef u64 compat_ulong_t; typedef u64 compat_uptr_t; typedef u64 compat_caddr_t; -typedef u64 compat_aio_context_t; typedef u64 compat_old_sigset_t; #else typedef u32 compat_size_t; @@ -68,9 +67,9 @@ typedef s32 compat_long_t; typedef u32 compat_ulong_t; typedef u32 compat_uptr_t; typedef u32 compat_caddr_t; -typedef u32 compat_aio_context_t; typedef u32 compat_old_sigset_t; #endif
Nit: would add an empty line in between.
Kevin
+typedef compat_uptr_t compat_aio_context_t; #ifndef __compat_uid_t typedef u32 __compat_uid_t; diff --git a/include/uapi/linux/aio_abi.h b/include/uapi/linux/aio_abi.h index 8050909c2887..87c270021449 100644 --- a/include/uapi/linux/aio_abi.h +++ b/include/uapi/linux/aio_abi.h @@ -31,7 +31,7 @@ #include <linux/fs.h> #include <asm/byteorder.h> -typedef __kernel_ulong_t aio_context_t; +typedef void __user *aio_context_t; enum { IOCB_CMD_PREAD = 0,