From nobody Sat Sep 6 14:41:22 2025 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=none dis=none) header.from=samsung.com ARC-Seal: i=1; a=rsa-sha256; t=1756999921; cv=none; d=zohomail.com; s=zohoarc; b=VhsOYVVr87BJ5Lo3OAU3bvbaP6ANClZTODKBvt9COc5GU1muVaUadzzz23qbU1FFYyNvha+MkG24QjzLrD2nrGGOJWxbCy6+AWO4nqrjDVkLe+GNkzOwgEaM0iyWBpCTd3NRoFVTLsWzl8mAs2K46HrHxzJaVGYcHkTlpNrX098= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1756999921; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=kS1RgeBBP9GXxsBqvz2fPMIRhTPgLNrw74fxVaxHOqA=; b=gjJrri2jWNc+RzDDl48FTQBCYlp6KO4fwnlzNOlIT8l1PDNpLDPHGy5eN5+iQT3Kdz6B5bFPHdaOz310NvR/6FeWMXb6Oy9FLnK6oMjAaTcMQFLShVa1iRFbxHPmena3mbLfUkC3Er7F/GWNtBOQJiCQAbdMXHdUIU+3LS+3xWE= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1756999921363572.4347934075149; Thu, 4 Sep 2025 08:32:01 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1uuBuT-0004ac-Af; Thu, 04 Sep 2025 11:30:02 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1uuBuP-0004aN-JS for qemu-devel@nongnu.org; Thu, 04 Sep 2025 11:29:57 -0400 Received: from mailout2.w1.samsung.com ([210.118.77.12]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1uuBuE-0000OX-Hv for qemu-devel@nongnu.org; Thu, 04 Sep 2025 11:29:57 -0400 Received: from eucas1p1.samsung.com (unknown [182.198.249.206]) by mailout2.w1.samsung.com (KnoxPortal) with ESMTP id 20250904152929euoutp023d75478e14f093aa6e13ad3db61b020b~iHfsy-4DF0550205502euoutp02e for ; Thu, 4 Sep 2025 15:29:29 +0000 (GMT) Received: from eusmtip1.samsung.com (unknown [203.254.199.221]) by eucas1p1.samsung.com (KnoxPortal) with ESMTPA id 20250904152929eucas1p19fabb7cc807c83ca18b5fcd5edcec2ff~iHfslYmI_0168501685eucas1p1w; Thu, 4 Sep 2025 15:29:29 +0000 (GMT) Received: from localhost (unknown [106.120.51.111]) by eusmtip1.samsung.com (KnoxPortal) with ESMTPA id 20250904152928eusmtip1fde7d546671dd4ca8e737c3bf7b86ebc~iHfscXuf92348523485eusmtip1S; Thu, 4 Sep 2025 15:29:28 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 mailout2.w1.samsung.com 20250904152929euoutp023d75478e14f093aa6e13ad3db61b020b~iHfsy-4DF0550205502euoutp02e DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=samsung.com; s=mail20170921; t=1756999769; bh=kS1RgeBBP9GXxsBqvz2fPMIRhTPgLNrw74fxVaxHOqA=; h=From:To:Cc:Subject:Date:References:From; b=oRiKV3kPP6t/ygvKa0qQHdGVcAl3FGRTkUV2HluQ7idCeXoN+8VP+hVbdUFTKmHss 283zsanH2STi8V15Jef4jXmun82ClV4aMhf7ZgEEw+nUXXFXVTF/X9d2i3KCXKv6h7 WLv15VDN2rxtSZW46ANSHfECU7z2rPKAMBkSArrI= From: =?UTF-8?q?=C5=81ukasz=20Stelmach?= To: qemu-devel@nongnu.org Cc: Laurent Vivier , =?UTF-8?q?=C5=81ukasz=20Stelmach?= Subject: [PATCH v2] linux-user: add y2038 safe socket timeout options Date: Thu, 4 Sep 2025 17:29:22 +0200 Message-Id: <20250904152922.2949232-1-l.stelmach@samsung.com> X-Mailer: git-send-email 2.39.5 MIME-Version: 1.0 Organization: Samsung R&D Institute Poland Content-Transfer-Encoding: quoted-printable X-CMS-MailID: 20250904152929eucas1p19fabb7cc807c83ca18b5fcd5edcec2ff X-Msg-Generator: CA Content-Type: text/plain; charset="utf-8" X-RootMTR: 20250904152929eucas1p19fabb7cc807c83ca18b5fcd5edcec2ff X-EPHeader: CA X-CMS-RootMailID: 20250904152929eucas1p19fabb7cc807c83ca18b5fcd5edcec2ff References: Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=210.118.77.12; envelope-from=l.stelmach@samsung.com; helo=mailout2.w1.samsung.com X-Spam_score_int: -43 X-Spam_score: -4.4 X-Spam_bar: ---- X-Spam_report: (-4.4 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.001, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_MED=-2.3, RCVD_IN_VALIDITY_CERTIFIED_BLOCKED=0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @samsung.com) X-ZM-MESSAGEID: 1756999923789124100 Linux kernel has redefined some socket options values and introduces y2038 safe code paths on 32-bit architectures. See include/uapi/asm-generic/socket.h in the kernel sources. The argument for SO_RCVTIMEO_NEW (66) SO_SNDTIMEO_NEW (67) is struct __kernel_sock_timeval which always comprises two 64-bit fields regardless of the architecture. Unlike the kernel QEMU needs to support both old and new values so SO_SNDTIME and SO_RCVTIMEO have been renamed to *_OLD, but neither old nor new values have been marked as "default". Signed-off-by: =C5=81ukasz Stelmach --- v2: - added missing TARGET_ prefix in header files linux-user/alpha/sockbits.h | 8 ++++-- linux-user/generic/sockbits.h | 8 ++++-- linux-user/hppa/sockbits.h | 8 ++++-- linux-user/mips/sockbits.h | 8 ++++-- linux-user/ppc/sockbits.h | 8 +++--- linux-user/sparc/sockbits.h | 8 ++++-- linux-user/strace.c | 6 +++-- linux-user/syscall.c | 47 +++++++++++++++++++++-------------- 8 files changed, 67 insertions(+), 34 deletions(-) diff --git a/linux-user/alpha/sockbits.h b/linux-user/alpha/sockbits.h index d54dc98c09..114e808693 100644 --- a/linux-user/alpha/sockbits.h +++ b/linux-user/alpha/sockbits.h @@ -28,8 +28,8 @@ #define TARGET_SO_RCVBUFFORCE 0x100b #define TARGET_SO_RCVLOWAT 0x1010 #define TARGET_SO_SNDLOWAT 0x1011 -#define TARGET_SO_RCVTIMEO 0x1012 -#define TARGET_SO_SNDTIMEO 0x1013 +#define TARGET_SO_RCVTIMEO_OLD 0x1012 +#define TARGET_SO_SNDTIMEO_OLD 0x1013 #define TARGET_SO_ACCEPTCONN 0x1014 #define TARGET_SO_PROTOCOL 0x1028 #define TARGET_SO_DOMAIN 0x1029 @@ -75,6 +75,10 @@ /* Instruct lower device to use last 4-bytes of skb data as FCS */ #define TARGET_SO_NOFCS 43 =20 +/* New socket timeout options that are y2038 safe. */ +#define TARGET_SO_RCVTIMEO_NEW 66 +#define TARGET_SO_SNDTIMEO_NEW 67 + /* TARGET_O_NONBLOCK clashes with the bits used for socket types. Therefo= re we * have to define SOCK_NONBLOCK to a different value here. */ diff --git a/linux-user/generic/sockbits.h b/linux-user/generic/sockbits.h index b3b4a8e44c..7b78b9dcaa 100644 --- a/linux-user/generic/sockbits.h +++ b/linux-user/generic/sockbits.h @@ -34,8 +34,8 @@ #define TARGET_SO_PEERCRED 17 #define TARGET_SO_RCVLOWAT 18 #define TARGET_SO_SNDLOWAT 19 -#define TARGET_SO_RCVTIMEO 20 -#define TARGET_SO_SNDTIMEO 21 +#define TARGET_SO_RCVTIMEO_OLD 20 +#define TARGET_SO_SNDTIMEO_OLD 21 =20 /* Security levels - as per NRL IPv6 - don't actually do anything */ #define TARGET_SO_SECURITY_AUTHENTICATION 22 @@ -58,4 +58,8 @@ =20 #define TARGET_SO_PROTOCOL 38 #define TARGET_SO_DOMAIN 39 + +/* New socket timeout options that are y2038 safe. */ +#define TARGET_SO_RCVTIMEO_NEW 66 +#define TARGET_SO_SNDTIMEO_NEW 67 #endif diff --git a/linux-user/hppa/sockbits.h b/linux-user/hppa/sockbits.h index 23f69a3293..bb98a8c8be 100644 --- a/linux-user/hppa/sockbits.h +++ b/linux-user/hppa/sockbits.h @@ -17,8 +17,8 @@ #define TARGET_SO_RCVBUFFORCE 0x100b #define TARGET_SO_SNDLOWAT 0x1003 #define TARGET_SO_RCVLOWAT 0x1004 -#define TARGET_SO_SNDTIMEO 0x1005 -#define TARGET_SO_RCVTIMEO 0x1006 +#define TARGET_SO_SNDTIMEO_OLD 0x1005 +#define TARGET_SO_RCVTIMEO_OLD 0x1006 #define TARGET_SO_ERROR 0x1007 #define TARGET_SO_TYPE 0x1008 #define TARGET_SO_PROTOCOL 0x1028 @@ -67,6 +67,10 @@ =20 #define TARGET_SO_CNX_ADVICE 0x402E =20 +/* New socket timeout options that are y2038 safe. */ +#define TARGET_SO_RCVTIMEO_NEW 0x4040 +#define TARGET_SO_SNDTIMEO_NEW 0x4041 + /* TARGET_O_NONBLOCK clashes with the bits used for socket types. Therefo= re we * have to define SOCK_NONBLOCK to a different value here. */ diff --git a/linux-user/mips/sockbits.h b/linux-user/mips/sockbits.h index 562cad88e2..11d25a5066 100644 --- a/linux-user/mips/sockbits.h +++ b/linux-user/mips/sockbits.h @@ -37,8 +37,8 @@ #define TARGET_SO_RCVBUF 0x1002 /* Receive buffer. */ #define TARGET_SO_SNDLOWAT 0x1003 /* send low-water mark */ #define TARGET_SO_RCVLOWAT 0x1004 /* receive low-water mark */ -#define TARGET_SO_SNDTIMEO 0x1005 /* send timeout */ -#define TARGET_SO_RCVTIMEO 0x1006 /* receive timeout */ +#define TARGET_SO_SNDTIMEO_OLD 0x1005 /* send timeout */ +#define TARGET_SO_RCVTIMEO_OLD 0x1006 /* receive timeout */ #define TARGET_SO_ACCEPTCONN 0x1009 #define TARGET_SO_PROTOCOL 0x1028 /* protocol type */ #define TARGET_SO_DOMAIN 0x1029 /* domain/socket family */ @@ -71,6 +71,10 @@ #define TARGET_SO_RCVBUFFORCE 33 #define TARGET_SO_PASSSEC 34 =20 +/* New socket timeout options that are y2038 safe. */ +#define TARGET_SO_RCVTIMEO_NEW 66 +#define TARGET_SO_SNDTIMEO_NEW 67 + /** sock_type - Socket types * * Please notice that for binary compat reasons MIPS has to diff --git a/linux-user/ppc/sockbits.h b/linux-user/ppc/sockbits.h index ee453347a3..25455a948e 100644 --- a/linux-user/ppc/sockbits.h +++ b/linux-user/ppc/sockbits.h @@ -14,10 +14,10 @@ #define TARGET_SO_RCVLOWAT 16 #undef TARGET_SO_SNDLOWAT #define TARGET_SO_SNDLOWAT 17 -#undef TARGET_SO_RCVTIMEO -#define TARGET_SO_RCVTIMEO 18 -#undef TARGET_SO_SNDTIMEO -#define TARGET_SO_SNDTIMEO 19 +#undef TARGET_SO_RCVTIMEO_OLD +#define TARGET_SO_RCVTIMEO_OLD 18 +#undef TARGET_SO_SNDTIMEO_OLD +#define TARGET_SO_SNDTIMEO_OLD 19 #undef TARGET_SO_PASSCRED #define TARGET_SO_PASSCRED 20 #undef TARGET_SO_PEERCRED diff --git a/linux-user/sparc/sockbits.h b/linux-user/sparc/sockbits.h index 0a822e3e1f..8fce0e5373 100644 --- a/linux-user/sparc/sockbits.h +++ b/linux-user/sparc/sockbits.h @@ -24,8 +24,8 @@ #define TARGET_SO_BSDCOMPAT 0x0400 #define TARGET_SO_RCVLOWAT 0x0800 #define TARGET_SO_SNDLOWAT 0x1000 -#define TARGET_SO_RCVTIMEO 0x2000 -#define TARGET_SO_SNDTIMEO 0x4000 +#define TARGET_SO_RCVTIMEO_OLD 0x2000 +#define TARGET_SO_SNDTIMEO_OLD 0x4000 #define TARGET_SO_ACCEPTCONN 0x8000 =20 #define TARGET_SO_SNDBUF 0x1001 @@ -104,6 +104,10 @@ =20 #define TARGET_SO_ZEROCOPY 0x003e =20 +/* New socket timeout options that are y2038 safe. */ +#define TARGET_SO_RCVTIMEO_NEW 0x0044 +#define TARGET_SO_SNDTIMEO_NEW 0x0045 + /* Security levels - as per NRL IPv6 - don't actually do anything */ #define TARGET_SO_SECURITY_AUTHENTICATION 0x5001 #define TARGET_SO_SECURITY_ENCRYPTION_TRANSPORT 0x5002 diff --git a/linux-user/strace.c b/linux-user/strace.c index 1233ebceb0..9639d47d70 100644 --- a/linux-user/strace.c +++ b/linux-user/strace.c @@ -2970,11 +2970,13 @@ print_optint: case TARGET_SO_RCVLOWAT: qemu_log("SO_RCVLOWAT,"); goto print_optint; - case TARGET_SO_RCVTIMEO: + case TARGET_SO_RCVTIMEO_OLD: + case TARGET_SO_RCVTIMEO_NEW: qemu_log("SO_RCVTIMEO,"); print_timeval(optval, 0); break; - case TARGET_SO_SNDTIMEO: + case TARGET_SO_SNDTIMEO_OLD: + case TARGET_SO_SNDTIMEO_NEW: qemu_log("SO_SNDTIMEO,"); print_timeval(optval, 0); break; diff --git a/linux-user/syscall.c b/linux-user/syscall.c index 91360a072c..fb37b516db 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -1132,7 +1132,8 @@ static inline abi_long copy_to_user_timeval(abi_ulong= target_tv_addr, return 0; } =20 -#if defined(TARGET_NR_clock_adjtime64) && defined(CONFIG_CLOCK_ADJTIME) +#if defined(TARGET_NR_clock_adjtime64) && defined(CONFIG_CLOCK_ADJTIME) ||= \ + defined(TARGET_NR_getsockopt) || defined(TARGET_NR_setsockopt) static inline abi_long copy_from_user_timeval64(struct timeval *tv, abi_ulong target_tv_addr) { @@ -2358,21 +2359,28 @@ static abi_long do_setsockopt(int sockfd, int level= , int optname, #endif case TARGET_SOL_SOCKET: switch (optname) { - case TARGET_SO_RCVTIMEO: - case TARGET_SO_SNDTIMEO: + case TARGET_SO_RCVTIMEO_OLD: + case TARGET_SO_SNDTIMEO_OLD: + case TARGET_SO_RCVTIMEO_NEW: + case TARGET_SO_SNDTIMEO_NEW: { struct timeval tv; + bool old_timeval =3D (optname =3D=3D TARGET_SO_RCVTIMEO_OL= D || + optname =3D=3D TARGET_SO_SNDTIMEO_OLD); =20 - if (optlen !=3D sizeof(struct target_timeval)) { + if (optlen !=3D (old_timeval ? sizeof(struct target_timeva= l) : \ + sizeof(struct target__kernel_sock_timeval))= ) { return -TARGET_EINVAL; } =20 - if (copy_from_user_timeval(&tv, optval_addr)) { + if ((old_timeval && copy_from_user_timeval(&tv, optval_add= r)) || + (!old_timeval && copy_from_user_timeval64(&tv, optval_= addr))) { return -TARGET_EFAULT; } =20 ret =3D get_errno(setsockopt(sockfd, SOL_SOCKET, - optname =3D=3D TARGET_SO_RCVTIMEO ? + optname =3D=3D TARGET_SO_RCVTIMEO_OLD || \ + optname =3D=3D TARGET_SO_RCVTIMEO_NEW ? SO_RCVTIMEO : SO_SNDTIMEO, &tv, sizeof(tv))); return ret; @@ -2590,13 +2598,16 @@ static abi_long do_getsockopt(int sockfd, int level= , int optname, /* These don't just return a single integer */ case TARGET_SO_PEERNAME: goto unimplemented; - case TARGET_SO_RCVTIMEO: { + case TARGET_SO_RCVTIMEO_OLD: + case TARGET_SO_RCVTIMEO_NEW: + case TARGET_SO_SNDTIMEO_OLD: + case TARGET_SO_SNDTIMEO_NEW: + { struct timeval tv; socklen_t tvlen; + bool old_timeval =3D (optname =3D=3D TARGET_SO_RCVTIMEO_OLD || + optname =3D=3D TARGET_SO_SNDTIMEO_OLD); =20 - optname =3D SO_RCVTIMEO; - -get_timeout: if (get_user_u32(len, optlen)) { return -TARGET_EFAULT; } @@ -2605,15 +2616,18 @@ get_timeout: } =20 tvlen =3D sizeof(tv); - ret =3D get_errno(getsockopt(sockfd, level, optname, + ret =3D get_errno(getsockopt(sockfd, level, + optname =3D=3D TARGET_SO_RCVTIMEO_O= LD || \ + optname =3D=3D TARGET_SO_RCVTIMEO_N= EW ? + SO_RCVTIMEO : SO_SNDTIMEO, &tv, &tvlen)); if (ret < 0) { return ret; } - if (len > sizeof(struct target_timeval)) { - len =3D sizeof(struct target_timeval); - } - if (copy_to_user_timeval(optval_addr, &tv)) { + len =3D MIN(len, (old_timeval ? sizeof(struct target_timeval) = : \ + sizeof(struct target__kernel_sock_timeval))); + if ((old_timeval && copy_to_user_timeval(optval_addr, &tv)) || + (!old_timeval && copy_to_user_timeval64(optval_addr, &tv))= ) { return -TARGET_EFAULT; } if (put_user_u32(len, optlen)) { @@ -2621,9 +2635,6 @@ get_timeout: } break; } - case TARGET_SO_SNDTIMEO: - optname =3D SO_SNDTIMEO; - goto get_timeout; case TARGET_SO_PEERCRED: { struct ucred cr; socklen_t crlen; --=20 2.39.5