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.