Subject: Re: kernel ip_randomid() and libc randomid(3) still "broken"
To: Jun-ichiro itojun Hagino <itojun@itojun.org>
From: Robert Elz <kre@munnari.OZ.AU>
List: tech-net
Date: 11/26/2003 17:07:18
    Date:        Wed, 26 Nov 2003 07:11:47 +0900 (JST)
    From:        itojun@itojun.org (Jun-ichiro itojun Hagino)
    Message-ID:  <20031125221147.C0C428A@coconut.itojun.org>

  | 	so we can either:
  | 	- stop skipping random number of ids (n=0)
  | 	- reduce numbers on the manpage to 1/3
  | 	and then we are happpy.

The problem with all of this is that in order to make it a bit more
difficult to suffer from a (fairly unlikely) DoS type attack, you're
proposing breaking IP.

Personally, I don't think that's a worthwhile tradeoff, and this is
regardless of just how much it costs to implement (that it is a relatively
expensive algorithm just makes it even less attractive).

The ID field in IP packets is used to match fragments - we all know that.
In order to be effective, it needs to be unique, for any (src,dst,proto)
tuple for at least as long as the TTL in the last packet sent using that
tuple for the same ID.

Now, as currently implemented, NetBSD ignores the (src,dst,proto), meaning
that the ID needs to remain un-reused until the TTL in the packet sent
with it expires.

If we assume that we're using TTL=1 on an ethernet, this means that the
maximum data rate that we can possibly transmit at, and remain legal IP,
using the full range of ID values before any re-use, is about 780 Mbit/sec.
That is, if you have a Gb ether, and you're connected to it with NetBSD,
and you're transmitting flat out (somehow) then you're breaking IP
already.

In practice, this bothers none of us (except possibly Jonathan) as most
of us don't approach anything like those rates.

Even with a TTL of 64, where the max rate we can legally transmit at
using a single generator for all connections is only about 12 Mbit/sec,
most of us aren't going to see any real problems.

But you're proposing to divide that in half, and perhaps to just 20%.
2.5 Mbit/sec is definitely way too low - at that rate we're going to
start seeing reassembly botches - in theory these should be detected
by the transport checksums, but ...  (the IP checksum algorithm is not
very robust against some kinds of packet errors).

I'm not security competent enough to comment on whether or not that
"number discard" is required, if not, things don't get quite so bad.
They also get less bad if we were to stop using the same generator
for all possible tuples - but this doesn't help at all to the user
whose fast traffic is all on one TCP connection (or UDP).

Enforcing DF is really the solution here - but do that, and we cease
caring what the packet ID is - the random generator would be totally
worthless.

I really think that you, or whatever OpenBSD source is prompting this
supposed fix, to really go and analyse just what it is that you're
achieving - how likely the problem is that you claim to be remedying,
how easy  it would be for an attacker to find another avenue to achieve
the same result (ie: blocking traffic) given the same knowledge needed
to implement an ID spoofing fragmentation attack (that is, the same
ability to acquire knowledge), and see if there is really anything here
which warrants a fix in the first place, and second whether limiting
the ID space before wraparound is really an effective way of achieving it.

But please, don't just see "there's a potential DoS here, it must be
fixed, no matter the cost" - that's absurd.

kre