From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on inbox.vuxu.org X-Spam-Level: X-Spam-Status: No, score=-1.5 required=5.0 tests=DKIM_INVALID,DKIM_SIGNED, FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_DNSWL_LOW, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.4 Received: (qmail 21611 invoked from network); 2 Jun 2023 14:49:53 -0000 Received: from second.openwall.net (193.110.157.125) by inbox.vuxu.org with ESMTPUTF8; 2 Jun 2023 14:49:53 -0000 Received: (qmail 23828 invoked by uid 550); 2 Jun 2023 14:49:50 -0000 Mailing-List: contact musl-help@lists.openwall.com; run by ezmlm Precedence: bulk List-Post: List-Help: List-Unsubscribe: List-Subscribe: List-ID: Reply-To: musl@lists.openwall.com Received: (qmail 23790 invoked from network); 2 Jun 2023 14:49:49 -0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gmx.net; s=s31663417; t=1685717377; x=1686322177; i=nullplan@gmx.net; bh=V1/pERLAaqksHLLqpMLSrgRoKBMSM6zb4uzyA5qq2eg=; h=X-UI-Sender-Class:Date:From:To:Subject; b=EQaHWvOIYy9QqP6aeU5kgMb01bgmyC8MXdhRo2aKpxUNEohF0iUYONA49sCYpQPxgq3GBjs jcIDEgVl7nnKQrluHYHse6+gbX++Z80gXCIS/o8fYJZL1dj5G29EAKF0/1YVHLuLxd/SsH6le yjvAMZfKQN3zK8EnqHVziDsHLeSmlwi6Lj1bex78yGMy/Goie2yGN6ohVZgDFMP3TTON1zR8v xANwrmp93KvFmUqk9ew7osQHltdbVbXO5qPGQE/yHYNWUK/8+5d3d9rQ+DMeXPkVpZcpuchKT 74e4RYN9kyKqEO3MfLqUs5t5F9uNaNks8arJ+O2d4kVeorV+PTww== X-UI-Sender-Class: 724b4f7f-cbec-4199-ad4e-598c01a50d3a Date: Fri, 2 Jun 2023 16:49:37 +0200 From: Markus Wichmann To: musl@lists.openwall.com Message-ID: MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="MAMxKDMPUmdWtYzs" Content-Disposition: inline X-Provags-ID: V03:K1:X0YMLKGflP8/Ck5Zbwb36le4wXaxj+1E9zHPVqlXGRU7AktG9oD 6dNUz2qKFs6jUJAmBiKh7m8KeZw5adx2wlPpIPC0bg1Adw7HeGTy0e8w+ZsVdFuVUS79c6L k1YkYZ5NN52VRZcoMV9N69fprOxgltCMFX1rPl9ETDy6YCcfwR4pL09d46JVc8M9NM0mGo5 mEAwSYjbzODcEdB3RnD/Q== UI-OutboundReport: notjunk:1;M01:P0:iwkMgfgFv6k=;RUoxQHMJX6nLeWwtiY4roPZHYNZ zl3xLJWeeETFKI9SkvBp7/Yb4QyHGzCo7JjbObYD6CgYGsGy8UUaP/a4XEYhkFsvwlfVaYle4 qZq8V/3lOQYW/KAiN16y1zJ3GpQicmR5nqfrW/YQgx4yTmZ2tRIi5POreASQJPRLmPJ5Rd44p lkz9G6W3CEaZhSS1h9RWcGiHnHIsmCxs9zYe48qqKZKZDf8WCq0hRMMn+pBR7ODD8T5GnpVKb FbXt6sXZ/6K0j5BMKdoAw+yo+yaRsDGUrpCOtwHOwXqT11hBqyrn3y5o9UjlB4WMdo6xq1+k+ PBpmwtJpC+aR09jT7BBLzMZxNpTaJqAR1NPpP2UJ9a1Ed43WsiFy1ZP0X+BEnaW/WxXqQI99H rGasFUpl9xed9mTLaC2e0HcoiQkt339FIVuf4rn8hJWaEARQVPis/DSGhylm99/ZdXMstR8gy xihtHP+LHd0vKEYoc/40949YdTer/rDxzQbdNqMjtCXLZjC0bT1DwY2N8SuwezaCbJCKFIatP LUl86U6l/HaW9+00ERn7x2c3Pneenj41WG1eI4jyGZq0vKrVYZ5/4xXuI8pR7X28kLejIlqA9 3V5QXb1qjUFGQ+GkLJ1oODL0X3ZxSWOtgFhZhOFIf5msWl82iUJ0IslfFMOwDQxx9BbRJuKT2 K+tlj/Mi1YS8WLJEh2K1R8jIe5/HtUxKX6j6Rw0qrNTF1LrYT2iuk0lw+tX0gNjitXCvOUN6A kTzepetDwC7d+ZlJVLOUE2czVq+AqZJuT5uZ81g+kd6XpWA5nEtzeaRfnQxlwm2dm0Pd/6Inj coa3qIQaIJNKNgyFIIIQuU/Xd5YuuQTC7ZfVjEJn+bloR6ROJFEEq55LK0Dqb4pFXHduzNXLM aRykJ+7TZrJ9ia37O4PV0WdPBQxXMM6bP/nQbDjOMcU3xxBX377riBKifCkvvLU++v0V4RaAB CPA7xA== Subject: [musl] __convert_scm_timestamps() probably breaks with struct timeval --MAMxKDMPUmdWtYzs Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Hi all, I couldn't think of a better subject. For unrelated reasons, today I stumbled upon the abovenamed function. It looks through all control messages in a msghdr, looking for SCM_TIMESTAMP_OLD and SCM_TIMESTAMPNS_OLD, and converting an array two long into an array of two long long. This will work with struct timespec (or SCM_TIMESTAMPNS_OLD) on all architectures, because struct timespec has been defined specifically for this to work (due to the kernel accessing it the same way). But it will break with struct timeval (or SCM_TIMESTAMP_OLD). First of all, on some 32-bit archs (and this code is only used on 32-bit archs) we have alignof(int64_t) == 4, and therefore sizeof (struct timeval) == 12. Therefore CMSG_LEN(sizeof (long long[2])) != CMSG_LEN(struct timeval), and therefore, applications won't read the newly converted cmsg. All the work for nothing. Next, even if alignof(int64_t) == 8, struct timeval does not have the same padding as struct timespec, and so on big endian architectures, the code ends up writing the microseconds into the padding and clearing the tv_usec field. This can all be solved easily, if you just try to be a touch less clever. I am attaching a patch that makes the intent more obvious. It's not as flashy as the previous code. It doesn't have a switch with a goto in it. I hope it finds your favor. Ciao, Markus --MAMxKDMPUmdWtYzs Content-Type: text/x-diff; charset=us-ascii Content-Disposition: attachment; filename="0001-Fix-time64-conversion-of-SCM_TIMESTAMP.patch" Content-Transfer-Encoding: quoted-printable =46rom adf608ddce58d652fc074d54e580fb724c35705b Mon Sep 17 00:00:00 2001 From: Markus Wichmann Date: Fri, 2 Jun 2023 16:41:56 +0200 Subject: [PATCH] Fix time64 conversion of SCM_TIMESTAMP. On 32-bit archs, the newly created cmsg might get the wrong length (if alignof(int64_t) =3D=3D 4), and might write the microseconds in the wrong place (if byte order is big endian). Besides, the old code went a long way obscuring its intent to give preference to SCM_TIMESTAMPNS. Don't know what it would matter, since according to the documentation only one of these types can be enabled at one time. Unless the docs are wrong. =2D-- src/network/recvmsg.c | 47 ++++++++++++++++++++++++------------------- 1 file changed, 26 insertions(+), 21 deletions(-) diff --git a/src/network/recvmsg.c b/src/network/recvmsg.c index 03641625..d990c620 100644 =2D-- a/src/network/recvmsg.c +++ b/src/network/recvmsg.c @@ -12,39 +12,44 @@ void __convert_scm_timestamps(struct msghdr *msg, sock= len_t csize) if (SCM_TIMESTAMP =3D=3D SCM_TIMESTAMP_OLD) return; if (!msg->msg_control || !msg->msg_controllen) return; - struct cmsghdr *cmsg, *last=3D0; - long tmp; - long long tvts[2]; + struct cmsghdr *cmsg, *last=3D0, *found=3D0; int type =3D 0; + void *data; + size_t len; + struct timespec ts; + struct timeval tv; for (cmsg=3DCMSG_FIRSTHDR(msg); cmsg; cmsg=3DCMSG_NXTHDR(msg, cmsg)) { - if (cmsg->cmsg_level=3D=3DSOL_SOCKET) switch (cmsg->cmsg_type) { - case SCM_TIMESTAMP_OLD: - if (type) break; - type =3D SCM_TIMESTAMP; - goto common; - case SCM_TIMESTAMPNS_OLD: - type =3D SCM_TIMESTAMPNS; - common: - memcpy(&tmp, CMSG_DATA(cmsg), sizeof tmp); - tvts[0] =3D tmp; - memcpy(&tmp, CMSG_DATA(cmsg) + sizeof tmp, sizeof tmp); - tvts[1] =3D tmp; - break; + if (cmsg->cmsg_level=3D=3DSOL_SOCKET) { + if ((cmsg->cmsg_type =3D=3D SCM_TIMESTAMP_OLD && !found) + || cmsg->cmsg_type =3D=3D SCM_TIMESTAMPNS_OLD) + found =3D cmsg; } last =3D cmsg; } - if (!last || !type) return; - if (CMSG_SPACE(sizeof tvts) > csize-msg->msg_controllen) { + if (!found) return; + const long *old =3D (void *)CMSG_DATA(found); + if (found->cmsg_type =3D=3D SCM_TIMESTAMP_OLD) { + type =3D SCM_TIMESTAMP; + data =3D &tv; + len =3D sizeof tv; + tv =3D (struct timeval){.tv_sec =3D old[0], .tv_usec =3D old[1]}; + } else { + type =3D SCM_TIMESTAMPNS; + data =3D &ts; + len =3D sizeof ts; + ts =3D (struct timespec){.tv_sec =3D old[0], .tv_nsec =3D old[1]}; + } + if (CMSG_SPACE(len) > csize-msg->msg_controllen) { msg->msg_flags |=3D MSG_CTRUNC; return; } - msg->msg_controllen +=3D CMSG_SPACE(sizeof tvts); + msg->msg_controllen +=3D CMSG_SPACE(len); cmsg =3D CMSG_NXTHDR(msg, last); cmsg->cmsg_level =3D SOL_SOCKET; cmsg->cmsg_type =3D type; - cmsg->cmsg_len =3D CMSG_LEN(sizeof tvts); - memcpy(CMSG_DATA(cmsg), &tvts, sizeof tvts); + cmsg->cmsg_len =3D CMSG_LEN(len); + memcpy(CMSG_DATA(cmsg), data, len); } ssize_t recvmsg(int fd, struct msghdr *msg, int flags) =2D- 2.39.2 --MAMxKDMPUmdWtYzs--