From owner-freebsd-bugs Fri Mar 24 10:10: 8 2000 Delivered-To: freebsd-bugs@freebsd.org Received: from freefall.freebsd.org (freefall.FreeBSD.ORG [204.216.27.21]) by hub.freebsd.org (Postfix) with ESMTP id 0951D37BC39 for ; Fri, 24 Mar 2000 10:10:02 -0800 (PST) (envelope-from gnats@FreeBSD.org) Received: (from gnats@localhost) by freefall.freebsd.org (8.9.3/8.9.2) id KAA15572; Fri, 24 Mar 2000 10:10:01 -0800 (PST) (envelope-from gnats@FreeBSD.org) Received: from salmon.maths.tcd.ie (salmon.maths.tcd.ie [134.226.81.11]) by hub.freebsd.org (Postfix) with SMTP id CD70537B885 for ; Fri, 24 Mar 2000 10:06:10 -0800 (PST) (envelope-from iedowse@maths.tcd.ie) Received: from walton.maths.tcd.ie by salmon.maths.tcd.ie with SMTP id ; 24 Mar 2000 18:06:08 +0000 (GMT) Message-Id: <200003241806.aa98076@walton.maths.tcd.ie> Date: Fri, 24 Mar 2000 18:06:08 +0000 (GMT) From: iedowse@maths.tcd.ie Reply-To: iedowse@maths.tcd.ie To: FreeBSD-gnats-submit@freebsd.org X-Send-Pr-Version: 3.2 Subject: kern/17583: NETATALK code can corrupt mbuf free lists Sender: owner-freebsd-bugs@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.org >Number: 17583 >Category: kern >Synopsis: NETATALK code can corrupt mbuf free lists >Confidential: no >Severity: serious >Priority: low >Responsible: freebsd-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: sw-bug >Submitter-Id: current-users >Arrival-Date: Fri Mar 24 10:10:01 PST 2000 >Closed-Date: >Last-Modified: >Originator: Ian Dowse >Release: FreeBSD 3.4-STABLE i386 >Organization: School of Mathematics Trinity College, Dublin >Environment: FreeBSD -current, but problem exists in 4.0-STABLE and 3.x >Description: In certain circumstances, the NETATALK code can cause an mbuf chain to be freed multiple times. The code uses a 'struct aarptab' to store information about appletalk addresses, which includes an mbuf pointer 'aap_hold'. In most places, the code is careful about ensuring that mbuf chains referenced by this mechanism are freed only once, but there is a subtle problem in at_aarpinput(). The code fragment looks something like: if (aat->aat_hold != NULL) { (*ac->ac_if.if_output)(&ac->ac_if, aat->aat_hold, ...); aat->aat_hold = NULL; } The problem here is that when if_output() is called, aat->aat_hold contains a non-NULL pointer. If the interface if_output routine calls aarpresolve(), then aarpresolve() may free aat->aat_hold. This can result in aat_hold being m_freem'd twice, since if_output will also free it. The simple solution is to ensure that aat_hold is NULLed out before calling the if_output routine. The patch below does this by copying the mbuf pointer into a local variable so that aat->aat_hold can be NULL when if_output is called. >How-To-Repeat: Connecting a FreeBSD router to a busy network seemed to trigger this problem every few hours, but it should be easy to construct a sequence of packet arrivals which cause it directly. >Fix: --- aarp.c.orig Fri Mar 24 16:26:08 2000 +++ aarp.c Fri Mar 24 17:48:12 2000 @@ -393,12 +393,20 @@ sizeof( ea->aarp_sha )); aat->aat_flags |= ATF_COM; if ( aat->aat_hold ) { + struct mbuf *mhold; + + /* + * We must NULL out the aat->aat_hold pointer, since otherwise + * if_output may call aarpresolve() which could m_freem() it. + */ + mhold = aat->aat_hold; + aat->aat_hold = NULL; + sat.sat_len = sizeof(struct sockaddr_at); sat.sat_family = AF_APPLETALK; sat.sat_addr = spa; - (*ac->ac_if.if_output)( &ac->ac_if, aat->aat_hold, + (*ac->ac_if.if_output)( &ac->ac_if, mhold, (struct sockaddr *)&sat, NULL); /* XXX */ - aat->aat_hold = 0; } } >Release-Note: >Audit-Trail: >Unformatted: To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-bugs" in the body of the message