From owner-p4-projects@FreeBSD.ORG Wed Jul 18 13:05:26 2007 Return-Path: X-Original-To: p4-projects@freebsd.org Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 0124016A40E; Wed, 18 Jul 2007 13:05:26 +0000 (UTC) X-Original-To: perforce@freebsd.org Delivered-To: perforce@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [69.147.83.52]) by hub.freebsd.org (Postfix) with ESMTP id B2DD716A40A for ; Wed, 18 Jul 2007 13:05:25 +0000 (UTC) (envelope-from avatar@freebsd.org) Received: from repoman.freebsd.org (repoman.freebsd.org [69.147.83.41]) by mx1.freebsd.org (Postfix) with ESMTP id A16F613C4BD for ; Wed, 18 Jul 2007 13:05:25 +0000 (UTC) (envelope-from avatar@freebsd.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.14.1/8.14.1) with ESMTP id l6ID5PDJ008002 for ; Wed, 18 Jul 2007 13:05:25 GMT (envelope-from avatar@freebsd.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.14.1/8.14.1/Submit) id l6ID5PRp007999 for perforce@freebsd.org; Wed, 18 Jul 2007 13:05:25 GMT (envelope-from avatar@freebsd.org) Date: Wed, 18 Jul 2007 13:05:25 GMT Message-Id: <200707181305.l6ID5PRp007999@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to avatar@freebsd.org using -f From: Tai-hwa Liang To: Perforce Change Reviews Cc: Subject: PERFORCE change 123686 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 18 Jul 2007 13:05:26 -0000 http://perforce.freebsd.org/chv.cgi?CH=123686 Change 123686 by avatar@avatar_t40 on 2007/07/18 13:05:24 Fixing various ancontrol(8) related panics by dropping locks around copyin()/copyout(). Reviewed by: sam, thompsa Tested by: dhw MFP4 after: 2 weeks Affected files ... .. //depot/projects/wifi/sys/dev/an/if_an.c#14 edit Differences ... ==== //depot/projects/wifi/sys/dev/an/if_an.c#14 (text+ko) ==== @@ -1914,7 +1914,9 @@ error = 0; break; case SIOCGAIRONET: + AN_UNLOCK(sc); error = copyin(ifr->ifr_data, &sc->areq, sizeof(sc->areq)); + AN_LOCK(sc); if (error != 0) break; #ifdef ANCACHE @@ -1940,12 +1942,16 @@ error = EINVAL; break; } + AN_UNLOCK(sc); error = copyout(&sc->areq, ifr->ifr_data, sizeof(sc->areq)); + AN_LOCK(sc); break; case SIOCSAIRONET: if ((error = priv_check(td, PRIV_DRIVER))) goto out; + AN_UNLOCK(sc); error = copyin(ifr->ifr_data, &sc->areq, sizeof(sc->areq)); + AN_LOCK(sc); if (error != 0) break; an_setdef(sc, &sc->areq); @@ -1953,7 +1959,9 @@ case SIOCGPRIVATE_0: /* used by Cisco client utility */ if ((error = priv_check(td, PRIV_DRIVER))) goto out; + AN_UNLOCK(sc); error = copyin(ifr->ifr_data, &l_ioctl, sizeof(l_ioctl)); + AN_LOCK(sc); if (error) goto out; mode = l_ioctl.command; @@ -1969,18 +1977,24 @@ } if (!error) { /* copy out the updated command info */ + AN_UNLOCK(sc); error = copyout(&l_ioctl, ifr->ifr_data, sizeof(l_ioctl)); + AN_LOCK(sc); } break; case SIOCGPRIVATE_1: /* used by Cisco client utility */ if ((error = priv_check(td, PRIV_DRIVER))) goto out; + AN_UNLOCK(sc); error = copyin(ifr->ifr_data, &l_ioctl, sizeof(l_ioctl)); + AN_LOCK(sc); if (error) goto out; l_ioctl.command = 0; error = AIROMAGIC; + AN_UNLOCK(sc); (void) copyout(&error, l_ioctl.data, sizeof(error)); + AN_LOCK(sc); error = 0; break; case SIOCG80211: @@ -2030,8 +2044,10 @@ ireq->i_len = len; bzero(tmpstr, IEEE80211_NWID_LEN); bcopy(tmpptr, tmpstr, len); + AN_UNLOCK(sc); error = copyout(tmpstr, ireq->i_data, IEEE80211_NWID_LEN); + AN_LOCK(sc); break; case IEEE80211_IOC_NUMSSIDS: sc->areq.an_len = sizeof(sc->areq); @@ -2105,7 +2121,9 @@ */ bzero(tmpstr, len); ireq->i_len = len; + AN_UNLOCK(sc); error = copyout(tmpstr, ireq->i_data, len); + AN_LOCK(sc); break; case IEEE80211_IOC_NUMWEPKEYS: ireq->i_val = 9; /* include home key */ @@ -2183,8 +2201,10 @@ tmpptr = config->an_nodename; bzero(tmpstr, IEEE80211_NWID_LEN); bcopy(tmpptr, tmpstr, ireq->i_len); + AN_UNLOCK(sc); error = copyout(tmpstr, ireq->i_data, IEEE80211_NWID_LEN); + AN_LOCK(sc); break; case IEEE80211_IOC_CHANNEL: sc->areq.an_type = AN_RID_STATUS; @@ -2268,9 +2288,11 @@ error = EINVAL; break; } else { + AN_UNLOCK(sc); error = copyin(ireq->i_data, ssids->an_entry[ireq->i_val].an_ssid, ireq->i_len); + AN_LOCK(sc); ssids->an_entry[ireq->i_val].an_len = ireq->i_len; break; @@ -2305,7 +2327,9 @@ error = EINVAL; break; } + AN_UNLOCK(sc); error = copyin(ireq->i_data, tmpstr, 13); + AN_LOCK(sc); if (error != 0) break; /* @@ -2387,8 +2411,10 @@ break; } bzero(config->an_nodename, 16); + AN_UNLOCK(sc); error = copyin(ireq->i_data, config->an_nodename, ireq->i_len); + AN_LOCK(sc); break; case IEEE80211_IOC_CHANNEL: /* @@ -2430,7 +2456,9 @@ an_setdef(sc, &sc->areq); break; default: + AN_UNLOCK(sc); error = ether_ioctl(ifp, command, data); + AN_LOCK(sc); break; } out: @@ -3159,6 +3187,7 @@ { unsigned short rid; struct an_softc *sc; + int error; switch (l_ioctl->command) { case AIROGCAP: @@ -3210,24 +3239,30 @@ l_ioctl->len = sc->areq.an_len - 4; /* just data */ + AN_UNLOCK(sc); /* the data contains the length at first */ if (copyout(&(sc->areq.an_len), l_ioctl->data, sizeof(sc->areq.an_len))) { - return -EFAULT; + error = -EFAULT; + goto lock_exit; } /* Just copy the data back */ if (copyout(&(sc->areq.an_val), l_ioctl->data + 2, l_ioctl->len)) { - return -EFAULT; + error = -EFAULT; + goto lock_exit; } - return 0; + error = 0; +lock_exit: + AN_LOCK(sc); + return (error); } static int writerids(struct ifnet *ifp, struct aironet_ioctl *l_ioctl) { struct an_softc *sc; - int rid, command; + int rid, command, error; sc = ifp->if_softc; rid = 0; @@ -3269,16 +3304,20 @@ an_read_record(sc, (struct an_ltv_gen *)&sc->areq); l_ioctl->len = sc->areq.an_len - 4; /* just data */ + AN_UNLOCK(sc); /* the data contains the length at first */ - if (copyout(&(sc->areq.an_len), l_ioctl->data, - sizeof(sc->areq.an_len))) { + error = copyout(&(sc->areq.an_len), l_ioctl->data, + sizeof(sc->areq.an_len)); + if (error) { + AN_LOCK(sc); return -EFAULT; } /* Just copy the data */ - if (copyout(&(sc->areq.an_val), l_ioctl->data + 2, - l_ioctl->len)) { + error = copyout(&(sc->areq.an_val), l_ioctl->data + 2, + l_ioctl->len); + AN_LOCK(sc); + if (error) return -EFAULT; - } return 0; break; case AIROPWEPKEY: @@ -3304,10 +3343,13 @@ sc->areq.an_type = rid; /* Just copy the data back */ - if (copyin((l_ioctl->data) + 2, &sc->areq.an_val, - l_ioctl->len)) { + AN_UNLOCK(sc); + error = copyin((l_ioctl->data) + 2, &sc->areq.an_val, + l_ioctl->len); + AN_LOCK(sc); + if (error) return -EFAULT; - } + an_cmd(sc, AN_CMD_DISABLE, 0); an_write_record(sc, (struct an_ltv_gen *)&sc->areq); an_cmd(sc, AN_CMD_ENABLE, 0); @@ -3603,7 +3645,9 @@ return ENOBUFS; break; case AIROFLSHGCHR: /* Get char from aux */ + AN_UNLOCK(sc); status = copyin(l_ioctl->data, &sc->areq, l_ioctl->len); + AN_LOCK(sc); if (status) return status; z = *(int *)&sc->areq; @@ -3612,7 +3656,9 @@ else return -1; case AIROFLSHPCHR: /* Send char to card. */ + AN_UNLOCK(sc); status = copyin(l_ioctl->data, &sc->areq, l_ioctl->len); + AN_LOCK(sc); if (status) return status; z = *(int *)&sc->areq; @@ -3627,7 +3673,9 @@ l_ioctl->len, FLASH_SIZE); return -EINVAL; } + AN_UNLOCK(sc); status = copyin(l_ioctl->data, sc->an_flash_buffer, l_ioctl->len); + AN_LOCK(sc); if (status) return status;