Subject: Re: bin/35479: /usr/sbin/timedc fails
To: Christian Biere <christianbiere@gmx.de>
From: Woodchuck <djv@bedford.net>
List: netbsd-bugs
Date: 01/26/2007 12:28:17
On Fri, 26 Jan 2007, Christian Biere wrote:

> 
> Alright, so OpenBSD won't reply to requests from ports below 1024 or the NFS port.
> The issue is in OpenBSD (inetd) and not in NetBSD. Their implementation is not
> compatible with any other and it's not documented either.

Agreed!  The FreeBSD implementation is yet a "third way", but is
similar to NetBSD's.  (They loop through a bunch of sockets, see
their routine "check_loop" in inetd.c  Without a lot of analysis,
it looks to me like they forbid service to a source port that is
the same as any dgram service that the host has open -- weak. If
Host A doesn't have "echo" open, it will receive from the echo port,
and service a time/udp request, say, returning to Host B's echo
port.  (Maybe. Probably.  I haven't walked through the code.) The
number of "likely suspects" is small enough that the NetBSD use of
a list is fully adequate and more flexible, easy to patch if a new
threat arises from some non-Unix source.)

OpenBSD has incorporated a security ~policy~ at this level, whereas
such a policy could probably be incorporated elsewhere, or at least
be switchable.  It refuses service to "innocent sources".  Inetd should
be *protocol*, not *policy* in a "perfect" world.

I have no idea what Windoze does.  Probably locks up or sends spam. 

> I don't see a good and clean way to work around this in NetBSD. One option would
> be a command-line parameter to use an unprivileged port. This would still fail
> in a mixed environment. Another is to use two sockets and send everything twice.

Why?  NetBSD's inetd doesn't require a privileged source port.
The question is why NetBSD's timedc uses one.  It looks like
a vestige of an earlier day, unless I am missing something.

It can't be "trust"; timedc is setuid.  Unprivileged source ports
are serviced happily by netbsd's inetd time/udp service:

Rachel: OpenBSD  Jezebel: NetBSD   timedc "clockdiff jezebel" run on rachel:

11:37:16.032983 IP rachel.chuck > jezebel.chuck: icmp 28: time stamp query id 11879 seq 38400
11:37:16.033047 IP jezebel.chuck > rachel.chuck: icmp 28: time stamp reply id 11879 seq 38400 : org 0x3910666 recv 0x3910681 xmit 0x3910681
11:37:16.033251 IP rachel.chuck.12987 > jezebel.chuck.time: UDP, length: 4
11:37:16.034860 IP jezebel.chuck.time > rachel.chuck.12987: UDP, length: 4

> Or NetBSD could behave as OpenBSD and break interoperability with itself and
> any other implementation.

No one is proposing any bug in, feature lacking in, or other
modification to NetBSD's inetd server.  Ain't broke; don't need
fixed.

On the other hand, would using an unprivileged port in timedc.c
break interoperability with anything?  It would seem to increase
interoperability.

In a world of a half-billion Windoze-running "roots", and
another 200 million hand-cranked Ubuntu laptops about to be
heli-dropped on the third world, what does the use of a privileged
port get you?  Are there NetBSD daemons, running out of inetd, that
trust service requests because they come from a privileged port?
Are there inetd-managed daemons that require a privileged source
port?  Both those questions probably have the answer "NO".  Perhaps
there is some special case?  It's certainly not the case in the
builtins, and the externals are in their own worlds.  They can make
that policy decision for themselves.

Why should a random non-root/non-sudo user on NetBSD be able to run
timedc successfully?  Dropping the setuid from timedc might be a
reasonable consideration.  There is a certain amount of mischief
possible with timedc, if hosts are running timed.  "Default deny"
is a safe approach, and it is easy to add sudo permissions to a user.

> I think their "fix" is pretty half-assed, so I wouldn't follow that route.

I do not propose it.  Leave NetBSD's inetd alone; but please consider
using a non-privileged source port for timedc and consider (as a separate,
unrelated issue) dropping default setuid from the timedc executable.

Yours,

Dave