From nobody Sat May 28 20:53:24 2022
X-Original-To: dev-commits-src-main@mlmmj.nyi.freebsd.org
Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1])
	by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 8947D1B5024B;
	Sat, 28 May 2022 20:53:24 +0000 (UTC)
	(envelope-from git@FreeBSD.org)
Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3])
	(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)
	 key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256
	 client-signature RSA-PSS (4096 bits) client-digest SHA256)
	(Client CN "mxrelay.nyi.freebsd.org", Issuer "R3" (verified OK))
	by mx1.freebsd.org (Postfix) with ESMTPS id 4L9YmN2MNKz4lR6;
	Sat, 28 May 2022 20:53:24 +0000 (UTC)
	(envelope-from git@FreeBSD.org)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim;
	t=1653771204;
	h=from:from:reply-to:subject:subject:date:date:message-id:message-id:
	 to:to:cc:mime-version:mime-version:content-type:content-type:
	 content-transfer-encoding:content-transfer-encoding;
	bh=eLEajrNA6NYF7Q5Vkmsvawja6/mmTQCK5TFXWwSZ5X4=;
	b=RwC6crm2L52E1AClpW56Qow5OkFjY4MCzTups35kmPRxDKuWuDcfz3R90JmsqdHjOPx8zD
	reSoIG3zicEptiF/RrDVaBtbtR42VXEOkJ4rbC9TpF4fdP7tqnM639E2jPsaeF4NOjrAVM
	QA8H895Ffm0hv880b65CL1VOMCMzef+Yco9ptZ5mCGxWLNfKMgzo9Jl7h5nJWCtD8QTNst
	SzvV5fcGSn00qXROGoiZlokIgzS6MFZQpCVpoJOsBlslo8w0mqHjrV1PM85wVUD7ZB0w9B
	CjEmhaXDn2xrI/ze3dSvUQzKh/9OdIyRCdwplXdhmAPds1BrJbt5xTH/5EbPMQ==
Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5])
	(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)
	 key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256)
	(Client did not present a certificate)
	by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 246AD162AF;
	Sat, 28 May 2022 20:53:24 +0000 (UTC)
	(envelope-from git@FreeBSD.org)
Received: from gitrepo.freebsd.org ([127.0.1.44])
	by gitrepo.freebsd.org (8.16.1/8.16.1) with ESMTP id 24SKrO1D099409;
	Sat, 28 May 2022 20:53:24 GMT
	(envelope-from git@gitrepo.freebsd.org)
Received: (from git@localhost)
	by gitrepo.freebsd.org (8.16.1/8.16.1/Submit) id 24SKrOc9099408;
	Sat, 28 May 2022 20:53:24 GMT
	(envelope-from git)
Date: Sat, 28 May 2022 20:53:24 GMT
Message-Id: <202205282053.24SKrOc9099408@gitrepo.freebsd.org>
To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org,
        dev-commits-src-main@FreeBSD.org
