From: Willem de Bruijn <willemb@xxxxxxxxxx> io_pgetevents has four variants, including compat variants of both timespec and sigmask. With set_maybe_compat_user_sigmask helper, the latter can be deduplicated. Move the shared logic to new do_io_pgetevents, analogous to do_io_getevents. Signed-off-by: Willem de Bruijn <willemb@xxxxxxxxxx> Cc: Benjamin LaHaise <bcrl@xxxxxxxxx> --- fs/aio.c | 94 ++++++++++++++++++++++---------------------------------- 1 file changed, 37 insertions(+), 57 deletions(-) diff --git a/fs/aio.c b/fs/aio.c index d213be7b8a7e..56460ab47d64 100644 --- a/fs/aio.c +++ b/fs/aio.c @@ -2101,6 +2101,31 @@ struct __aio_sigset { size_t sigsetsize; }; +static long do_io_pgetevents(aio_context_t ctx_id, + long min_nr, + long nr, + struct io_event __user *events, + struct timespec64 *ts, + const void __user *umask, + size_t sigsetsize) +{ + bool interrupted; + int ret; + + ret = set_maybe_compat_user_sigmask(umask, sigsetsize); + if (ret) + return ret; + + ret = do_io_getevents(ctx_id, min_nr, nr, events, ts); + + interrupted = signal_pending(current); + restore_saved_sigmask_unless(interrupted); + if (interrupted && !ret) + ret = -ERESTARTNOHAND; + + return ret; +} + SYSCALL_DEFINE6(io_pgetevents, aio_context_t, ctx_id, long, min_nr, @@ -2111,8 +2136,6 @@ SYSCALL_DEFINE6(io_pgetevents, { struct __aio_sigset ksig = { NULL, }; struct timespec64 ts; - bool interrupted; - int ret; if (timeout && unlikely(get_timespec64(&ts, timeout))) return -EFAULT; @@ -2120,18 +2143,9 @@ SYSCALL_DEFINE6(io_pgetevents, if (usig && copy_from_user(&ksig, usig, sizeof(ksig))) return -EFAULT; - ret = set_user_sigmask(ksig.sigmask, ksig.sigsetsize); - if (ret) - return ret; - - ret = do_io_getevents(ctx_id, min_nr, nr, events, timeout ? &ts : NULL); - - interrupted = signal_pending(current); - restore_saved_sigmask_unless(interrupted); - if (interrupted && !ret) - ret = -ERESTARTNOHAND; - - return ret; + return do_io_pgetevents(ctx_id, min_nr, nr, events, + timeout ? &ts : NULL, + ksig.sigmask, ksig.sigsetsize); } #if defined(CONFIG_COMPAT_32BIT_TIME) && !defined(CONFIG_64BIT) @@ -2146,8 +2160,6 @@ SYSCALL_DEFINE6(io_pgetevents_time32, { struct __aio_sigset ksig = { NULL, }; struct timespec64 ts; - bool interrupted; - int ret; if (timeout && unlikely(get_old_timespec32(&ts, timeout))) return -EFAULT; @@ -2155,19 +2167,9 @@ SYSCALL_DEFINE6(io_pgetevents_time32, if (usig && copy_from_user(&ksig, usig, sizeof(ksig))) return -EFAULT; - - ret = set_user_sigmask(ksig.sigmask, ksig.sigsetsize); - if (ret) - return ret; - - ret = do_io_getevents(ctx_id, min_nr, nr, events, timeout ? &ts : NULL); - - interrupted = signal_pending(current); - restore_saved_sigmask_unless(interrupted); - if (interrupted && !ret) - ret = -ERESTARTNOHAND; - - return ret; + return do_io_pgetevents(ctx_id, min_nr, nr, events, + timeout ? &ts : NULL, + ksig.sigmask, ksig.sigsetsize); } #endif @@ -2213,8 +2215,6 @@ COMPAT_SYSCALL_DEFINE6(io_pgetevents, { struct __compat_aio_sigset ksig = { 0, }; struct timespec64 t; - bool interrupted; - int ret; if (timeout && get_old_timespec32(&t, timeout)) return -EFAULT; @@ -2222,18 +2222,9 @@ COMPAT_SYSCALL_DEFINE6(io_pgetevents, if (usig && copy_from_user(&ksig, usig, sizeof(ksig))) return -EFAULT; - ret = set_compat_user_sigmask(compat_ptr(ksig.sigmask), ksig.sigsetsize); - if (ret) - return ret; - - ret = do_io_getevents(ctx_id, min_nr, nr, events, timeout ? &t : NULL); - - interrupted = signal_pending(current); - restore_saved_sigmask_unless(interrupted); - if (interrupted && !ret) - ret = -ERESTARTNOHAND; - - return ret; + return do_io_pgetevents(ctx_id, min_nr, nr, events, + timeout ? &t : NULL, + compat_ptr(ksig.sigmask), ksig.sigsetsize); } #endif @@ -2248,8 +2239,6 @@ COMPAT_SYSCALL_DEFINE6(io_pgetevents_time64, { struct __compat_aio_sigset ksig = { 0, }; struct timespec64 t; - bool interrupted; - int ret; if (timeout && get_timespec64(&t, timeout)) return -EFAULT; @@ -2257,17 +2246,8 @@ COMPAT_SYSCALL_DEFINE6(io_pgetevents_time64, if (usig && copy_from_user(&ksig, usig, sizeof(ksig))) return -EFAULT; - ret = set_compat_user_sigmask(compat_ptr(ksig.sigmask), ksig.sigsetsize); - if (ret) - return ret; - - ret = do_io_getevents(ctx_id, min_nr, nr, events, timeout ? &t : NULL); - - interrupted = signal_pending(current); - restore_saved_sigmask_unless(interrupted); - if (interrupted && !ret) - ret = -ERESTARTNOHAND; - - return ret; + return do_io_pgetevents(ctx_id, min_nr, nr, events, + timeout ? &t : NULL, + compat_ptr(ksig.sigmask), ksig.sigsetsize); } #endif -- 2.30.0.284.gd98b1dd5eaa7-goog