Changeset 2317

Show
Ignore:
Timestamp:
05/09/07 02:37:13 (2 years ago)
Author:
mentor
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@op.pl>

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/net80211/ieee80211.c

    r2315 r2317  
    804804                                /* Get an AP mode VAP */ 
    805805                                vap = TAILQ_FIRST(&ic->ic_vaps); 
    806                                 while ((vap->iv_state != IEEE80211_S_RUN) && (vap != NULL) && 
     806                                while ((vap != NULL) && (vap->iv_state != IEEE80211_S_RUN) && 
    807807                                       (vap->iv_ic != ic)) { 
    808808                                        vap = TAILQ_NEXT(vap, iv_next); 
    809809                                } 
     810 
    810811                                if (vap == NULL) { 
    811812                                        /* 
     
    814815                                         */ 
    815816                                        vap = TAILQ_FIRST(&ic->ic_vaps); 
    816                                         while ((vap->iv_state != IEEE80211_S_SCAN) && (vap != NULL) && 
     817                                        while ((vap != NULL) && (vap->iv_state != IEEE80211_S_SCAN) &&  
    817818                                               (vap->iv_ic != ic)) { 
    818819                                                vap = TAILQ_NEXT(vap, iv_next); 
  • trunk/net80211/ieee80211_scan_ap.c

    r1721 r2317  
    328328        } 
    329329        if (bestchan == -1) { 
    330                 /* no suitable channel, should not happen */ 
    331                 IEEE80211_DPRINTF(vap, IEEE80211_MSG_SCAN, 
    332                         "%s: no suitable channel! (should not happen)\n", __func__); 
    333                 /* XXX print something? */ 
    334                 return 0;                       /* restart scan */ 
     330                if (ss->ss_last > 0) { 
     331                        /* no suitable channel, should not happen */ 
     332                        IEEE80211_DPRINTF(vap, IEEE80211_MSG_SCAN, 
     333                                "%s: no suitable channel! (should not happen)\n", __func__); 
     334                        /* XXX print something? */ 
     335                } 
     336                return 0; /* restart scan */ 
    335337        } else { 
    336338                struct ieee80211_channel *c; 
  • trunk/net80211/ieee80211_wireless.c

    r2314 r2317  
    114114} 
    115115 
    116 static void 
     116static int 
    117117preempt_scan(struct net_device *dev, int max_grace, int max_wait) 
    118118{ 
     
    121121        int total_delay = 0; 
    122122        int canceled = 0, ready = 0; 
     123         
    123124        while (!ready && total_delay < max_grace + max_wait) { 
    124           if ((ic->ic_flags & IEEE80211_F_SCAN) == 0) { 
    125             ready = 1; 
    126           } else { 
    127             if (!canceled && total_delay > max_grace) { 
    128               /*  
    129                  Cancel any existing active scan, so that any new parameters 
    130                  in this scan ioctl (or the defaults) can be honored, then 
    131                  wait around a while to see if the scan cancels properly. 
    132               */ 
    133               IEEE80211_DPRINTF(vap, IEEE80211_MSG_SCAN, 
    134                                 "%s: cancel pending scan request\n", __func__); 
    135               (void) ieee80211_cancel_scan(vap); 
    136               canceled = 1; 
    137             } 
    138             mdelay (1); 
    139             total_delay += 1; 
    140           } 
    141         } 
     125                if ((ic->ic_flags & IEEE80211_F_SCAN) == 0) { 
     126                        ready = 1; 
     127                } else { 
     128                        if (!canceled && (total_delay > max_grace)) { 
     129                                /* Cancel any existing active scan, so that any new parameters 
     130                                 * in this scan ioctl (or the defaults) can be honored, then 
     131                                 * wait around a while to see if the scan cancels properly. */ 
     132                                IEEE80211_DPRINTF(vap, IEEE80211_MSG_SCAN, 
     133                                                "%s: cancel pending scan request\n", __func__); 
     134                                (void) ieee80211_cancel_scan(vap); 
     135                                canceled = 1; 
     136                        } 
     137                        mdelay (1); 
     138                        total_delay += 1; 
     139                } 
     140        } 
     141 
    142142        if (!ready) { 
    143           IEEE80211_DPRINTF(vap, IEEE80211_MSG_SCAN,  
    144                             "%s: Timeout canceling current scan.\n",  
    145                             __func__);  
    146         } 
     143                IEEE80211_DPRINTF(vap, IEEE80211_MSG_SCAN,  
     144                                "%s: Timeout canceling current scan.\n",  
     145                                __func__);  
     146        } 
     147 
     148        return ready; 
    147149} 
    148150         
     
    19311933        struct ifreq ifr; 
    19321934        char s[6];              /* big enough for ``11adt'' */ 
    1933         int retv, mode, ifr_mode, itr_count
     1935        int retv, mode, ifr_mode
    19341936 
    19351937        if (ic->ic_media.ifm_cur == NULL) 
    1936                 return -EINVAL; 
     1938                return -EINVAL;                        /* XXX: Wrong error */ 
    19371939        if (wri->length > sizeof(s))            /* silently truncate */ 
    19381940                wri->length = sizeof(s); 
    19391941        if (copy_from_user(s, wri->pointer, wri->length)) 
    19401942                return -EINVAL; 
    1941         s[sizeof(s)-1] = '\0';                /* ensure null termination */ 
     1943        s[sizeof(s) - 1] = '\0';              /* ensure null termination */ 
    19421944        mode = ieee80211_convert_mode(s); 
    19431945        if (mode < 0) 
    19441946                return -EINVAL; 
    19451947 
    1946         if(ieee80211_check_mode_consistency(ic,mode,vap->iv_des_chan)) {  
     1948        if(ieee80211_check_mode_consistency(ic, mode, vap->iv_des_chan)) {  
    19471949                /* 
    19481950                 * error in AP mode. 
     
    19521954                        return -EINVAL; 
    19531955                else 
    1954                         vap->iv_des_chan=IEEE80211_CHAN_ANYC; 
     1956                        vap->iv_des_chan = IEEE80211_CHAN_ANYC; 
    19551957        } 
    19561958 
    19571959        ifr_mode = mode; 
    19581960        memset(&ifr, 0, sizeof(ifr)); 
    1959         ifr.ifr_media = ic->ic_media.ifm_cur->ifm_media &~ IFM_MMASK; 
     1961        ifr.ifr_media = ic->ic_media.ifm_cur->ifm_media & ~IFM_MMASK; 
    19601962        if (mode == IEEE80211_MODE_TURBO_STATIC_A) 
    19611963                ifr_mode = IEEE80211_MODE_11A; 
    19621964        ifr.ifr_media |= IFM_MAKEMODE(ifr_mode); 
     1965         
    19631966        retv = ifmedia_ioctl(ic->ic_dev, &ifr, &ic->ic_media, SIOCSIFMEDIA); 
    1964         if ((!retv || retv == -ENETRESET) &&  mode != vap->iv_des_mode) { 
    1965                 ieee80211_scan_flush(ic);       /* NB: could optimize */ 
     1967        if ((!retv || retv == -ENETRESET) && (mode != vap->iv_des_mode)) { 
     1968                if (preempt_scan(dev, 100, 100)) 
     1969                        ieee80211_scan_flush(ic);       /* NB: could optimize */ 
     1970                else 
     1971                        return -ETIMEDOUT; 
     1972                 
    19661973                vap->iv_des_mode = mode; 
    1967                 if (IS_UP_AUTO(vap)) { 
    1968                         ieee80211_cancel_scan(vap); 
    1969                         itr_count = 0; 
    1970                         while((ic->ic_flags & IEEE80211_F_SCAN) != 0) { 
    1971                                 mdelay(1); 
    1972                                 if (itr_count < 100) { 
    1973                                         itr_count++; 
    1974                                         continue; 
    1975                                 } 
    1976                                 IEEE80211_DPRINTF(vap, IEEE80211_MSG_SCAN, 
    1977                                   "%s: Timeout canceling current scan.\n", 
    1978                                   __func__); 
    1979                                 return -ETIMEDOUT; 
    1980                         } 
     1974                if (IS_UP_AUTO(vap)) 
    19811975                        ieee80211_new_state(vap, IEEE80211_S_SCAN, 0); 
    1982                 } 
     1976                 
    19831977                retv = 0; 
    19841978        } 
     1979 
    19851980#ifdef ATH_SUPERG_XR 
    19861981        /* set the same params on the xr vap device if exists */ 
     
    19881983                vap->iv_xrvap->iv_des_mode = mode; 
    19891984#endif 
     1985 
    19901986        return -retv; 
    19911987}