From: Dmitry Chagin <dchagin@FreeBSD.org>
Subject: git: 0e26e54bdfa2 - main - linux(4): Handle 64-bit SO_TIMESTAMP for 32-bit binaries
List-Id: Commit messages for the main branch of the src repository <dev-commits-src-main.freebsd.org>
List-Archive: https://lists.freebsd.org/archives/dev-commits-src-main
List-Help: <mailto:dev-commits-src-main+help@freebsd.org>
List-Post: <mailto:dev-commits-src-main@freebsd.org>
List-Subscribe: <mailto:dev-commits-src-main+subscribe@freebsd.org>
List-Unsubscribe: <mailto:dev-commits-src-main+unsubscribe@freebsd.org>
Sender: owner-dev-commits-src-main@freebsd.org
X-BeenThere: dev-commits-src-main@freebsd.org
MIME-Version: 1.0
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: 8bit
X-Git-Committer: dchagin
X-Git-Repository: src
X-Git-Refname: refs/heads/main
X-Git-Reftype: branch
X-Git-Commit: 0e26e54bdfa2859908150011a4a165e9dd3de9ac
Auto-Submitted: auto-generated
ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org;
	s=dkim; t=1653771204;
	h=from:from:reply-to:subject:subject:date:date:message-id:message-id:
	 to:to:cc:mime-version:mime-version:content-type:content-type:
	 content-transfer-encoding:content-transfer-encoding;
	bh=eLEajrNA6NYF7Q5Vkmsvawja6/mmTQCK5TFXWwSZ5X4=;
	b=PLOkewHvBvR1TVVasDhOH1XfG5welcLxFGwqZBKixovdGGEUQFoXs0DbEytjxaaIkRnQIA
	0ag7nbNia7qJLNdgKi6j9bVUm1KvbyCRr+OEkNMa05QTo79xJaCAORDebaKbywsQJwpah1
	MRYw7QX0TXA9f/G30ndSzw9uR9/2mFDPKn8NPqcp1FJhL0lLKLn+MduWTTVF7vla9Hmte3
	9Zczf9D2kgLB6HsN9F4PJ0nlZy2pwMjCJP1ei2gcyzlF7EVewl32DDhBD3bpzWVbInVs8L
	ZAUAsuNzTXiKZPKFGn7bEdBzwQgtNEewy5po/oBjfMo9UfFwrc5VkZ3nD3kHqQ==
ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1653771204; a=rsa-sha256; cv=none;
	b=JMhXbbfb8GWCxNKMpjRR8No8rhgk1zPVYbOCtf4Ois40g6AFA7Ua7sX8wfi1PhKX0OWJML
	fo1jSZdEpj4XJw9WPbgNYG38pQEaSUPii+LqjTrcuQwdzpfSyNHZ34bMFY0k7sa7fVqkgT
	mqVkMdPBNc7vNdJxQZ3QO8DK7WDwr3ANE43PyzSuqdkwWf9EhxqhfgSnNC5ru8mu46Iji/
	LzGWThAF6wuMFancp8PPEIMLEN4A+S58TfihMFwlzayGJS4SvR6xmjKQ+ZBPD9PPfSK40M
	fiPCzM35BanmVn3pcUtm0Qav5J1ch6JdH6LCkRXsMg//+zvjf3ybm34mGxgMJw==
ARC-Authentication-Results: i=1;
	mx1.freebsd.org;
	none
X-ThisMailContainsUnwantedMimeParts: N

The branch main has been updated by dchagin:

URL: https://cgit.FreeBSD.org/src/commit/?id=0e26e54bdfa2859908150011a4a165e9dd3de9ac

commit 0e26e54bdfa2859908150011a4a165e9dd3de9ac
Author:     Dmitry Chagin <dchagin@FreeBSD.org>
AuthorDate: 2022-05-28 20:45:39 +0000
Commit:     Dmitry Chagin <dchagin@FreeBSD.org>
CommitDate: 2022-05-28 20:45:39 +0000

    linux(4): Handle 64-bit SO_TIMESTAMP for 32-bit binaries
    
    To solve y2k38 problem in the recvmsg syscall the new SO_TIMESTAMP
    constant were added on v5.1 Linux kernel. So, old 32-bit binaries
    that knows only 32-bit time_t uses the old value of the constant,
    and binaries that knows 64-bit time_t uses the new constant.
    
    To determine what size of time_t type is expected by the user-space,
    store requested value (SO_TIMESTAMP) in the process emuldata structure.
    
    MFC after:              2 weeks
---
 sys/amd64/linux32/linux.h       |  5 +++
 sys/compat/linux/linux_emul.h   |  1 +
 sys/compat/linux/linux_socket.c | 70 ++++++++++++++++++++++++++++++++---------
 sys/compat/linux/linux_socket.h |  6 ++--
 sys/i386/linux/linux.h          |  5 +++
 5 files changed, 70 insertions(+), 17 deletions(-)

diff --git a/sys/amd64/linux32/linux.h b/sys/amd64/linux32/linux.h
index 5cdf7624fef5..6ba3d3214a09 100644
--- a/sys/amd64/linux32/linux.h
+++ b/sys/amd64/linux32/linux.h
@@ -93,6 +93,11 @@ typedef struct {
 	l_suseconds_t	tv_usec;
 } l_timeval;
 
+typedef struct {
+	l_time64_t	tv_sec;
+	l_time64_t	tv_usec;
+} l_sock_timeval;
+
 #define	l_fd_set	fd_set
 
 /*
diff --git a/sys/compat/linux/linux_emul.h b/sys/compat/linux/linux_emul.h
index 4e35da64606f..e801bf09ba72 100644
--- a/sys/compat/linux/linux_emul.h
+++ b/sys/compat/linux/linux_emul.h
@@ -76,6 +76,7 @@ struct linux_pemuldata {
 	uint32_t	persona;	/* process execution domain */
 	uint32_t	ptrace_flags;	/* used by ptrace(2) */
 	uint32_t	oom_score_adj;	/* /proc/self/oom_score_adj */
