Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 7 Feb 2010 08:30:11 GMT
From:      Alexander Egorenkov <egorenar@gmail.com>
To:        freebsd-gnats-submit@FreeBSD.org
Subject:   kern/143627: [ieee80211] A bug in ht_send_action_ba_addba causes net80211 to send malformed ADDBA response frames
Message-ID:  <201002070830.o178UB8e003759@www.freebsd.org>
Resent-Message-ID: <201002070840.o178e05I010628@freefall.freebsd.org>

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

>Number:         143627
>Category:       kern
>Synopsis:       [ieee80211] A bug in ht_send_action_ba_addba causes net80211 to send malformed ADDBA response frames
>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 Feb 07 08:40:00 UTC 2010
>Closed-Date:
>Last-Modified:
>Originator:     Alexander Egorenkov
>Release:        FreeBSD 8.0 STABLE
>Organization:
>Environment:
FreeBSD dantooine 8.0-RELEASE FreeBSD 8.0-RELEASE #2: Tue Dec 15 17:56:06 CET 2009 root@dantooine:/usr/obj/usr/src/sys/MYKERNEL i386
>Description:
I'm developing an 802.11n device driver and added A-MPDU Rx support to the driver.
While testing this feature, i noticed that net80211 stack sends malformed ADDBA response frames in response to ADDBA requests from AP. The ADDBA response frames sent by net80211 stack contain 2 bytes fewer. I analyzed this problem and found out that the problem lies in the function ieee80211_ht.c:ht_send_action_ba_addba:2178.

>How-To-Repeat:

>Fix:
Here is the code snippet which causes the problem:

        if (m != NULL) {
		*frm++ = category;
		*frm++ = action;
		*frm++ = args[0];		/* dialog token */
		ADDSHORT(frm, args[1]);		/* baparamset */
		ADDSHORT(frm, args[2]);		/* batimeout */
		if (action == IEEE80211_ACTION_BA_ADDBA_REQUEST)
			ADDSHORT(frm, args[3]);	/* baseqctl */
		m->m_pkthdr.len = m->m_len = frm - mtod(m, uint8_t *);
		return ht_action_output(ni, m);
	} else {
		vap->iv_stats.is_tx_nobuf++;
		ieee80211_free_node(ni);
		return ENOMEM;
	}

I took a look into the 802.11 specification and found out that
an ADDBA response has the same size as an ADDBA request but
an ADDBA response has a status code after the dialog token field and
doesn't have a block starting sequence control (baseqctl) field.

So here is my fix to the problem:

        if (m != NULL) {
		*frm++ = category;
		*frm++ = action;

                if (action == IEEE80211_ACTION_BA_ADDBA_REQUEST)
                {
		   *frm++ = args[0];		/* dialog token */
		   ADDSHORT(frm, args[1]);	/* baparamset */
		   ADDSHORT(frm, args[2]);	/* batimeout */
	           ADDSHORT(frm, args[3]);	/* baseqctl */
                }
                else /* IEEE80211_ACTION_BA_ADDBA_RESPONSE */
                {
                   *frm++ = args[0];		/* dialog token */
                   ADDSHORT(frm, args[1]);	/* status code */
		   ADDSHORT(frm, args[2]);	/* baparamset */
		   ADDSHORT(frm, args[3]);	/* batimeout */
                }

		m->m_pkthdr.len = m->m_len = frm - mtod(m, uint8_t *);
		return ht_action_output(ni, m);
	} else {
		vap->iv_stats.is_tx_nobuf++;
		ieee80211_free_node(ni);
		return ENOMEM;
	}

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



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