xenomai.lists.linux.dev archive mirror
 help / color / mirror / Atom feed
From: Florian Bezdeka <florian.bezdeka@siemens.com>
To: jan.kiszka@siemens.com, xenomai@lists.linux.dev
Cc: Florian Bezdeka <florian.bezdeka@siemens.com>
Subject: [PATCH 1/3] y2038: cobalt/posix/select: Refactor __cobalt_select()
Date: Wed, 17 May 2023 11:34:40 +0200	[thread overview]
Message-ID: <20230516-florian-y2038-part-three-v1-1-b140278b26c6@siemens.com> (raw)
In-Reply-To: <20230516-florian-y2038-part-three-v1-0-b140278b26c6@siemens.com>

There is no y2038 safe select() syscall provided by Linuy. If y2038
safety is required the application should not use select() and move on
to something like pselect().

As we still want to support select() for keeping backward compatibility
- even if y2038 safety is requested - an additional pselect() based
entry will be introduced soon which will re-use __cobalt_select().

This patch moves all the timeout related userspace copy operations out
of __cobalt_select() and migrates __cobalt_select() to
struct timespec64. That will allow pselect64() to be based on
__cobalt_select() as well.

Signed-off-by: Florian Bezdeka <florian.bezdeka@siemens.com>
---
 .../cobalt/include/asm-generic/xenomai/syscall.h   | 22 ++++++++
 kernel/cobalt/posix/clock.h                        |  6 +--
 kernel/cobalt/posix/io.c                           | 62 +++++++++++-----------
 kernel/cobalt/posix/syscall32.c                    | 24 ++++++++-
 4 files changed, 78 insertions(+), 36 deletions(-)

diff --git a/kernel/cobalt/include/asm-generic/xenomai/syscall.h b/kernel/cobalt/include/asm-generic/xenomai/syscall.h
index 70b3e68f9..d61b985fb 100644
--- a/kernel/cobalt/include/asm-generic/xenomai/syscall.h
+++ b/kernel/cobalt/include/asm-generic/xenomai/syscall.h
@@ -138,6 +138,28 @@ static inline int cobalt_put_u_itimerspec(
 	return cobalt_copy_to_user(dst, &u_its, sizeof(*dst));
 }
 
+static inline struct timespec64
+cobalt_timeval_to_timespec64(const struct __kernel_old_timeval *src)
+{
+	struct timespec64 ts;
+
+	ts.tv_sec = src->tv_sec + (src->tv_usec / USEC_PER_SEC);
+	ts.tv_nsec = (src->tv_usec % USEC_PER_SEC) * NSEC_PER_USEC;
+
+	return ts;
+}
+
+static inline struct __kernel_old_timeval
+cobalt_timespec64_to_timeval(const struct timespec64 *src)
+{
+	struct __kernel_old_timeval tv;
+
+	tv.tv_sec = src->tv_sec + (src->tv_nsec / NSEC_PER_SEC);
+	tv.tv_usec = (src->tv_nsec % NSEC_PER_SEC) / NSEC_PER_USEC;
+
+	return tv;
+}
+
 /* 32bit syscall emulation */
 #define __COBALT_COMPAT_BIT	0x1
 /* 32bit syscall emulation - extended form */
diff --git a/kernel/cobalt/posix/clock.h b/kernel/cobalt/posix/clock.h
index dbaabbc5d..38b59e24f 100644
--- a/kernel/cobalt/posix/clock.h
+++ b/kernel/cobalt/posix/clock.h
@@ -68,12 +68,12 @@ static inline xnticks_t tv2ns(const struct __kernel_old_timeval *tv)
 	return nsecs;
 }
 
-static inline void ticks2tv(struct __kernel_old_timeval *tv, xnticks_t ticks)
+static inline void ticks2ts64(struct timespec64 *ts, xnticks_t ticks)
 {
 	unsigned long nsecs;
 
-	tv->tv_sec = xnclock_divrem_billion(ticks, &nsecs);
-	tv->tv_usec = nsecs / 1000;
+	ts->tv_sec = xnclock_divrem_billion(ticks, &nsecs);
+	ts->tv_nsec = nsecs;
 }
 
 static inline xnticks_t clock_get_ticks(clockid_t clock_id)