+	uint32_t	so_timestamp;	/* requested timeval */
 };
 
 #define	LINUX_PEM_XLOCK(p)	sx_xlock(&(p)->pem_sx)
diff --git a/sys/compat/linux/linux_socket.c b/sys/compat/linux/linux_socket.c
index 56355f4f6ddb..3360cf48cb16 100644
--- a/sys/compat/linux/linux_socket.c
+++ b/sys/compat/linux/linux_socket.c
@@ -76,6 +76,7 @@ __FBSDID("$FreeBSD$");
 #include <machine/../linux/linux_proto.h>
 #endif
 #include <compat/linux/linux_common.h>
+#include <compat/linux/linux_emul.h>
 #include <compat/linux/linux_file.h>
 #include <compat/linux/linux_mib.h>
 #include <compat/linux/linux_socket.h>
@@ -547,7 +548,8 @@ linux_to_bsd_so_sockopt(int opt)
 		return (SO_RCVTIMEO);
 	case LINUX_SO_SNDTIMEO:
 		return (SO_SNDTIMEO);
-	case LINUX_SO_TIMESTAMP:
+	case LINUX_SO_TIMESTAMPO:
+	case LINUX_SO_TIMESTAMPN:
 		return (SO_TIMESTAMP);
 	case LINUX_SO_ACCEPTCONN:
 		return (SO_ACCEPTCONN);
@@ -644,8 +646,11 @@ linux_to_bsd_cmsg_type(int cmsg_type)
 }
 
 static int
-bsd_to_linux_cmsg_type(int cmsg_type)
+bsd_to_linux_cmsg_type(struct proc *p, int cmsg_type)
 {
+	struct linux_pemuldata *pem;
+
+	pem = pem_find(p);
 
 	switch (cmsg_type) {
 	case SCM_RIGHTS:
@@ -655,7 +660,7 @@ bsd_to_linux_cmsg_type(int cmsg_type)
 	case SCM_CREDS2:
 		return (LINUX_SCM_CREDENTIALS);
 	case SCM_TIMESTAMP:
-		return (LINUX_SCM_TIMESTAMP);
+		return (pem->so_timestamp);
 	}
 	return (-1);
 }
@@ -1583,28 +1588,55 @@ recvmsg_scm_creds2(socklen_t *datalen, void **data, void **udata)
 _Static_assert(sizeof(struct sockcred2) >= sizeof(struct l_ucred),
     "scm_creds2 sizeof l_ucred");
 
+#if defined(__i386__) || (defined(__amd64__) && defined(COMPAT_LINUX32))
 static int
-recvmsg_scm_timestamp(socklen_t *datalen, void **data, void **udata)
+recvmsg_scm_timestamp(l_int msg_type, socklen_t *datalen, void **data,
+    void **udata)
 {
-	struct timeval *ftmvl;
-	l_timeval *ltv;
+	l_sock_timeval ltv64;
+	l_timeval ltv;
+	struct timeval *tv;
+	socklen_t len;
+	void *buf;
 
 	if (*datalen != sizeof(struct timeval))
 		return (EMSGSIZE);
 
-	ftmvl = *data;
-	ltv = malloc(sizeof(*ltv), M_LINUX, M_WAITOK);
-	ltv->tv_sec = ftmvl->tv_sec;
-	ltv->tv_usec = ftmvl->tv_usec;
-	*data = *udata = ltv;
-	*datalen = sizeof(*ltv);
+	tv = *data;
+#if defined(COMPAT_LINUX32)
+	if (msg_type == LINUX_SCM_TIMESTAMPO &&
+	    (tv->tv_sec > INT_MAX || tv->tv_sec < INT_MIN))
+		return (EOVERFLOW);
+#endif
+	if (msg_type == LINUX_SCM_TIMESTAMPN)
+		len = sizeof(ltv64);
+	else
+		len = sizeof(ltv);
+
+	buf = malloc(len, M_LINUX, M_WAITOK);
+	if (msg_type == LINUX_SCM_TIMESTAMPN) {
+		ltv64.tv_sec = tv->tv_sec;
+		ltv64.tv_usec = tv->tv_usec;
+		memmove(buf, &ltv64, len);
+	} else {
+		ltv.tv_sec = tv->tv_sec;
+		ltv.tv_usec = tv->tv_usec;
+		memmove(buf, &ltv, len);
+	}
+	*data = *udata = buf;
+	*datalen = len;
 	return (0);
 }
