git: 573a0f3e6830 - stable/13 - linux(4): Add a helper intended for copying timespec's from the userspace.
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Fri, 17 Jun 2022 19:40:05 UTC
The branch stable/13 has been updated by dchagin: URL: https://cgit.FreeBSD.org/src/commit/?id=573a0f3e6830381f3bba40559e14f9c369cbfc2f commit 573a0f3e6830381f3bba40559e14f9c369cbfc2f Author: Dmitry Chagin <dchagin@FreeBSD.org> AuthorDate: 2022-05-08 13:16:47 +0000 Commit: Dmitry Chagin <dchagin@FreeBSD.org> CommitDate: 2022-06-17 19:34:59 +0000 linux(4): Add a helper intended for copying timespec's from the userspace. There are many places where we copyin Linux timespec from the userspace and then convert it to the kernel timespec. To avoid code duplication add a tiny halper for doing this. MFC after: 2 weeks (cherry picked from commit 707e567a4061669b7643ddbe8a1ad9c4e6545a75) --- sys/compat/linux/linux_event.c | 10 ++---- sys/compat/linux/linux_futex.c | 12 ++----- sys/compat/linux/linux_ipc.c | 10 ++---- sys/compat/linux/linux_misc.c | 24 +++----------- sys/compat/linux/linux_signal.c | 10 ++---- sys/compat/linux/linux_socket.c | 12 ++----- sys/compat/linux/linux_time.c | 73 ++++++++++++++++------------------------- sys/compat/linux/linux_timer.h | 4 +++ 8 files changed, 47 insertions(+), 108 deletions(-) diff --git a/sys/compat/linux/linux_event.c b/sys/compat/linux/linux_event.c index 1ac1052def7b..05df4401dbab 100644 --- a/sys/compat/linux/linux_event.c +++ b/sys/compat/linux/linux_event.c @@ -540,7 +540,6 @@ int linux_epoll_pwait2_64(struct thread *td, struct linux_epoll_pwait2_64_args *args) { struct timespec ts, *tsa; - struct l_timespec64 lts; sigset_t mask, *pmask; int error; @@ -550,9 +549,7 @@ linux_epoll_pwait2_64(struct thread *td, struct linux_epoll_pwait2_64_args *args return (error); if (args->timeout) { - if ((error = copyin(args->timeout, <s, sizeof(lts)))) - return (error); - error = linux_to_native_timespec64(&ts, <s); + error = linux_get_timespec64(&ts, args->timeout); if (error != 0) return (error); tsa = &ts; @@ -567,7 +564,6 @@ int linux_epoll_pwait2(struct thread *td, struct linux_epoll_pwait2_args *args) { struct timespec ts, *tsa; - struct l_timespec lts; sigset_t mask, *pmask; int error; @@ -577,9 +573,7 @@ linux_epoll_pwait2(struct thread *td, struct linux_epoll_pwait2_args *args) return (error); if (args->timeout) { - if ((error = copyin(args->timeout, <s, sizeof(lts)))) - return (error); - error = linux_to_native_timespec(&ts, <s); + error = linux_get_timespec(&ts, args->timeout); if (error != 0) return (error); tsa = &ts; diff --git a/sys/compat/linux/linux_futex.c b/sys/compat/linux/linux_futex.c index a194e0ac7962..5591b4fc3234 100644 --- a/sys/compat/linux/linux_futex.c +++ b/sys/compat/linux/linux_futex.c @@ -816,7 +816,6 @@ linux_sys_futex(struct thread *td, struct linux_sys_futex_args *args) .val3 = args->val3, .val3_compare = true, }; - struct l_timespec lts; int error; switch (args->op & LINUX_FUTEX_CMD_MASK) { @@ -825,10 +824,7 @@ linux_sys_futex(struct thread *td, struct linux_sys_futex_args *args) case LINUX_FUTEX_LOCK_PI: case LINUX_FUTEX_LOCK_PI2: if (args->timeout != NULL) { - error = copyin(args->timeout, <s, sizeof(lts)); - if (error != 0) - return (error); - error = linux_to_native_timespec(&fargs.kts, <s); + error = linux_get_timespec(&fargs.kts, args->timeout); if (error != 0) return (error); fargs.ts = &fargs.kts; @@ -854,7 +850,6 @@ linux_sys_futex_time64(struct thread *td, .val3 = args->val3, .val3_compare = true, }; - struct l_timespec64 lts; int error; switch (args->op & LINUX_FUTEX_CMD_MASK) { @@ -863,10 +858,7 @@ linux_sys_futex_time64(struct thread *td, case LINUX_FUTEX_LOCK_PI: case LINUX_FUTEX_LOCK_PI2: if (args->timeout != NULL) { - error = copyin(args->timeout, <s, sizeof(lts)); - if (error != 0) - return (error); - error = linux_to_native_timespec64(&fargs.kts, <s); + error = linux_get_timespec64(&fargs.kts, args->timeout); if (error != 0) return (error); fargs.ts = &fargs.kts; diff --git a/sys/compat/linux/linux_ipc.c b/sys/compat/linux/linux_ipc.c index 51bf18dcd097..258917e6a969 100644 --- a/sys/compat/linux/linux_ipc.c +++ b/sys/compat/linux/linux_ipc.c @@ -510,13 +510,10 @@ int linux_semtimedop_time64(struct thread *td, struct linux_semtimedop_time64_args *args) { struct timespec ts, *tsa; - struct l_timespec64 lts; int error; if (args->timeout) { - if ((error = copyin(args->timeout, <s, sizeof(lts)))) - return (error); - error = linux_to_native_timespec64(&ts, <s); + error = linux_get_timespec64(&ts, args->timeout); if (error != 0) return (error); tsa = &ts; @@ -532,13 +529,10 @@ int linux_semtimedop(struct thread *td, struct linux_semtimedop_args *args) { struct timespec ts, *tsa; - struct l_timespec lts; int error; if (args->timeout) { - if ((error = copyin(args->timeout, <s, sizeof(lts)))) - return (error); - error = linux_to_native_timespec(&ts, <s); + error = linux_get_timespec(&ts, args->timeout); if (error != 0) return (error); tsa = &ts; diff --git a/sys/compat/linux/linux_misc.c b/sys/compat/linux/linux_misc.c index d43289786611..96555f2e8d04 100644 --- a/sys/compat/linux/linux_misc.c +++ b/sys/compat/linux/linux_misc.c @@ -2387,15 +2387,11 @@ linux_prlimit64(struct thread *td, struct linux_prlimit64_args *args) int linux_pselect6(struct thread *td, struct linux_pselect6_args *args) { - struct l_timespec lts; struct timespec ts, *tsp; int error; if (args->tsp != NULL) { - error = copyin(args->tsp, <s, sizeof(lts)); - if (error != 0) - return (error); - error = linux_to_native_timespec(&ts, <s); + error = linux_get_timespec(&ts, args->tsp); if (error != 0) return (error); tsp = &ts; @@ -2479,15 +2475,11 @@ int linux_pselect6_time64(struct thread *td, struct linux_pselect6_time64_args *args) { - struct l_timespec64 lts; struct timespec ts, *tsp; int error; if (args->tsp != NULL) { - error = copyin(args->tsp, <s, sizeof(lts)); - if (error != 0) - return (error); - error = linux_to_native_timespec64(&ts, <s); + error = linux_get_timespec64(&ts, args->tsp); if (error != 0) return (error); tsp = &ts; @@ -2507,14 +2499,10 @@ int linux_ppoll(struct thread *td, struct linux_ppoll_args *args) { struct timespec uts, *tsp; - struct l_timespec lts; int error; if (args->tsp != NULL) { - error = copyin(args->tsp, <s, sizeof(lts)); - if (error) - return (error); - error = linux_to_native_timespec(&uts, <s); + error = linux_get_timespec(&uts, args->tsp); if (error != 0) return (error); tsp = &uts; @@ -2589,14 +2577,10 @@ int linux_ppoll_time64(struct thread *td, struct linux_ppoll_time64_args *args) { struct timespec uts, *tsp; - struct l_timespec64 lts; int error; if (args->tsp != NULL) { - error = copyin(args->tsp, <s, sizeof(lts)); - if (error != 0) - return (error); - error = linux_to_native_timespec64(&uts, <s); + error = linux_get_timespec64(&uts, args->tsp); if (error != 0) return (error); tsp = &uts; diff --git a/sys/compat/linux/linux_signal.c b/sys/compat/linux/linux_signal.c index 0848040d009c..a9af0d726f56 100644 --- a/sys/compat/linux/linux_signal.c +++ b/sys/compat/linux/linux_signal.c @@ -436,13 +436,10 @@ linux_rt_sigtimedwait(struct thread *td, struct linux_rt_sigtimedwait_args *args) { struct timespec ts, *tsa; - struct l_timespec lts; int error; if (args->timeout) { - if ((error = copyin(args->timeout, <s, sizeof(lts)))) - return (error); - error = linux_to_native_timespec(&ts, <s); + error = linux_get_timespec(&ts, args->timeout); if (error != 0) return (error); tsa = &ts; @@ -490,13 +487,10 @@ linux_rt_sigtimedwait_time64(struct thread *td, struct linux_rt_sigtimedwait_time64_args *args) { struct timespec ts, *tsa; - struct l_timespec64 lts; int error; if (args->timeout) { - if ((error = copyin(args->timeout, <s, sizeof(lts)))) - return (error); - error = linux_to_native_timespec64(&ts, <s); + error = linux_get_timespec64(&ts, args->timeout); if (error != 0) return (error); tsa = &ts; diff --git a/sys/compat/linux/linux_socket.c b/sys/compat/linux/linux_socket.c index 93b5cea7ecc3..b5ec32835981 100644 --- a/sys/compat/linux/linux_socket.c +++ b/sys/compat/linux/linux_socket.c @@ -1786,15 +1786,11 @@ linux_recvmmsg_common(struct thread *td, l_int s, struct l_mmsghdr *msg, int linux_recvmmsg(struct thread *td, struct linux_recvmmsg_args *args) { - struct l_timespec lts; struct timespec ts, tts, *ptts; int error; if (args->timeout) { - error = copyin(args->timeout, <s, sizeof(struct l_timespec)); - if (error != 0) - return (error); - error = linux_to_native_timespec(&ts, <s); + error = linux_get_timespec(&ts, args->timeout); if (error != 0) return (error); getnanotime(&tts); @@ -1811,15 +1807,11 @@ linux_recvmmsg(struct thread *td, struct linux_recvmmsg_args *args) int linux_recvmmsg_time64(struct thread *td, struct linux_recvmmsg_time64_args *args) { - struct l_timespec64 lts; struct timespec ts, tts, *ptts; int error; if (args->timeout) { - error = copyin(args->timeout, <s, sizeof(struct l_timespec)); - if (error != 0) - return (error); - error = linux_to_native_timespec64(&ts, <s); + error = linux_get_timespec64(&ts, args->timeout); if (error != 0) return (error); getnanotime(&tts); diff --git a/sys/compat/linux/linux_time.c b/sys/compat/linux/linux_time.c index 0f1af6b3a5cf..0be7025abe05 100644 --- a/sys/compat/linux/linux_time.c +++ b/sys/compat/linux/linux_time.c @@ -101,16 +101,13 @@ LIN_SDT_PROBE_DEFINE1(time, linux_clock_getres, copyout_error, "int"); #if defined(__i386__) || (defined(__amd64__) && defined(COMPAT_LINUX32)) LIN_SDT_PROBE_DEFINE1(time, linux_clock_getres_time64, copyout_error, "int"); #endif -LIN_SDT_PROBE_DEFINE1(time, linux_nanosleep, conversion_error, "int"); LIN_SDT_PROBE_DEFINE1(time, linux_nanosleep, copyout_error, "int"); LIN_SDT_PROBE_DEFINE1(time, linux_nanosleep, copyin_error, "int"); -LIN_SDT_PROBE_DEFINE1(time, linux_clock_nanosleep, conversion_error, "int"); LIN_SDT_PROBE_DEFINE1(time, linux_clock_nanosleep, copyout_error, "int"); LIN_SDT_PROBE_DEFINE1(time, linux_clock_nanosleep, copyin_error, "int"); LIN_SDT_PROBE_DEFINE1(time, linux_common_clock_nanosleep, unsupported_flags, "int"); LIN_SDT_PROBE_DEFINE1(time, linux_common_clock_nanosleep, unsupported_clockid, "int"); #if defined(__i386__) || (defined(__amd64__) && defined(COMPAT_LINUX32)) -LIN_SDT_PROBE_DEFINE1(time, linux_clock_nanosleep_time64, conversion_error, "int"); LIN_SDT_PROBE_DEFINE1(time, linux_clock_nanosleep_time64, copyout_error, "int"); LIN_SDT_PROBE_DEFINE1(time, linux_clock_nanosleep_time64, copyin_error, "int"); #endif @@ -162,6 +159,18 @@ linux_put_timespec(struct timespec *ntp, struct l_timespec *ltp) return (copyout(<s, ltp, sizeof(lts))); } +int +linux_get_timespec(struct timespec *ntp, const struct l_timespec *ultp) +{ + struct l_timespec lts; + int error; + + error = copyin(ultp, <s, sizeof(lts)); + if (error != 0) + return (error); + return (linux_to_native_timespec(ntp, <s)); +} + #if defined(__i386__) || (defined(__amd64__) && defined(COMPAT_LINUX32)) int native_to_linux_timespec64(struct l_timespec64 *ltp64, struct timespec *ntp) @@ -203,6 +212,18 @@ linux_put_timespec64(struct timespec *ntp, struct l_timespec64 *ltp) return (error); return (copyout(<s, ltp, sizeof(lts))); } + +int +linux_get_timespec64(struct timespec *ntp, const struct l_timespec64 *ultp) +{ + struct l_timespec64 lts; + int error; + + error = copyin(ultp, <s, sizeof(lts)); + if (error != 0) + return (error); + return (linux_to_native_timespec64(ntp, <s)); +} #endif int @@ -508,19 +529,13 @@ int linux_clock_settime(struct thread *td, struct linux_clock_settime_args *args) { struct timespec ts; - struct l_timespec lts; int error; - error = copyin(args->tp, <s, sizeof(lts)); + error = linux_get_timespec(&ts, args->tp); if (error != 0) { LIN_SDT_PROBE1(time, linux_clock_settime, copyin_error, error); return (error); } - error = linux_to_native_timespec(&ts, <s); - if (error != 0) - LIN_SDT_PROBE1(time, linux_clock_settime, conversion_error, - error); - return (linux_common_clock_settime(td, args->which, &ts)); } @@ -529,18 +544,13 @@ int linux_clock_settime64(struct thread *td, struct linux_clock_settime64_args *args) { struct timespec ts; - struct l_timespec64 lts; int error; - error = copyin(args->tp, <s, sizeof(lts)); + error = linux_get_timespec64(&ts, args->tp); if (error != 0) { LIN_SDT_PROBE1(time, linux_clock_settime64, copyin_error, error); return (error); } - error = linux_to_native_timespec64(&ts, <s); - if (error != 0) - LIN_SDT_PROBE1(time, linux_clock_settime64, conversion_error, - error); return (linux_common_clock_settime(td, args->which, &ts)); } #endif @@ -680,26 +690,19 @@ int linux_nanosleep(struct thread *td, struct linux_nanosleep_args *args) { struct timespec *rmtp; - struct l_timespec lrqts; struct timespec rqts, rmts; int error, error2; - error = copyin(args->rqtp, &lrqts, sizeof lrqts); + error = linux_get_timespec(&rqts, args->rqtp); if (error != 0) { LIN_SDT_PROBE1(time, linux_nanosleep, copyin_error, error); return (error); } - if (args->rmtp != NULL) rmtp = &rmts; else rmtp = NULL; - error = linux_to_native_timespec(&rqts, &lrqts); - if (error != 0) { - LIN_SDT_PROBE1(time, linux_nanosleep, conversion_error, error); - return (error); - } error = kern_nanosleep(td, &rqts, rmtp); if (error == EINTR && args->rmtp != NULL) { error2 = linux_put_timespec(rmtp, args->rmtp); @@ -746,24 +749,15 @@ linux_clock_nanosleep(struct thread *td, struct linux_clock_nanosleep_args *args) { struct timespec *rmtp; - struct l_timespec lrqts; struct timespec rqts, rmts; int error, error2; - error = copyin(args->rqtp, &lrqts, sizeof(lrqts)); + error = linux_get_timespec(&rqts, args->rqtp); if (error != 0) { LIN_SDT_PROBE1(time, linux_clock_nanosleep, copyin_error, error); return (error); } - - error = linux_to_native_timespec(&rqts, &lrqts); - if (error != 0) { - LIN_SDT_PROBE1(time, linux_clock_nanosleep, conversion_error, - error); - return (error); - } - if (args->rmtp != NULL) rmtp = &rmts; else @@ -789,24 +783,15 @@ linux_clock_nanosleep_time64(struct thread *td, struct linux_clock_nanosleep_time64_args *args) { struct timespec *rmtp; - struct l_timespec64 lrqts; struct timespec rqts, rmts; int error, error2; - error = copyin(args->rqtp, &lrqts, sizeof(lrqts)); + error = linux_get_timespec64(&rqts, args->rqtp); if (error != 0) { LIN_SDT_PROBE1(time, linux_clock_nanosleep_time64, copyin_error, error); return (error); } - - error = linux_to_native_timespec64(&rqts, &lrqts); - if (error != 0) { - LIN_SDT_PROBE1(time, linux_clock_nanosleep_time64, - conversion_error, error); - return (error); - } - if (args->rmtp != NULL) rmtp = &rmts; else diff --git a/sys/compat/linux/linux_timer.h b/sys/compat/linux/linux_timer.h index edff6c845032..b9f877cc83a4 100644 --- a/sys/compat/linux/linux_timer.h +++ b/sys/compat/linux/linux_timer.h @@ -117,6 +117,8 @@ int linux_to_native_timespec(struct timespec *, struct l_timespec *); int linux_put_timespec(struct timespec *, struct l_timespec *); +int linux_get_timespec(struct timespec *, + const struct l_timespec *); #if defined(__i386__) || (defined(__amd64__) && defined(COMPAT_LINUX32)) int native_to_linux_timespec64(struct l_timespec64 *, struct timespec *); @@ -124,6 +126,8 @@ int linux_to_native_timespec64(struct timespec *, struct l_timespec64 *); int linux_put_timespec64(struct timespec *, struct l_timespec64 *); +int linux_get_timespec64(struct timespec *, + const struct l_timespec64 *); #endif int linux_to_native_clockid(clockid_t *, clockid_t); int native_to_linux_itimerspec(struct l_itimerspec *,