git: 5171ed79f6d1 - main - linux(4): Copyout pselect timeout.
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Tue, 26 Apr 2022 16:37:15 UTC
The branch main has been updated by dchagin:
URL: https://cgit.FreeBSD.org/src/commit/?id=5171ed79f6d1fc3948a7ebfb32b02d698224c29b
commit 5171ed79f6d1fc3948a7ebfb32b02d698224c29b
Author: Dmitry Chagin <dchagin@FreeBSD.org>
AuthorDate: 2022-04-26 16:35:56 +0000
Commit: Dmitry Chagin <dchagin@FreeBSD.org>
CommitDate: 2022-04-26 16:35:56 +0000
linux(4): Copyout pselect timeout.
According to pselect6 manual, on error timeout becomes undefined, by fact
Linux modifies the timeout and ignore EFAULT error if so.
MFC after: 2 weeks
---
sys/compat/linux/linux_misc.c | 46 ++++++++++++++++++-------------------------
1 file changed, 19 insertions(+), 27 deletions(-)
diff --git a/sys/compat/linux/linux_misc.c b/sys/compat/linux/linux_misc.c
index 252c6e0737c0..8a9e34d6cae3 100644
--- a/sys/compat/linux/linux_misc.c
+++ b/sys/compat/linux/linux_misc.c
@@ -2379,7 +2379,7 @@ linux_pselect6(struct thread *td, struct linux_pselect6_args *args)
{
struct l_timespec lts;
struct timespec ts, *tsp;
- int error;
+ int error, error2;
if (args->tsp != NULL) {
error = copyin(args->tsp, <s, sizeof(lts));
@@ -2394,13 +2394,11 @@ linux_pselect6(struct thread *td, struct linux_pselect6_args *args)
error = linux_common_pselect6(td, args->nfds, args->readfds,
args->writefds, args->exceptfds, tsp, args->sig);
- if (error != 0)
- return (error);
if (args->tsp != NULL) {
- error = native_to_linux_timespec(<s, tsp);
- if (error == 0)
- error = copyout(<s, args->tsp, sizeof(lts));
+ error2 = native_to_linux_timespec(<s, tsp);
+ if (error2 == 0)
+ copyout(<s, args->tsp, sizeof(lts));
}
return (error);
}
@@ -2452,21 +2450,17 @@ linux_common_pselect6(struct thread *td, l_int nfds, l_fd_set *readfds,
error = kern_pselect(td, nfds, readfds, writefds,
exceptfds, tvp, ssp, LINUX_NFDBITS);
- if (error == 0 && tsp != NULL) {
- if (td->td_retval[0] != 0) {
- /*
- * Compute how much time was left of the timeout,
- * by subtracting the current time and the time
- * before we started the call, and subtracting
- * that result from the user-supplied value.
- */
-
- microtime(&tv1);
- timevalsub(&tv1, &tv0);
- timevalsub(&utv, &tv1);
- if (utv.tv_sec < 0)
- timevalclear(&utv);
- } else
+ if (tsp != NULL) {
+ /*
+ * Compute how much time was left of the timeout,
+ * by subtracting the current time and the time
+ * before we started the call, and subtracting
+ * that result from the user-supplied value.
+ */
+ microtime(&tv1);
+ timevalsub(&tv1, &tv0);
+ timevalsub(&utv, &tv1);
+ if (utv.tv_sec < 0)
timevalclear(&utv);
TIMEVAL_TO_TIMESPEC(&utv, tsp);
}
@@ -2480,7 +2474,7 @@ linux_pselect6_time64(struct thread *td,
{
struct l_timespec64 lts;
struct timespec ts, *tsp;
- int error;
+ int error, error2;
if (args->tsp != NULL) {
error = copyin(args->tsp, <s, sizeof(lts));
@@ -2495,13 +2489,11 @@ linux_pselect6_time64(struct thread *td,
error = linux_common_pselect6(td, args->nfds, args->readfds,
args->writefds, args->exceptfds, tsp, args->sig);
- if (error != 0)
- return (error);
if (args->tsp != NULL) {
- error = native_to_linux_timespec64(<s, tsp);
- if (error == 0)
- error = copyout(<s, args->tsp, sizeof(lts));
+ error2 = native_to_linux_timespec64(<s, tsp);
+ if (error2 == 0)
+ copyout(<s, args->tsp, sizeof(lts));
}
return (error);
}