Yes, this will be a blogpost where I bitch some more about NetBSD.
A couple of hours ago I was reading through the openbsd 3.9 -> 4.0 changes. One of them stated “Fix signal races in ping(8)”. So I looked at OpenBSD’s ping.c and there was indeed a fix for a signal race. I figured, let’s check NetBSD, since they still have a lot of shared code, there might be simular races in NetBSD’s ping code.
And thus, I go to NetBSD’s cvsweb and look at ping.c and while reading it I though to myself “well, this is odd, there is no socket() and privdrop before argument parsing” (and some people might already see where I’m going with this). socket() was indeed after argument parsing, but I couldn’t see the privdrop code. So I search for setuid, seteuid, setreuid, setresuid. NOTHING !, absolutely NOTHING. Do my eyes deceive me ? I must have missed something, it cannot be this bad !
I must have spend an hour digging through their code,
looking for the missing privdrop. thinking to myself “maybe it’s abstracted away in some ugly and nasty way, or maybe it’s in some library code”. But I found nothing that indicated any of that. Then it sort of hit me, THERE IS NO PRIVDROP IN NetBSD’S PING IMPLEMENTATION.
Still in disbelieve I decided I needed to test this, so I recompile NetBSD’s ping from source and add the following right before it exits:
printf(”euid: %u\n”, geteuid());
the output I got:
ping -c 1 127.0.0.1
PING localhost (127.0.0.1): 56 data bytes
64 bytes from 127.0.0.1: icmp_seq=0 ttl=255 time=0.065 ms
—-localhost PING statistics—-
1 packets transmitted, 1 packets received, 0.0% packet loss
round-trip min/avg/max/stddev = 0.065/0.065/0.065/0.000 ms
euid: 0
I am Shocked and horrified. You’d expect this kind of glitches from apple (who added a privdrop to ping and traceroute about a year ago !) but from NetBSD ? It’s 2006 for fucks sake !! I compared with OpenBSD and FreeBSD, both added a privdrop OVER A DECADE AGO !
I decided to look at NetBSD’s traceroute aswell, after all, who knows, they might be consistent in not having privdrop code. They did mildly better in traceroute. There was a privdrop, AFTER argument parsing.
Ofcourse, you could argue that you don’t need a privdrop, as long as you don’t have any [security] bugs. But euh, you know, I mentioned these signal race conditions earlier …
as a final note, I went through all of the ping.c commit messages for NetBSD and some of them stated something about an overrun and some fd_set overflows, but I couldn’t find anything about this in their advisories.