3 ms·
Why does ping on Linux call bind()?
I noticed earlier that ping (mine is from iputils [0]) calls bind():
rascul@smarts:~> strace -fe bind ping -c1 google.com > /dev/null
bind(5, {sa_family=AF_NETLINK, nl_pid=0, nl_groups=00000000}, 12) = 0
+++ exited with 0 +++
This confused me, because I didn't understand why ping needed to bind(). I understood ping to send an ICMP echo request and time the reply [1]. I wasn't sure why ping needed to act as a server for this. This appears to be Netlink related, according to the sa_family in the bind() call.
I asked about this on IRC, the #linux [2] channel on Libera [3]. Several people helped do some digging, and it looks like it might come from a getaddrinfo() call, but we weren't able to verify that. We noticed that bind() isn't called for some hosts:
rascul@smarts:~> strace -fe bind ping -c1 kernel.org > /dev/null
+++ exited with 0 +++
Nor is bind() called for ip addresses:
rascul@smarts:~> strace -fe bind ping -c1 9.9.9.9 > /dev/null
+++ exited with 0 +++
I wasn't able to test it at the time, but I was informed that ping from busybox sometimes calls bind() also.
I don't know that there's any security implications involved, but mostly I'm just curious, why does ping call bind()? It would be great if anyone was able to help shed some light on this.
[0] https://github.com/iputils/iputils/blob/master/ping/ping.c
[1] https://en.wikipedia.org/wiki/Internet_Control_Message_Protocol
[2] https://linux.chat/linux-on-libera/
[3] https://libera.chat/
- wmf 5y agoMy next step would be to capture a stack trace to find out where bind() is being called, then examine that code. See https://www.brendangregg.com/perf.html#StaticKernelTracing https://www.brendangregg.com/perf.html#StaticKernelTracing
- theamk 5y agoThis link is for kernel stack tracking and the OP has the question about userspace call. You want gdb for that.
- theamk 5y agoAm I missing something? this seems trivial.... $ sudo gdb --args ping -c1 google.com ... Reading symbols from ping...(no debugging symbols found)...done. (gdb) break bind Breakpoint 1 at 0x2e30 (gdb) run Starting program: /bin/ping -c1 google.com Breakpoint 1, bind () at ../sysdeps/unix/syscall-template.S:78 78 ../sysdeps/unix/syscall-template.S: No such file or directory. (gdb) bt #0 bind () at ../sysdeps/unix/syscall-template.S:78 #1 0x00007fe80c66967c in __check_pf (seen_ipv4=seen_ipv4@entry=0x7ffd63cff8e2, seen_ipv6=seen_ipv6@entry=0x7ffd63cff8e3, in6ai=in6ai@entry=0x7ffd63cff8f0, in6ailen=in6ailen@entry=0x7ffd63cff8f8) at ../sysdeps/unix/sysv/linux/check_pf.c:326 #2 0x00007fe80c630651 in __GI_getaddrinfo (name=<optimized out>, service=<optimized out>, hints=<optimized out>, pai=0x7ffd63cffdc0) at ../sysdeps/posix/getaddrinfo.c:2354 #3 0x000055c067f89870 in ?? () #4 0x00007fe80c549bf7 in __libc_start_main (main=0x55c067f88ff0, argc=3, argv=0x7ffd63cfff28, init=<optimized out>, fini=<optimized out>, rtld_fini=<optimized out>, stack_end=0x7ffd63cfff18) at ../csu/libc-start.c:310 #5 0x000055c067f89caa in ?? () yes, this is getaddrinfo. If you want to debug more, install the debug packages and play with gdb.