The ping received signal SIGABRT on lib32-qemux86-64 or lib32-qemuarm64 (64bit kernel + 32bit lib) with glibc 2.34. Kernel: 5.10 Glibc: 2.34 ping: iputils-20210722 root@qemux86-64:~# uname -a Linux qemux86-64 5.10.53-yocto-standard #1 SMP PREEMPT Sun Jul 25 15:15:01 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux root@qemux86-64:~# root@qemux86-64:~# iptables -F root@qemux86-64:~# iptables -A INPUT -p icmp --icmp-type 8 -j REJECT root@qemux86-64:~# ping -c1 127.0.0.1 PING 127.0.0.1 (127.0.0.1) 56(84) bytes of data. Aborted root@qemux86-64:~# On glibc 2.33, it works well: root@qemux86-64:~# iptables -F root@qemux86-64:~# iptables -A INPUT -p icmp --icmp-type 8 -j REJECT root@qemux86-64:~# ping -c1 127.0.0.1 PING 127.0.0.1 (127.0.0.1) 56(84) bytes of data. From 127.0.0.1 icmp_seq=1 Destination Port Unreachable --- 127.0.0.1 ping statistics --- 1 packets transmitted, 0 received, +1 errors, 100% packet loss, time 0ms This issue is introduced by glibc commit 13c51549e2077f2f3bf84e8fd0b46d8b0c615912: commit 13c51549e2077f2f3bf84e8fd0b46d8b0c615912 Author: Adhemerval Zanella <adhemerval.zanella@linaro.org> Date: Mon Sep 7 17:08:46 2020 -0300 linux: Add fallback for 64-bit time_t SO_TIMESTAMP{NS} Here are some gdb outputs: $ gdb ping Reading symbols from ping... Reading symbols from /bin/.debug/ping.iputils... (gdb) set args -c1 127.0.0.1 (gdb) b ping4_receive_error_msg Breakpoint 1 at 0x5ae0: file ../git/ping/ping.c, line 1293. (gdb) r Starting program: /bin/ping -c1 127.0.0.1 PING 127.0.0.1 (127.0.0.1) 56(84) bytes of data. Breakpoint 1, ping4_receive_error_msg (rts=0xffffaa20, sock=0xffffa9f0) at ../git/ping/ping.c:1293 1293 { (gdb) n 1304 int saved_errno = errno; (gdb) n 1306 iov.iov_base = &icmph; (gdb) p saved_errno $1 = 111 (gdb) n 1308 msg.msg_name = (void *)⌖ (gdb) 1310 msg.msg_iov = &iov; (gdb) 1312 msg.msg_flags = 0; (gdb) 1313 msg.msg_control = cbuf; (gdb) 1314 msg.msg_controllen = sizeof(cbuf); (gdb) 1316 res = recvmsg(sock->fd, &msg, MSG_ERRQUEUE | MSG_DONTWAIT); (gdb) s __libc_recvmsg (fd=3, msg=0xffff9120, flags=8256) at ../sysdeps/unix/sysv/linux/recvmsg.c:25 25 { (gdb) n 28 socklen_t orig_controllen = msg != NULL ? msg->msg_controllen : 0; (gdb) p *msg $2 = {msg_name = 0xffff913c, msg_namelen = 16, msg_iov = 0xffff9110, msg_iovlen = 1, msg_control = 0xffff914c, msg_controllen = 512, msg_flags = 0} (gdb) n 34 r = SOCKETCALL_CANCEL (recvmsg, fd, msg, flags); (gdb) n 38 if (r >= 0 && orig_controllen != 0) (gdb) n 39 __convert_scm_timestamps (msg, orig_controllen); (gdb) p *msg $3 = {msg_name = 0xffff913c, msg_namelen = 16, msg_iov = 0xffff9110, msg_iovlen = 1, msg_control = 0xffff914c, msg_controllen = 64, msg_flags = 8224} (gdb) n 42 return r; (gdb) p *msg $4 = {msg_name = 0xffff913c, msg_namelen = 16, msg_iov = 0xffff9110, msg_iovlen = 1, msg_control = 0xffff914c, msg_controllen = 92, msg_flags = 8224} (gdb) n ping4_receive_error_msg (rts=0xffffaa20, sock=0xffffa9f0) at ../git/ping/ping.c:1317 1317 if (res < 0) { (gdb) p res $5 = 8 (gdb) n 1324 for (cmsgh = CMSG_FIRSTHDR(&msg); cmsgh; cmsgh = CMSG_NXTHDR(&msg, cmsgh)) { (gdb) n 1325 if (cmsgh->cmsg_level == SOL_IP) { (gdb) p *cmsgh $6 = {cmsg_len = 20, cmsg_level = 1, cmsg_type = 29, __cmsg_data = 0xffff9158 "]\212EaG@\016"} (gdb) n 1324 for (cmsgh = CMSG_FIRSTHDR(&msg); cmsgh; cmsgh = CMSG_NXTHDR(&msg, cmsgh)) { (gdb) n 1325 if (cmsgh->cmsg_level == SOL_IP) { (gdb) p *cmsgh $7 = {cmsg_len = 28, cmsg_level = 1, cmsg_type = 63, __cmsg_data = 0xffff916c "]\212Ea"} (gdb) n 1324 for (cmsgh = CMSG_FIRSTHDR(&msg); cmsgh; cmsgh = CMSG_NXTHDR(&msg, cmsgh)) { (gdb) n 1325 if (cmsgh->cmsg_level == SOL_IP) { (gdb) p *cmsgh $8 = {cmsg_len = 2, cmsg_level = 16777343, cmsg_type = 0, __cmsg_data = 0xffff9188 ""} (gdb) n 1324 for (cmsgh = CMSG_FIRSTHDR(&msg); cmsgh; cmsgh = CMSG_NXTHDR(&msg, cmsgh)) { (gdb) n 1330 if (e == NULL) (gdb) n 1331 abort(); (gdb) n Program received signal SIGABRT, Aborted. 0xf7fc9549 in __kernel_vsyscall () (gdb)
We need to disable recvmsg time64 emulation for time32 calls, it causes too many issues.
(In reply to Florian Weimer from comment #1) > We need to disable recvmsg time64 emulation for time32 calls, it causes too > many issues. I don't think we need to resort on this change, the issue is in fact that __convert_scm_timestamps does not correctly update the last cmsg. With the following patch it fixes the regression: diff --git a/sysdeps/unix/sysv/linux/convert_scm_timestamps.c b/sysdeps/unix/sysv/linux/convert_scm_timestamps.c index 00c934c413..4da2c60799 100644 --- a/sysdeps/unix/sysv/linux/convert_scm_timestamps.c +++ b/sysdeps/unix/sysv/linux/convert_scm_timestamps.c @@ -55,7 +55,10 @@ __convert_scm_timestamps (struct msghdr *msg, socklen_t msgsize) cmsg = CMSG_NXTHDR (msg, cmsg)) { if (cmsg->cmsg_level != SOL_SOCKET) - continue; + { + last = cmsg; + continue; + } switch (cmsg->cmsg_type) { I will work on a patch along with a testcase.
The master branch has been updated by Adhemerval Zanella <azanella@sourceware.org>: https://sourceware.org/git/gitweb.cgi?p=glibc.git;h=21e0f45c7d73df6fe30c77ffcc9f81410e2ee369 commit 21e0f45c7d73df6fe30c77ffcc9f81410e2ee369 Author: Adhemerval Zanella <adhemerval.zanella@linaro.org> Date: Mon Sep 27 16:07:08 2021 -0300 linux: Fix ancillary 64-bit time timestamp conversion (BZ #28349, BZ #28350) The __convert_scm_timestamps() only updates the control message last pointer for SOL_SOCKET type, so if the message control buffer contains multiple ancillary message types the converted timestamp one might overwrite a valid message. The test check if the extra ancillary space is correctly handled by recvmsg/recvmmsg, where if there is no extra space for the 64-bit time_t converted message the control buffer should be marked with MSG_TRUNC. It also check if recvmsg/recvmmsg handle correctly multiple ancillary data. Checked on x86_64-linux and on i686-linux-gnu on both 5.11 and 4.15 kernel. Co-authored-by: Fabian Vogt <fvogt@suse.de>
The master branch has been updated by Adhemerval Zanella <azanella@sourceware.org>: https://sourceware.org/git/gitweb.cgi?p=glibc.git;h=572e0c855495bfbcd2323584a243430e6b7c8bb3 commit 572e0c855495bfbcd2323584a243430e6b7c8bb3 Author: Adhemerval Zanella <adhemerval.zanella@linaro.org> Date: Wed Jan 12 10:35:06 2022 -0300 Revert "linux: Fix ancillary 64-bit time timestamp conversion (BZ #28349, BZ #28350)" This reverts commit 21e0f45c7d73df6fe30c77ffcc9f81410e2ee369.
Fixed on 2.35.