Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 26 Apr 2004 00:07:03 +0800 (KRAST)
From:      Eugene Grosbein <eugen@grosbein.pp.ru>
To:        FreeBSD-gnats-submit@FreeBSD.org
Cc:        luigy@FreeBSD.org
Subject:   bin/65961: ipfw2 memory corruption inside add()
Message-ID:  <200404251607.i3PG73as002417@grosbein.pp.ru>
Resent-Message-ID: <200404251610.i3PGAJso084908@freefall.freebsd.org>

next in thread | raw e-mail | index | archive | help

>Number:         65961
>Category:       bin
>Synopsis:       ipfw2 memory corruption inside add()
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Sun Apr 25 09:10:19 PDT 2004
>Closed-Date:
>Last-Modified:
>Originator:     Eugene Grosbein
>Release:        FreeBSD 4.10-PRERELEASE i386
>Organization:
Svyaz Service JSC
>Environment:
System: FreeBSD grosbein.pp.ru 4.10-PRERELEASE FreeBSD 4.10-PRERELEASE #1: Sun Apr 25 13:29:39 KRAST 2004 eu@grosbein.pp.ru:/usr/local/obj/usr/local/src/sys/DADV i386

>Description:
	ipfw2 supports or-blocks that may have variable length.
	A function add() in ipfw2.c uses fixed-length arrays
	and does not check for overflows. Hence, memory structure corruption
	occurs while very long or-block is passed from a command line.

	This results in segmentation faults or even enless loops
	when ipfw2 eats all available CPU cycles.

>How-To-Repeat:

	The next script takes a number (n) and creates syntactical correct
	'ipfw add' rule with or-block containing of n+1 IP address.

#!/bin/sh

args="add 60001 count ip from any to { "

for i in `jot $1 1`
do
  args="${args}127.0.0.$i or "
done
args="${args}127.0.1.1 }";

ipfw delete 60001
echo ipfw $args
ipfw $args

	"./test 121" works.
	"./test 123" leads to corruption of actbuf[] and th cycle
	does not finish because variable i gets zero value:

        /*
         * copy all other actions
         */
        for (src = (ipfw_insn *)actbuf; src != action; src += i) {
                i = F_LEN(src);
                bcopy(src, dst, i * sizeof(uint32_t));
                dst += i;
        }

	"./test 500" leads to segmentation fault inside exit():

Core was generated by 	pfw'.
Program terminated with signal 11, Segmentation fault.
#0  0x8072648 in exit ()
(gdb) bt
#0  0x8072648 in exit ()
#1  0x8054970 in warn ()
#2  0x80548de in errx ()
#3  0x804bda0 in fill_ip (cmd=0x808d098, av=0x809e0f0 "127.0.0.256")
    at /usr/local/src/sbin/ipfw/ipfw2.c:1932
#4  0x804da76 in add_dstip (cmd=0x808d098, av=0x809e0f0 "127.0.0.256")
    at /usr/local/src/sbin/ipfw/ipfw2.c:2669
#5  0x804e90e in add (ac=492, av=0x809b818)
    at /usr/local/src/sbin/ipfw/ipfw2.c:3052
#6  0x80505ba in ipfw_main (oldac=1010, oldav=0xbfbfcea4)
    at /usr/local/src/sbin/ipfw/ipfw2.c:3793
#7  0x8050eb4 in main (ac=1011, av=0xbfbfcea0)
    at /usr/local/src/sbin/ipfw/ipfw2.c:3966

>Fix:

	Document limits of or-block length and implement sanity checks.

Eugene Grosbein
>Release-Note:
>Audit-Trail:
>Unformatted:



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200404251607.i3PG73as002417>