From nobody Fri Jun 17 19:41:14 2022 X-Original-To: dev-commits-src-branches@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 F2F7085D93A; Fri, 17 Jun 2022 19:41:15 +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 4LPqCv3hY0z3jJ4; Fri, 17 Jun 2022 19:41:15 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1655494875; 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=7Ks+kaFqcT/qbGcdqD8vEPCjfofoGxqKOhhIsHaWmO4=; b=FgjLWy2ciTAKDuR3sapZ/FHcjuDoKEh/lJscWp1yzUjdDq9/4d+ra/lsyLgsk/5uJ7qJGS xqos3tlf4iH40Fohlh5NK5aFyULWCHKwYhpWMXxBnDKeqeDKCPB/TeA9/SxyczHeBi8kd9 PNqN1H7B0N2KR5ks22ykDpsxoXIUOffTL2H9D4Y8ZQbaRS08eMcXLHFbcHz7RpCDi3AXHq Y3JLbcWDaGdtAq0zyxwa+1cmzqZYxAAVlfjudpzoUX8qyisiW9Qby/OxftGssYyOt9Z86X KCEdT9+SnZKGNpNjIvCjEr9pEvIETRXFmLPEVEKFahPJhP5pKW1cw+ZO3zWReg== 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 7D5E1259E0; Fri, 17 Jun 2022 19:41:14 +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 25HJfEne030209; Fri, 17 Jun 2022 19:41:14 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.16.1/8.16.1/Submit) id 25HJfEIq030208; Fri, 17 Jun 2022 19:41:14 GMT (envelope-from git) Date: Fri, 17 Jun 2022 19:41:14 GMT Message-Id: <202206171941.25HJfEIq030208@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org From: Dmitry Chagin Subject: git: 6bee81f9c634 - stable/13 - linux(4): Handle 64-bit SO_TIMESTAMP for 32-bit binaries List-Id: Commits to the stable branches of the FreeBSD src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-branches List-Help: List-Post: List-Subscribe: List-Unsubscribe: Sender: owner-dev-commits-src-branches@freebsd.org X-BeenThere: dev-commits-src-branches@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/stable/13 X-Git-Reftype: branch X-Git-Commit: 6bee81f9c6342c1f0a989d939447948e08a593a8 Auto-Submitted: auto-generated ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1655494875; 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=7Ks+kaFqcT/qbGcdqD8vEPCjfofoGxqKOhhIsHaWmO4=; b=tmGgjciH+yj+KXhlp/l8NrUr1EloBgzSPkcX0gJ2ZpkwDwTvgzo82Ft9RHWZRjvHsfiqxM Gnuj25rvKNbyr4/e3Pv8MQEG6H94l9ewICaSEDQ5kE1/5jNuV+19eNt6e55e1OVt7oordX 5KvDlNtVJjuGdKAZ96t1ZE8IlKCM98Z+UY/iTtZSzoBRuqWouKeYaBJR8luej0xLAGOL0i rGTdQBtZR6zPwjZBnjjmV46JGpDdGIOrVdr/+J6Ubk0kPjOvGHqnUqeY26+oANft5V8BcG n8ePzNdq1bUhsTZi/9p396jyTVQ+R14EYjP4AwacdC6W8XUV0YTjCcLp1MdrfQ== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1655494875; a=rsa-sha256; cv=none; b=IU1oA+cK4r7KNMbl9hrvsFd2ztUCLDo1hi8rFfDCbmOn/f+qamcjCg9KunPmGP2jW9UHtG NXbWwafga+39S3RsUCOtJ4FWS4VrVUl2Hc/1x+nthFUWmoEm/+cmt4d7xb1sA1GACHQN2r 3FBnM/tDtuFOaOHHh/8HUDbeeCukkzCu12ERu8Dr0IKk4QA6x2hZ6siYL/13AsRu8iC8x0 TFPKf0pHJcDYXPNwKL5yX3AapKPU2BEWGL8IYaRV845IBjaE/Z1FrBTNr02kfpd+K1tGzW 8rfWyog1JB5J9HClnMCtCz9pJPNDMlMQoV56WjO1mY0Q5+ru9IQtR9piVXgybA== ARC-Authentication-Results: i=1; mx1.freebsd.org; none X-ThisMailContainsUnwantedMimeParts: N The branch stable/13 has been updated by dchagin: URL: https://cgit.FreeBSD.org/src/commit/?id=6bee81f9c6342c1f0a989d939447948e08a593a8 commit 6bee81f9c6342c1f0a989d939447948e08a593a8 Author: Dmitry Chagin AuthorDate: 2022-05-28 20:45:39 +0000 Commit: Dmitry Chagin CommitDate: 2022-06-17 19:35:34 +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 (cherry picked from commit 0e26e54bdfa2859908150011a4a165e9dd3de9ac) --- 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 #endif #include +#include #include #include #include @@ -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, <v64, len); + } else { + ltv.tv_sec = tv->tv_sec; + ltv.tv_usec = tv->tv_usec; + memmove(buf, <v, 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 /*