From nobody@FreeBSD.org  Wed Apr  4 14:59:52 2012
Return-Path: <nobody@FreeBSD.org>
Received: from mx1.freebsd.org (mx1.freebsd.org [69.147.83.52])
	by hub.freebsd.org (Postfix) with ESMTP id 48DCE1065672
	for <freebsd-gnats-submit@FreeBSD.org>; Wed,  4 Apr 2012 14:59:52 +0000 (UTC)
	(envelope-from nobody@FreeBSD.org)
Received: from red.freebsd.org (red.freebsd.org [IPv6:2001:4f8:fff6::22])
	by mx1.freebsd.org (Postfix) with ESMTP id 1AF9D8FC08
	for <freebsd-gnats-submit@FreeBSD.org>; Wed,  4 Apr 2012 14:59:52 +0000 (UTC)
Received: from red.freebsd.org (localhost [127.0.0.1])
	by red.freebsd.org (8.14.4/8.14.4) with ESMTP id q34ExpsM042991
	for <freebsd-gnats-submit@FreeBSD.org>; Wed, 4 Apr 2012 14:59:51 GMT
	(envelope-from nobody@red.freebsd.org)
Received: (from nobody@localhost)
	by red.freebsd.org (8.14.4/8.14.4/Submit) id q34ExpRS042990;
	Wed, 4 Apr 2012 14:59:51 GMT
	(envelope-from nobody)
Message-Id: <201204041459.q34ExpRS042990@red.freebsd.org>
Date: Wed, 4 Apr 2012 14:59:51 GMT
From: Andrew Atrens <andrew@atrens.ca>
To: freebsd-gnats-submit@FreeBSD.org
Subject: mbuf/cluster leak in AP mode in 802.11 power saving support
X-Send-Pr-Version: www-3.1
X-GNATS-Notify:

>Number:         166641
>Category:       kern
>Synopsis:       [ieee80211] [patch] mbuf/cluster leak in AP mode in 802.11 power saving support
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    freebsd-wireless
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Wed Apr 04 15:00:09 UTC 2012
>Closed-Date:    
>Last-Modified:  Thu Apr 05 01:41:38 UTC 2012
>Originator:     Andrew Atrens
>Release:        trunk
>Organization:
>Environment:
generic - will affect all supported platforms.
>Description:
If one has a FreeBSD AP and clients (like iPods and macbooks) that are
constantly going into/out-of power saving mode, the AP will leak mbufs
for fragmented packets added to the sleeping node's power saving queue.

Eventually (depending on activity, available kvm) the AP will run out of
mbuf/clusters and become incommunicado.

--Andrew


>How-To-Repeat:
See above.
>Fix:
Here's my patch -

$ svn diff ieee80211_power.c
Index: ieee80211_power.c
===================================================================
--- ieee80211_power.c   (revision 233759)
+++ ieee80211_power.c   (working copy)
@@ -323,6 +323,7 @@
        struct ieee80211com *ic = ni->ni_ic;
        struct ieee80211_psq_head *qhead;
        int qlen, age;
+       struct mbuf *m0;
 
        IEEE80211_PSQ_LOCK(psq);
        if (psq->psq_len >= psq->psq_maxlen) {
@@ -336,7 +337,9 @@
                        ieee80211_dump_pkt(ni->ni_ic, mtod(m, caddr_t),
                            m->m_len, -1, -1);
 #endif
-               psq_mfree(m);
+               for (m0 = m; (m0=m) != NULL ; m = m->m_nextpkt) {
+                       psq_mfree(m0);
+               }
                return ENOSPC;
        }
        /*
@@ -386,10 +389,25 @@
        }
        KASSERT(age >= 0, ("age %d", age));
        M_AGE_SET(m, age);
        qhead->tail = m;
        qhead->len++;
        qlen = ++(psq->psq_len);
+
+       /*
+        *  We could have a fragmented frame that has multiple packets.
+        *  In that case we want to enqueue them all.
+        *
+        *  Make sure they're all tagged with the same age.
+         */
+
+       while ((m = m->m_nextpkt)) {
+               M_AGE_SET(m, age);
+               qhead->len++;
+               qlen = ++(psq->psq_len);
+               if (!m->m_nextpkt)
+                       qhead->tail = m;
+       }
+
        IEEE80211_PSQ_UNLOCK(psq);
 
        IEEE80211_NOTE(vap, IEEE80211_MSG_POWER, ni,


>Release-Note:
>Audit-Trail:
Responsible-Changed-From-To: freebsd-bugs->freebsd-wireless 
Responsible-Changed-By: linimon 
Responsible-Changed-When: Thu Apr 5 01:40:39 UTC 2012 
Responsible-Changed-Why:  
Over to maintainer(s). 

http://www.freebsd.org/cgi/query-pr.cgi?pr=166641 
>Unformatted:
