Bugtraq mailing list archives

FreeBSD Security Advisory: FreeBSD-SA-00:23.ip-options


From: security-advisories () FREEBSD ORG (FreeBSD Security Advisories)
Date: Thu, 22 Jun 2000 14:50:52 -0700


-----BEGIN PGP SIGNED MESSAGE-----

=============================================================================
FreeBSD-SA-00:23                                           Security Advisory
                                                                FreeBSD, Inc.

Topic:          Remote denial-of-service in IP stack

Category:       core
Module:         kernel
Announced:      2000-06-19
Affects:        FreeBSD systems prior to the correction date
Credits:        NetBSD Security Advisory 2000-002, and
                Jun-ichiro itojun Hagino <itojun () kame net>
Corrected:      (Several bugs fixed, the date below is that of the most
                recent fix)
                2000-06-08 (3.4-STABLE)
                2000-06-08 (4.0-STABLE)
                2000-06-02 (5.0-CURRENT)
FreeBSD only:   NO

I.   Background

II.  Problem Description

There are several bugs in the processing of IP options in the FreeBSD
IP stack, which fail to correctly bounds-check arguments and contain
other coding errors leading to the possibility of data corruption and
a kernel panic upon reception of certain invalid IP packets.

This set of bugs includes the instance of the vulnerability described
in NetBSD Security Advisory 2000-002 (see
ftp://ftp.NetBSD.ORG/pub/NetBSD/misc/security/advisories/NetBSD-SA2000-002.txt.asc)
as well as other bugs with similar effect.

III. Impact

Remote users can cause a FreeBSD system to panic and reboot.

IV.  Workaround

None available.

V.   Solution

One of the following:

1) Upgrade your FreeBSD system to 3.4-STABLE, 4.0-STABLE or
5.0-CURRENT after the respective correction dates.

2) Apply the patch below and recompile your kernel.

Either save this advisory to a file, or download the patch and
detached PGP signature from the following locations, and verify the
signature using your PGP utility.

ftp://ftp.freebsd.org/pub/FreeBSD/CERT/patches/SA-00:23/ip_options.diff
ftp://ftp.freebsd.org/pub/FreeBSD/CERT/patches/SA-00:23/ip_options.diff.asc

# cd /usr/src/sys/netinet
# patch -p < /path/to/patch_or_advisory

[ Recompile your kernel as described in
http://www.freebsd.org/handbook/kernelconfig.html and reboot the
system ]

    Index: ip_icmp.c
    ===================================================================
    RCS file: /ncvs/src/sys/netinet/ip_icmp.c,v
    retrieving revision 1.39
    diff -u -r1.39 ip_icmp.c
    --- ip_icmp.c       2000/01/28 06:13:09     1.39
    +++ ip_icmp.c       2000/06/08 15:26:39
    @@ -662,8 +662,11 @@
                                 if (opt == IPOPT_NOP)
                                         len = 1;
                                 else {
    +                               if (cnt < IPOPT_OLEN + sizeof(*cp))
    +                                       break;
                                         len = cp[IPOPT_OLEN];
    -                               if (len <= 0 || len > cnt)
    +                               if (len < IPOPT_OLEN + sizeof(*cp) ||
    +                                   len > cnt)
                                                 break;
                                 }
                                 /*
    Index: ip_input.c
    ===================================================================
    RCS file: /ncvs/src/sys/netinet/ip_input.c,v
    retrieving revision 1.130
    diff -u -r1.130 ip_input.c
    --- ip_input.c      2000/02/23 20:11:57     1.130
    +++ ip_input.c      2000/06/08 15:25:46
    @@ -1067,8 +1067,12 @@
                     if (opt == IPOPT_NOP)
                             optlen = 1;
                     else {
    +                   if (cnt < IPOPT_OLEN + sizeof(*cp)) {
    +                           code = &cp[IPOPT_OLEN] - (u_char *)ip;
    +                           goto bad;
    +                   }
                             optlen = cp[IPOPT_OLEN];
    -                   if (optlen <= 0 || optlen > cnt) {
    +                   if (optlen < IPOPT_OLEN + sizeof(*cp) || optlen > cnt) {
                                     code = &cp[IPOPT_OLEN] - (u_char *)ip;
                                     goto bad;
                             }
    @@ -1174,6 +1178,10 @@
                             break;

                     case IPOPT_RR:
    +                   if (optlen < IPOPT_OFFSET + sizeof(*cp)) {
    +                           code = &cp[IPOPT_OFFSET] - (u_char *)ip;
    +                           goto bad;
    +                   }
                             if ((off = cp[IPOPT_OFFSET]) < IPOPT_MINOFF) {
                                     code = &cp[IPOPT_OFFSET] - (u_char *)ip;
                                     goto bad;
    Index: ip_output.c
    ===================================================================
    RCS file: /ncvs/src/sys/netinet/ip_output.c,v
    retrieving revision 1.99
    diff -u -r1.99 ip_output.c
    --- ip_output.c     2000/03/09 14:57:15     1.99
    +++ ip_output.c     2000/06/08 15:27:08
    @@ -1302,8 +1302,10 @@
                     if (opt == IPOPT_NOP)
                             optlen = 1;
                     else {
    +                   if (cnt < IPOPT_OLEN + sizeof(*cp))
    +                           goto bad;
                             optlen = cp[IPOPT_OLEN];
    -                   if (optlen <= IPOPT_OLEN || optlen > cnt)
    +                   if (optlen < IPOPT_OLEN + sizeof(*cp) || optlen > cnt)
                                     goto bad;
                     }
                     switch (opt) {

-----BEGIN PGP SIGNATURE-----
Version: 2.6.2

iQCVAwUBOU3tLFUuHi5z0oilAQGR8AP/UbWPEYtE9Z5UAlesutOSp6UcHnl+6Gga
nglpEBloBsf81J53nkLbf02rWQedb1BhROL1i+df9J328sCF/Tpci04bmdSAtiox
EwDim4AlTjn4PqjlHyX1jf1mi0sMgxSuI5bBPuiVfsdYRbd96+AEbftfR9BuyqbB
m6dFcBN5+y0=
=A1Fk
-----END PGP SIGNATURE-----


Current thread: