logo       
Google Custom Search
    AddThis Social Bookmark Button

revision 2317 committed: msg#00012

Subject: revision 2317 committed
Project     : madwifi
Revision    : 2317
Author      : mentor (Matthew W. S. Bell)
Date        : 2007-05-09 02:37:13 +0200 (Wed, 09 May 2007)

Log Message :
Fix two possible NULL pointer dereferences, and fix a race condition when 
changing channel mode whilst scanning. Also, whitespace and syntax cleanup of 
some associated code. Adapted from original patch at #1301.

Original patch: Signed-off-by: Przemyslaw Bruski <pbruskispam@xxxxx>

Affected Files:
* trunk/net80211/ieee80211.c                          updated             
* trunk/net80211/ieee80211_scan_ap.c                  updated             
* trunk/net80211/ieee80211_wireless.c                 updated             


Modified: trunk/net80211/ieee80211.c
===================================================================
--- trunk/net80211/ieee80211.c  2007-05-05 13:31:05 UTC (rev 2316)
+++ trunk/net80211/ieee80211.c  2007-05-09 00:37:13 UTC (rev 2317)
@@ -803,17 +803,18 @@
                        if  (ic->ic_curchan->ic_freq == c->ic_freq) {
                                /* Get an AP mode VAP */
                                vap = TAILQ_FIRST(&ic->ic_vaps);
-                               while ((vap->iv_state != IEEE80211_S_RUN) && 
(vap != NULL) &&
+                               while ((vap != NULL) && (vap->iv_state != 
IEEE80211_S_RUN) &&
                                       (vap->iv_ic != ic)) {
                                        vap = TAILQ_NEXT(vap, iv_next);
                                }
+
                                if (vap == NULL) {
                                        /*
                                         * No running VAP was found, check
                                         * if any one is scanning.
                                         */
                                        vap = TAILQ_FIRST(&ic->ic_vaps);
-                                       while ((vap->iv_state != 
IEEE80211_S_SCAN) && (vap != NULL) &&
+                                       while ((vap != NULL) && (vap->iv_state 
!= IEEE80211_S_SCAN) && 
                                               (vap->iv_ic != ic)) {
                                                vap = TAILQ_NEXT(vap, iv_next);
                                        }

Modified: trunk/net80211/ieee80211_scan_ap.c
===================================================================
--- trunk/net80211/ieee80211_scan_ap.c  2007-05-05 13:31:05 UTC (rev 2316)
+++ trunk/net80211/ieee80211_scan_ap.c  2007-05-09 00:37:13 UTC (rev 2317)
@@ -327,11 +327,13 @@
                        bestchan = chan;
        }
        if (bestchan == -1) {
-               /* no suitable channel, should not happen */
-               IEEE80211_DPRINTF(vap, IEEE80211_MSG_SCAN,
-                       "%s: no suitable channel! (should not happen)\n", 
__func__);
-               /* XXX print something? */
-               return 0;                       /* restart scan */
+               if (ss->ss_last > 0) {
+                       /* no suitable channel, should not happen */
+                       IEEE80211_DPRINTF(vap, IEEE80211_MSG_SCAN,
+                               "%s: no suitable channel! (should not 
happen)\n", __func__);
+                       /* XXX print something? */
+               }
+               return 0; /* restart scan */
        } else {
                struct ieee80211_channel *c;
                struct ieee80211_scan_entry se;

Modified: trunk/net80211/ieee80211_wireless.c
===================================================================
--- trunk/net80211/ieee80211_wireless.c 2007-05-05 13:31:05 UTC (rev 2316)
+++ trunk/net80211/ieee80211_wireless.c 2007-05-09 00:37:13 UTC (rev 2317)
@@ -113,37 +113,39 @@
        iq->updated = IW_QUAL_ALL_UPDATED;
 }
 
-static void
+static int
 preempt_scan(struct net_device *dev, int max_grace, int max_wait)
 {
        struct ieee80211vap *vap = dev->priv;
        struct ieee80211com *ic = vap->iv_ic;
        int total_delay = 0;
        int canceled = 0, ready = 0;
+       
        while (!ready && total_delay < max_grace + max_wait) {
-         if ((ic->ic_flags & IEEE80211_F_SCAN) == 0) {
-           ready = 1;
-         } else {
-           if (!canceled && total_delay > max_grace) {
-             /* 
-                Cancel any existing active scan, so that any new parameters
-                in this scan ioctl (or the defaults) can be honored, then
-                wait around a while to see if the scan cancels properly.
-             */
-             IEEE80211_DPRINTF(vap, IEEE80211_MSG_SCAN,
-                               "%s: cancel pending scan request\n", __func__);
-             (void) ieee80211_cancel_scan(vap);
-             canceled = 1;
-           }
-           mdelay (1);
-           total_delay += 1;
-         }
+               if ((ic->ic_flags & IEEE80211_F_SCAN) == 0) {
+                       ready = 1;
+               } else {
+                       if (!canceled && (total_delay > max_grace)) {
+                               /* Cancel any existing active scan, so that any 
new parameters
+                                * in this scan ioctl (or the defaults) can be 
honored, then
+                                * wait around a while to see if the scan 
cancels properly. */
+                               IEEE80211_DPRINTF(vap, IEEE80211_MSG_SCAN,
+                                               "%s: cancel pending scan 
request\n", __func__);
+                               (void) ieee80211_cancel_scan(vap);
+                               canceled = 1;
+                       }
+                       mdelay (1);
+                       total_delay += 1;
+               }
        }
+
        if (!ready) {
-         IEEE80211_DPRINTF(vap, IEEE80211_MSG_SCAN, 
-                           "%s: Timeout canceling current scan.\n", 
-                           __func__); 
+               IEEE80211_DPRINTF(vap, IEEE80211_MSG_SCAN, 
+                               "%s: Timeout canceling current scan.\n", 
+                               __func__); 
        }
+
+       return ready;
 }
        
 static struct iw_statistics *
@@ -1930,20 +1932,20 @@
        struct ieee80211com *ic = vap->iv_ic;
        struct ifreq ifr;
        char s[6];              /* big enough for ``11adt'' */
-       int retv, mode, ifr_mode, itr_count;
+       int retv, mode, ifr_mode;
 
        if (ic->ic_media.ifm_cur == NULL)
-               return -EINVAL;
+               return -EINVAL;                 /* XXX: Wrong error */
        if (wri->length > sizeof(s))            /* silently truncate */
                wri->length = sizeof(s);
        if (copy_from_user(s, wri->pointer, wri->length))
                return -EINVAL;
-       s[sizeof(s)-1] = '\0';                  /* ensure null termination */
+       s[sizeof(s) - 1] = '\0';                /* ensure null termination */
        mode = ieee80211_convert_mode(s);
        if (mode < 0)
                return -EINVAL;
 
-       if(ieee80211_check_mode_consistency(ic,mode,vap->iv_des_chan)) { 
+       if(ieee80211_check_mode_consistency(ic, mode, vap->iv_des_chan)) { 
                /*
                 * error in AP mode.
                 * overwrite channel selection in other modes.
@@ -1951,42 +1953,36 @@
                if (vap->iv_opmode == IEEE80211_M_HOSTAP)
                        return -EINVAL;
                else
-                       vap->iv_des_chan=IEEE80211_CHAN_ANYC;
+                       vap->iv_des_chan = IEEE80211_CHAN_ANYC;
        }
 
        ifr_mode = mode;
        memset(&ifr, 0, sizeof(ifr));
-       ifr.ifr_media = ic->ic_media.ifm_cur->ifm_media &~ IFM_MMASK;
+       ifr.ifr_media = ic->ic_media.ifm_cur->ifm_media & ~IFM_MMASK;
        if (mode == IEEE80211_MODE_TURBO_STATIC_A)
                ifr_mode = IEEE80211_MODE_11A;
        ifr.ifr_media |= IFM_MAKEMODE(ifr_mode);
+       
        retv = ifmedia_ioctl(ic->ic_dev, &ifr, &ic->ic_media, SIOCSIFMEDIA);
-       if ((!retv || retv == -ENETRESET) &&  mode != vap->iv_des_mode) {
-               ieee80211_scan_flush(ic);       /* NB: could optimize */
+       if ((!retv || retv == -ENETRESET) && (mode != vap->iv_des_mode)) {
+               if (preempt_scan(dev, 100, 100))
+                       ieee80211_scan_flush(ic);       /* NB: could optimize */
+               else
+                       return -ETIMEDOUT;
+               
                vap->iv_des_mode = mode;
-               if (IS_UP_AUTO(vap)) {
-                       ieee80211_cancel_scan(vap);
-                       itr_count = 0;
-                       while((ic->ic_flags & IEEE80211_F_SCAN) != 0) {
-                               mdelay(1);
-                               if (itr_count < 100) {
-                                       itr_count++;
-                                       continue;
-                               }
-                               IEEE80211_DPRINTF(vap, IEEE80211_MSG_SCAN,
-                                 "%s: Timeout canceling current scan.\n",
-                                 __func__);
-                               return -ETIMEDOUT;
-                       }
+               if (IS_UP_AUTO(vap))
                        ieee80211_new_state(vap, IEEE80211_S_SCAN, 0);
-               }
+               
                retv = 0;
        }
+
 #ifdef ATH_SUPERG_XR
        /* set the same params on the xr vap device if exists */
        if (vap->iv_xrvap && !(vap->iv_flags & IEEE80211_F_XR))
                vap->iv_xrvap->iv_des_mode = mode;
 #endif
+
        return -retv;
 }
 #undef IEEE80211_MODE_TURBO_STATIC_A

-------------------------------------------------------------------------
This SF.net email is sponsored by DB2 Express
Download DB2 Express C - the FREE version of DB2 express and take
control of your XML. No limits. Just data. Click to get it now.
http://sourceforge.net/powerbar/db2/



Try Searching:
servers, voip, java, networking, microsoft ...
<Prev in Thread] Current Thread [Next in Thread>