From patchwork Wed Apr 8 11:51:15 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lukasz Majewski X-Patchwork-Id: 38770 Return-Path: X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from mail-out.m-online.net (mail-out.m-online.net [212.18.0.9]) by sourceware.org (Postfix) with ESMTPS id 62B2F385BF81 for ; Wed, 8 Apr 2020 11:51:36 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org 62B2F385BF81 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=denx.de Authentication-Results: sourceware.org; spf=none smtp.mailfrom=lukma@denx.de Received: from frontend01.mail.m-online.net (unknown [192.168.8.182]) by mail-out.m-online.net (Postfix) with ESMTP id 48y2g96Xvxz1qskH; Wed, 8 Apr 2020 13:51:33 +0200 (CEST) Received: from localhost (dynscan1.mnet-online.de [192.168.6.70]) by mail.m-online.net (Postfix) with ESMTP id 48y2g93ldbz1qtwZ; Wed, 8 Apr 2020 13:51:33 +0200 (CEST) X-Virus-Scanned: amavisd-new at mnet-online.de Received: from mail.mnet-online.de ([192.168.8.182]) by localhost (dynscan1.mail.m-online.net [192.168.6.70]) (amavisd-new, port 10024) with ESMTP id 2qn4LR5KRSHC; Wed, 8 Apr 2020 13:51:31 +0200 (CEST) X-Auth-Info: /ppgT6CLgQrv88ccDugtlXE5M9NB2B0xVCU3qPQ34gA= Received: from localhost.localdomain (85-222-111-42.dynamic.chello.pl [85.222.111.42]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.mnet-online.de (Postfix) with ESMTPSA; Wed, 8 Apr 2020 13:51:31 +0200 (CEST) From: Lukasz Majewski To: Joseph Myers , Adhemerval Zanella Cc: Alistair Francis , Alistair Francis , GNU C Library , Florian Weimer , Andreas Schwab , Lukasz Majewski Subject: [PATCH] y2038: linux: Provide __recvmmsg_time64 implementation Date: Wed, 8 Apr 2020 13:51:15 +0200 Message-Id: <20200408115115.8140-1-lukma@denx.de> X-Mailer: git-send-email 2.20.1 MIME-Version: 1.0 X-Spam-Status: No, score=-32.2 required=5.0 tests=BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, KAM_DMARC_STATUS, KAM_LAZY_DOMAIN_SECURITY, RCVD_IN_BARRACUDACENTRAL, RCVD_IN_DNSWL_LOW, RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL, SPF_HELO_NONE, SPF_NONE, TXREP autolearn=ham autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on server2.sourceware.org X-BeenThere: libc-alpha@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Libc-alpha mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 08 Apr 2020 11:51:38 -0000 This patch provides new __recvmmsg_time64 explicit 64 bit function for receiving messages from a socket with absolute timeout. Moreover, a 32 bit version - __recvmmsg has been refactored to internally use __recvmmsg_time64. The __recvmmsg is now supposed to be used on systems still supporting 32 bit time (__TIMESIZE != 64) - hence the necessary conversion to 64 bit struct __timespec64 from struct timespec. The new recvmmsg_time64 syscall available from Linux 5.1+ has been used, when applicable. Build tests: - ./src/scripts/build-many-glibcs.py glibcs Run-time tests: - Run specific tests on ARM/x86 32bit systems (qemu): https://github.com/lmajewski/meta-y2038 and run tests: https://github.com/lmajewski/y2038-tests/commits/master Linux kernel, headers and minimal kernel version for glibc build test matrix: - Linux v5.1 (with recvmmsg_time64) and glibc built with v5.1 as minimal kernel version (--enable-kernel="5.1.0") The __ASSUME_TIME64_SYSCALLS flag defined. - Linux v5.1 and default minimal kernel version The __ASSUME_TIME64_SYSCALLS not defined, but kernel supports recvmmsg_time64 syscall. - Linux v4.19 (no recvmmsg_time64 support) with default minimal kernel version for contemporary glibc (3.2.0) This kernel doesn't support recvmmsg_time64 syscall, so the fallback to recvmmsg is tested. Above tests were performed with Y2038 redirection applied as well as without (so the __TIMESIZE != 64 execution path is checked as well). --- include/sys/socket.h | 10 +++++++ sysdeps/unix/sysv/linux/recvmmsg.c | 48 ++++++++++++++++++++++++++++-- 2 files changed, 55 insertions(+), 3 deletions(-) diff --git a/include/sys/socket.h b/include/sys/socket.h index 26db0e0d77..df39244005 100644 --- a/include/sys/socket.h +++ b/include/sys/socket.h @@ -96,6 +96,16 @@ extern ssize_t __sendmsg (int __fd, const struct msghdr *__message, extern int __sendmmsg (int __fd, struct mmsghdr *__vmessages, unsigned int __vlen, int __flags); libc_hidden_proto (__sendmmsg) + +# include +# if __TIMESIZE == 64 +# define __recvmmsg_time64 __recvmmsg +# else +extern int __recvmmsg_time64 (int fd, struct mmsghdr *vmessages, + unsigned int vlen, int flags, + struct __timespec64 *tmo); +libc_hidden_proto (__recvmmsg_time64) +# endif #endif /* Receive a message as described by MESSAGE from socket FD. diff --git a/sysdeps/unix/sysv/linux/recvmmsg.c b/sysdeps/unix/sysv/linux/recvmmsg.c index 42c80c59c3..248dae7dac 100644 --- a/sysdeps/unix/sysv/linux/recvmmsg.c +++ b/sysdeps/unix/sysv/linux/recvmmsg.c @@ -25,12 +25,54 @@ #include int -recvmmsg (int fd, struct mmsghdr *vmessages, unsigned int vlen, int flags, - struct timespec *tmo) +__recvmmsg_time64 (int fd, struct mmsghdr *vmessages, unsigned int vlen, + int flags, struct __timespec64 *tmo) { #ifdef __ASSUME_RECVMMSG_SYSCALL - return SYSCALL_CANCEL (recvmmsg, fd, vmessages, vlen, flags, tmo); +# ifdef __ASSUME_TIME64_SYSCALLS +# ifndef __NR_recvmmsg_time64 +# define __NR_recvmmsg_time64 __NR_recvmmsg +# endif + return SYSCALL_CANCEL (recvmmsg_time64, fd, vmessages, vlen, flags, tmo); +# else + int ret = SYSCALL_CANCEL (recvmmsg_time64, fd, vmessages, vlen, flags, tmo); + if (ret == 0 || errno != ENOSYS) + return ret; + + struct timespec ts32; + if (tmo != NULL) + { + if (! in_time_t_range (tmo->tv_sec)) + { + __set_errno (EOVERFLOW); + return -1; + } + + ts32 = valid_timespec64_to_timespec (*tmo); + } + + return SYSCALL_CANCEL (recvmmsg, fd, vmessages, vlen, flags, + tmo != NULL ? &ts32 : NULL); +# endif #else return SOCKETCALL_CANCEL (recvmmsg, fd, vmessages, vlen, flags, tmo); #endif } + +#if __TIMESIZE != 64 +libc_hidden_def (__recvmmsg_time64) + +int +__recvmmsg (int fd, struct mmsghdr *vmessages, unsigned int vlen, int flags, + struct timespec *tmo) +{ + struct __timespec64 ts64; + + if (tmo != NULL) + ts64 = valid_timespec_to_timespec64 (*tmo); + + return __recvmmsg_time64 (fd, vmessages, vlen, flags, + tmo != NULL ? &ts64 : NULL); +} +#endif +strong_alias (__recvmmsg, recvmmsg)