diff --git a/kernel/cobalt/posix/io.c b/kernel/cobalt/posix/io.c
index 45ec09fae..ebe7791ab 100644
--- a/kernel/cobalt/posix/io.c
+++ b/kernel/cobalt/posix/io.c
@@ -221,7 +221,7 @@ static int __cobalt_select_bind_all(struct xnselector *selector,
 }
 
 int __cobalt_select(int nfds, void __user *u_rfds, void __user *u_wfds,
-		    void __user *u_xfds, void __user *u_tv, bool compat)
+		    void __user *u_xfds, struct timespec64 *to, bool compat)
 {
 	void __user *ufd_sets[XNSELECT_MAX_TYPES] = {
 		[XNSELECT_READ] = u_rfds,
@@ -237,13 +237,12 @@ int __cobalt_select(int nfds, void __user *u_rfds, void __user *u_wfds,
 	xntmode_t mode = XN_RELATIVE;
 	struct xnselector *selector;
 	struct xnthread *curr;
-	struct __kernel_old_timeval tv;
 	size_t fds_size;
 	int i, err;
 
 	curr = xnthread_current();
 
-	if (u_tv) {
+	if (to) {
 		if (xnthread_test_localinfo(curr, XNSYSRST)) {
 			xnthread_clear_localinfo(curr, XNSYSRST);
 
@@ -255,23 +254,11 @@ int __cobalt_select(int nfds, void __user *u_rfds, void __user *u_wfds,
 				goto out;
 			}
 		} else {
-#ifdef CONFIG_XENO_ARCH_SYS3264
-			if (compat) {
-				if (sys32_get_timeval(&tv, u_tv))
-					return -EFAULT;
-			} else
-#endif
-			{
-				if (!access_ok(u_tv, sizeof(tv))
-				    || cobalt_copy_from_user(&tv, u_tv,
-							     sizeof(tv)))
-					return -EFAULT;
-			}
 
-			if (tv.tv_usec >= 1000000)
+			if (!timespec64_valid(to))
 				return -EINVAL;
 
-			timeout = clock_get_ticks(CLOCK_MONOTONIC) + tv2ns(&tv);
+			timeout = clock_get_ticks(CLOCK_MONOTONIC) + ts2ns(to);
 		}
 
 		mode = XN_ABSOLUTE;
@@ -343,23 +330,12 @@ int __cobalt_select(int nfds, void __user *u_rfds, void __user *u_wfds,
 	}
 
 out:
-	if (u_tv && (err > 0 || err == -EINTR)) {
+	if (to && (err > 0 || err == -EINTR)) {
 		xnsticks_t diff = timeout - clock_get_ticks(CLOCK_MONOTONIC);
 		if (diff > 0)
-			ticks2tv(&tv, diff);
+			ticks2ts64(to, diff);
 		else
-			tv.tv_sec = tv.tv_usec = 0;
-
-#ifdef CONFIG_XENO_ARCH_SYS3264
-		if (compat) {
-			if (sys32_put_timeval(u_tv, &tv))
-				return -EFAULT;
-		} else
-#endif
-		{
-			if (cobalt_copy_to_user(u_tv, &tv, sizeof(tv)))
-				return -EFAULT;
-		}
+			to->tv_sec = to->tv_nsec = 0;
 	}
 
 	if (err >= 0)
@@ -390,5 +366,27 @@ COBALT_SYSCALL(select, primary,
 		fd_set __user *u_xfds,
 		struct __kernel_old_timeval __user *u_tv))
 {
-	return __cobalt_select(nfds, u_rfds, u_wfds, u_xfds, u_tv, false);
+	struct timespec64 ts64, *to = NULL;
+	struct __kernel_old_timeval tv;
+	int ret;
+
+	if (u_tv && (!access_ok(u_tv, sizeof(tv)) ||
+		     cobalt_copy_from_user(&tv, u_tv, sizeof(tv))))
+		return -EFAULT;
+
+	if (u_tv) {
+		ts64 = cobalt_timeval_to_timespec64(&tv);
+		to = &ts64;
+	}
+
+	ret = __cobalt_select(nfds, u_rfds, u_wfds, u_xfds, to, false);
+	if (ret)
+		return ret;
+
+	if (u_tv) {
+		tv = cobalt_timespec64_to_timeval(to);
+		ret = cobalt_copy_to_user(u_tv, &tv, sizeof(tv));
+	}
+
+	return ret;
 }
diff --git a/kernel/cobalt/posix/syscall32.c b/kernel/cobalt/posix/syscall32.c
index 10b080dfd..466534f4c 100644
--- a/kernel/cobalt/posix/syscall32.c
+++ b/kernel/cobalt/posix/syscall32.c
@@ -749,7 +749,29 @@ COBALT_SYSCALL32emu(select, primary,
 		     compat_fd_set __user *u_xfds,
 		     struct old_timeval32 __user *u_tv))
 {
-	return __cobalt_select(nfds, u_rfds, u_wfds, u_xfds, u_tv, true);
+	struct timespec64 ts64, *to = NULL;
+	struct __kernel_old_timeval tv;
+	int ret;
+
+	if (u_tv &&
+	    (!access_ok(u_tv, sizeof(tv)) || sys32_get_timeval(&tv, u_tv)))
+		return -EFAULT;
+
+	if (u_tv) {
+		ts64 = cobalt_timeval_to_timespec64(&tv);
+		to = &ts64;
+	}
+
+	ret = __cobalt_select(nfds, u_rfds, u_wfds, u_xfds, to, true);
+	if (ret)
+		return ret;
+
+	if (u_tv) {
+		tv = cobalt_timespec64_to_timeval(to);
+		ret = sys32_put_timeval(u_tv, &tv);
+	}
+
+	return ret;
 }
 
 COBALT_SYSCALL32emu(recvmsg, handover,

-- 
2.39.2


  reply	other threads:[~2023-05-17  9:34 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-05-17  9:34 [PATCH 0/3] y2038: Part three - support for select() Florian Bezdeka
2023-05-17  9:34 ` Florian Bezdeka [this message]
2023-05-17  9:34 ` [PATCH 2/3] y2038: cobalt/posix/select: Adding pselect64 Florian Bezdeka
2023-05-17  9:34 ` [PATCH 3/3] y2038: testsuite/smokey/y2038: Adding tests for pselect64 Florian Bezdeka
2023-05-17 11:01 ` [PATCH 0/3] y2038: Part three - support for select() Jan Kiszka
2023-05-21 10:07   ` Florian Bezdeka
2023-05-23  9:13     ` Jan Kiszka

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20230516-florian-y2038-part-three-v1-1-b140278b26c6@siemens.com \
    --to=florian.bezdeka@siemens.com \
    --cc=jan.kiszka@siemens.com \
    --cc=xenomai@lists.linux.dev \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).