COMMAND
kernel
SYSTEMS AFFECTED
NetBSD 1.4.2 and prior; NetBSD-current until 20000507
PROBLEM
Matt Hargett and Erik Fair discovered and repored the first
problem, Jason Thorpe for analysed the problem and implemented
the fixes for it, and Bill Sommerfeld ffound and fixed the second
problem. Receipt of IP packets with certain sequences of
malformed IP options can cause an unaligned access in kernel mode
(on many architectures), or data corruption, resulting in a panic
or other problems.
There are two problems. One is the result of an interaction
between a relatively new optimization performed by GCC and a code
fragment which violates ANSI C, as well as insufficient
protection of some data structures from alignment changes by the
compiler. The second problem (uncovered while testing fixes to
the first) involves several incorrect range checks due to a
computation involving a mix of signed and unsigned values. Either
or both of these problems may be present in other 4.4BSD-derived
systems.
IP packets can contain optional processing directives, which may
be examined both by the destination system of the packet, as well
as by intermediate routers. These options can be malformed, if
constructed randomly or maliciously. Tools to construct such
packets are widely available and in common use.
1) Alignment problems
=====================
The first problem arises because more aggressive optimisations
added in recent compilers made previously marginal code unsafe:
* In ip_input.c, in the code fragment that processes the IP
Timestamp option, an illegal type cast was performed from an
unaligned pointer to something needing more strict alignment;
this is disallowed by the ANSI C standard. This interacted
poorly with an optimization that GCC performed on the code
fragment; the compiler inlined a call to memcpy(), and due to
the illegal type cast, emitted a load-store of a single 32-bit
value.
* In ip.h, several structures used to describe over-the-wire data
required "__attribute__((__packed__))" to prevent the compiler
making unwarranted assumptions about the alignment of the
structures.
Either of these may cause the kernel to make an unaligned access.
This unaligned access will result in a fault and a panic or other
problems on many architectures:
* It is known to produce alignment fault panics on the alpha,
sparc and sparc64 architectures; others affected may include
mips and sh3.
* On some architectures, for example the arm32, misaligned
accesses do not produce faults, instead they produce incorrect
data; these systems will not panic, but instead suffer other
problems, such as exhaustion of the mbuf cluster pool.
* Other platforms, including the i386, m68k, pc532 and vax do not
have alignment checking requirements and so are unaffected by
this issue.
Because this involves an interaction with compiler optimisations,
its appearance and behaviour depend on the compiler flags used.
For example, the second problem (ip.h) does not occur when the
code is compiled specifically for Alpha 21164a or higher
processors with bwx extensions; in that case the compiler uses
the added byte load/store instructions and there is no alignment
problem. As a result, it took some additional time for this
problem to be found and fixed; unfortunately this was after the
release of NetBSD 1.4.2.
2) Incorrect range-checking
===========================
In the course of exhaustively testing the fix and related code,
the second problem cited above was uncovered. A malformed option
can induce the system to overwrite four bytes of memory near the
packet. This may quietly corrupt user data or cause a crash
depending on exactly what is overwritten. In order to sanity-check
incoming messages, range checks of the following general form were
used:
if (off > len - sizeof(...))
goto error;
Because sizeof() yields an unsigned value, C requires
"len - sizeof()" to be computed as an unsigned value. If len is
less than the value of sizeof(), the subtraction silently
underflows and yields a large positive value. As a result, the
options processing code may continue on to overwrite 4 bytes of
memory near the packet buffer with one of its ip addresses. This
problem was detected when internal consistency checks within the
NetBSD pool memory allocator (which are enabled by default)
determined that a free mbuf had been overwritten.
All architectures are vulnerable to this problem. Because of
differences in type sizes and structure layout, the exact offsets
which cause trouble, and therefore the packet contents that can be
used to exploit the problem, will vary from architecture to
architecture.
SOLUTION
The fix involves changes to two files. Because part of the fix
was included in NetBSD 1.4.2, different patch files have been
made available for NetBSD 1.4.1 and NetBSD 1.4.2. For all NetBSD
versions, you need to download the source patch, apply it to your
kernel source tree using the patch(1) command, and rebuild,
install the kernel, and reboot. For more information on how to do
this, see:
http://www.netbsd.org/Documentation/kernel/#building_a_kernel
For NetBSD 1.4.1 (and earlier):
===============================
A patch is available which contains changes to ip_input.c and
ip.h, located at:
ftp://ftp.NetBSD.ORG/pub/NetBSD/misc/security/patches/20000507-ipopt141
For NetBSD 1.4.2:
=================
A patch is available which contains changes to ip_input.c and
ip.h, located at:
ftp://ftp.NetBSD.ORG/pub/NetBSD/misc/security/patches/20000507-ipopt142
These changes have been pulled up to the 1.4.x release branch;
users tracking this branch via cvs should update to a source tree
dated 20000507 or later.
For NetBSD-current:
===================
NetBSD-current since 20000506 contains all the fixes, and is not
vulnerable. Users of NetBSD-current should upgrade to a source
tree dated 20000507 or later.