+#else
+_Static_assert(sizeof(struct timeval) == sizeof(l_timeval),
+    "scm_timestamp sizeof l_timeval");
+#endif /* __i386__ || (__amd64__ && COMPAT_LINUX32) */
 
 static int
 linux_recvmsg_common(struct thread *td, l_int s, struct l_msghdr *msghdr,
     l_uint flags, struct msghdr *msg)
 {
+	struct proc *p = td->td_proc;
 	struct cmsghdr *cm;
 	struct l_cmsghdr *linux_cmsg = NULL;
 	socklen_t datalen, maxlen, outlen;
@@ -1685,7 +1717,7 @@ linux_recvmsg_common(struct thread *td, l_int s, struct l_msghdr *msghdr,
 		outlen = 0;
 		while (cm != NULL) {
 			linux_cmsg->cmsg_type =
-			    bsd_to_linux_cmsg_type(cm->cmsg_type);
+			    bsd_to_linux_cmsg_type(p, cm->cmsg_type);
 			linux_cmsg->cmsg_level =
 			    bsd_to_linux_sockopt_level(cm->cmsg_level);
 			if (linux_cmsg->cmsg_type == -1 ||
@@ -1718,8 +1750,10 @@ linux_recvmsg_common(struct thread *td, l_int s, struct l_msghdr *msghdr,
 				break;
 
 			case SCM_TIMESTAMP:
-				error = recvmsg_scm_timestamp(&datalen,
-				    &data, &udata);
+#if defined(__i386__) || (defined(__amd64__) && defined(COMPAT_LINUX32))
+				error = recvmsg_scm_timestamp(linux_cmsg->cmsg_type,
+				    &datalen, &data, &udata);
+#endif
 				break;
 			}
 			if (error != 0)
@@ -1894,6 +1928,8 @@ linux_shutdown(struct thread *td, struct linux_shutdown_args *args)
 int
 linux_setsockopt(struct thread *td, struct linux_setsockopt_args *args)
 {
+	struct proc *p = td->td_proc;
+	struct linux_pemuldata *pem;
 	l_timeval linux_tv;
 	struct sockaddr *sa;
 	struct timeval tv;
@@ -1920,6 +1956,10 @@ linux_setsockopt(struct thread *td, struct linux_setsockopt_args *args)
 			return (kern_setsockopt(td, args->s, level,
 			    name, &tv, UIO_SYSSPACE, sizeof(tv)));
 			/* NOTREACHED */
+		case SO_TIMESTAMP:
+			pem = pem_find(p);
+			pem->so_timestamp = args->optname;
+			break;
 		default:
 			break;
 		}
diff --git a/sys/compat/linux/linux_socket.h b/sys/compat/linux/linux_socket.h
index 33f54ffcf634..77537afad6ee 100644
--- a/sys/compat/linux/linux_socket.h
+++ b/sys/compat/linux/linux_socket.h
@@ -187,7 +187,8 @@ int linux_accept(struct thread *td, struct linux_accept_args *args);
 #define	LINUX_SO_RCVTIMEO	20
 #define	LINUX_SO_SNDTIMEO	21
 #endif
-#define	LINUX_SO_TIMESTAMP	29
+#define	LINUX_SO_TIMESTAMPO	29
+#define	LINUX_SO_TIMESTAMPN	63
 #define	LINUX_SO_ACCEPTCONN	30
 #define	LINUX_SO_PEERSEC	31
 #define	LINUX_SO_SNDBUFFORCE	32
@@ -200,7 +201,8 @@ int linux_accept(struct thread *td, struct linux_accept_args *args);
 
 #define LINUX_SCM_RIGHTS	0x01
 #define LINUX_SCM_CREDENTIALS	0x02
-#define LINUX_SCM_TIMESTAMP	LINUX_SO_TIMESTAMP
+#define LINUX_SCM_TIMESTAMPO	LINUX_SO_TIMESTAMPO
+#define LINUX_SCM_TIMESTAMPN	LINUX_SO_TIMESTAMPN
 
 /* Socket options */
 #define	LINUX_IP_TOS		1
diff --git a/sys/i386/linux/linux.h b/sys/i386/linux/linux.h
index 210fb6ca5778..75d2017fb61f 100644
--- a/sys/i386/linux/linux.h
+++ b/sys/i386/linux/linux.h
@@ -85,6 +85,11 @@ typedef struct {
 	l_suseconds_t	tv_usec;
 } l_timeval;
 
+typedef struct {
+	l_time64_t	tv_sec;
+	l_time64_t	tv_usec;
+} l_sock_timeval;
+
 #define	l_fd_set	fd_set
 
 /*