[PATCH 2/4] The ioctl wext etc, seems to be broken because they don't take any lock during shutdown. If the user do an echo to the state variabile of the rfkill during the network scanning the system can go in panic. It introduces a semaphore variable to the ar priv data.

michael michael at panicking.kicks-ass.org
Thu Jul 30 12:47:00 CEST 2009


Signed-off-by: Michael Trimarchi <michael at panicking.kicks-ass.org>
---
 drivers/ar6000/ar6000/ar6000_drv.c   |    5 +-
 drivers/ar6000/ar6000/ar6000_drv.h   |    2 +-
 drivers/ar6000/ar6000/wireless_ext.c |  136 ++++++++++++++++++++++++----------
 3 files changed, 101 insertions(+), 42 deletions(-)

diff --git a/drivers/ar6000/ar6000/ar6000_drv.c b/drivers/ar6000/ar6000/ar6000_drv.c
index 21504f2..87194d4 100644
--- a/drivers/ar6000/ar6000/ar6000_drv.c
+++ b/drivers/ar6000/ar6000/ar6000_drv.c
@@ -902,6 +902,7 @@ ar6000_avail_ev(HTC_HANDLE HTCHandle)
     AR_DEBUG_PRINTF("ar6000_avail: name=%s htcTarget=0x%x, dev=0x%x (%d), ar=0x%x\n",
                     dev->name, (A_UINT32)HTCHandle, (A_UINT32)dev, device_index,
                     (A_UINT32)ar);
+    init_rwsem(&ar->arHwAvail);
 }
 
 static void ar6000_target_failure(void *Instance, A_STATUS Status)
@@ -942,7 +943,9 @@ static void
 ar6000_unavail_ev(void *Instance)
 {
     AR_SOFTC_T *ar = (AR_SOFTC_T *)Instance;
-        /* NULL out it's entry in the global list */
+    /* NULL out it's entry in the global list */
+
+    down_write(&ar->arHwAvail);
     ar6000_devices[ar->arDeviceIndex] = NULL;
     ar6000_destroy(ar->arNetDev, 1);
 }
diff --git a/drivers/ar6000/ar6000/ar6000_drv.h b/drivers/ar6000/ar6000/ar6000_drv.h
index 784f158..2b918cf 100644
--- a/drivers/ar6000/ar6000/ar6000_drv.h
+++ b/drivers/ar6000/ar6000/ar6000_drv.h
@@ -98,7 +98,6 @@ struct USER_SAVEDKEYS {
 
 #define DBG_DEFAULTS	(DBG_ERROR|DBG_WARNING)
 
-
 #ifdef DEBUG
 #define AR_DEBUG_PRINTF(args...)        if (debugdriver) A_PRINTF(args);
 #define AR_DEBUG2_PRINTF(args...)        if (debugdriver >= 2) A_PRINTF(args);
@@ -205,6 +204,7 @@ typedef struct ar6_softc {
     HTC_HANDLE              arHtcTarget;
     void                    *arHifDevice;
     spinlock_t              arLock;
+    struct rw_semaphore     arHwAvail;
     struct semaphore        arSem;
     int                     arRxBuffers[WMI_PRI_MAX_COUNT];
     int                     arSsidLen;
diff --git a/drivers/ar6000/ar6000/wireless_ext.c b/drivers/ar6000/ar6000/wireless_ext.c
index af78ae0..8cd5f2a 100644
--- a/drivers/ar6000/ar6000/wireless_ext.c
+++ b/drivers/ar6000/ar6000/wireless_ext.c
@@ -25,6 +25,20 @@ extern unsigned int wmitimeout;
 extern A_WAITQUEUE_HEAD arEvent;
 extern wait_queue_head_t ar6000_scan_queue;
 
+#define DECLARE_LOCKED_VERSION(_name) \
+int lock_##_name(struct net_device *dev, struct iw_request_info *info, \
+                void *p, char *data) \
+{ \
+	AR_SOFTC_T *ar = (AR_SOFTC_T *)netdev_priv(dev);	\
+	int ret = -EAGAIN;					\
+								\
+	if (down_read_trylock(&ar->arHwAvail)) {		\
+		ret = _name(dev, info, p, data);		\
+		up_read(&ar->arHwAvail);			\
+	}							\
+	return ret;						\
+}
+
 /*
  * Encode a WPA or RSN information element as a custom
  * element using the hostap format.
@@ -1859,21 +1873,63 @@ ar6000_set_quality(struct iw_quality *iq, A_INT8 rssi)
     iq->updated = 7;
 }
 
+DECLARE_LOCKED_VERSION(ar6000_ioctl_giwname)
+DECLARE_LOCKED_VERSION(ar6000_ioctl_siwfreq)
+DECLARE_LOCKED_VERSION(ar6000_ioctl_siwmode)
+DECLARE_LOCKED_VERSION(ar6000_ioctl_giwfreq)
+DECLARE_LOCKED_VERSION(ar6000_ioctl_giwmode)
+DECLARE_LOCKED_VERSION(ar6000_ioctl_siwsens)
+DECLARE_LOCKED_VERSION(ar6000_ioctl_giwsens)
+DECLARE_LOCKED_VERSION(ar6000_ioctl_giwrange)
+DECLARE_LOCKED_VERSION(ar6000_ioctl_siwap)
+DECLARE_LOCKED_VERSION(ar6000_ioctl_giwap)
+DECLARE_LOCKED_VERSION(ar6000_ioctl_iwaplist)
+DECLARE_LOCKED_VERSION(ar6000_ioctl_siwscan)
+DECLARE_LOCKED_VERSION(ar6000_ioctl_giwscan)
+DECLARE_LOCKED_VERSION(ar6000_ioctl_siwessid)
+DECLARE_LOCKED_VERSION(ar6000_ioctl_giwessid)
+DECLARE_LOCKED_VERSION(ar6000_ioctl_siwrate)
+DECLARE_LOCKED_VERSION(ar6000_ioctl_giwrate)
+DECLARE_LOCKED_VERSION(ar6000_ioctl_siwtxpow)
+DECLARE_LOCKED_VERSION(ar6000_ioctl_giwtxpow)
+DECLARE_LOCKED_VERSION(ar6000_ioctl_siwretry)
+DECLARE_LOCKED_VERSION(ar6000_ioctl_giwretry)
+DECLARE_LOCKED_VERSION(ar6000_ioctl_siwencode)
+DECLARE_LOCKED_VERSION(ar6000_ioctl_giwencode)
+DECLARE_LOCKED_VERSION(ar6000_ioctl_siwpower)
+DECLARE_LOCKED_VERSION(ar6000_ioctl_giwpower)
+DECLARE_LOCKED_VERSION(ar6000_ioctl_siwgenie)
+DECLARE_LOCKED_VERSION(ar6000_ioctl_giwgenie)
+DECLARE_LOCKED_VERSION(ar6000_ioctl_siwauth)
+DECLARE_LOCKED_VERSION(ar6000_ioctl_giwauth)
+DECLARE_LOCKED_VERSION(ar6000_ioctl_siwencodeext)
+DECLARE_LOCKED_VERSION(ar6000_ioctl_giwencodeext)
+
+/* private handler */
+DECLARE_LOCKED_VERSION(ar6000_ioctl_setparam)
+DECLARE_LOCKED_VERSION(ar6000_ioctl_getparam)
+DECLARE_LOCKED_VERSION(ar6000_ioctl_setkey)
+DECLARE_LOCKED_VERSION(ar6000_ioctl_setwmmparams)
+DECLARE_LOCKED_VERSION(ar6000_ioctl_delkey)
+DECLARE_LOCKED_VERSION(ar6000_ioctl_getwmmparams)
+DECLARE_LOCKED_VERSION(ar6000_ioctl_setoptie)
+DECLARE_LOCKED_VERSION(ar6000_ioctl_setmlme)
+DECLARE_LOCKED_VERSION(ar6000_ioctl_addpmkid)
 
 /* Structures to export the Wireless Handlers */
 static const iw_handler ath_handlers[] = {
     (iw_handler) NULL,                          /* SIOCSIWCOMMIT */
-    (iw_handler) ar6000_ioctl_giwname,          /* SIOCGIWNAME */
+    (iw_handler) lock_ar6000_ioctl_giwname,          /* SIOCGIWNAME */
     (iw_handler) NULL,                          /* SIOCSIWNWID */
     (iw_handler) NULL,                          /* SIOCGIWNWID */
-    (iw_handler) ar6000_ioctl_siwfreq,          /* SIOCSIWFREQ */
-    (iw_handler) ar6000_ioctl_giwfreq,          /* SIOCGIWFREQ */
-    (iw_handler) ar6000_ioctl_siwmode,          /* SIOCSIWMODE */
-    (iw_handler) ar6000_ioctl_giwmode,          /* SIOCGIWMODE */
-    (iw_handler) ar6000_ioctl_siwsens,          /* SIOCSIWSENS */
-    (iw_handler) ar6000_ioctl_giwsens,          /* SIOCGIWSENS */
+    (iw_handler) lock_ar6000_ioctl_siwfreq,          /* SIOCSIWFREQ */
+    (iw_handler) lock_ar6000_ioctl_giwfreq,          /* SIOCGIWFREQ */
+    (iw_handler) lock_ar6000_ioctl_siwmode,          /* SIOCSIWMODE */
+    (iw_handler) lock_ar6000_ioctl_giwmode,          /* SIOCGIWMODE */
+    (iw_handler) lock_ar6000_ioctl_siwsens,          /* SIOCSIWSENS */
+    (iw_handler) lock_ar6000_ioctl_giwsens,          /* SIOCGIWSENS */
     (iw_handler) NULL /* not _used */,          /* SIOCSIWRANGE */
-    (iw_handler) ar6000_ioctl_giwrange,         /* SIOCGIWRANGE */
+    (iw_handler) lock_ar6000_ioctl_giwrange,         /* SIOCGIWRANGE */
     (iw_handler) NULL /* not used */,           /* SIOCSIWPRIV */
     (iw_handler) NULL /* kernel code */,        /* SIOCGIWPRIV */
     (iw_handler) NULL /* not used */,           /* SIOCSIWSTATS */
@@ -1882,53 +1938,53 @@ static const iw_handler ath_handlers[] = {
     (iw_handler) NULL,                          /* SIOCGIWSPY */
     (iw_handler) NULL,                          /* SIOCSIWTHRSPY */
     (iw_handler) NULL,                          /* SIOCGIWTHRSPY */
-    (iw_handler) ar6000_ioctl_siwap,            /* SIOCSIWAP */
-    (iw_handler) ar6000_ioctl_giwap,            /* SIOCGIWAP */
+    (iw_handler) lock_ar6000_ioctl_siwap,            /* SIOCSIWAP */
+    (iw_handler) lock_ar6000_ioctl_giwap,            /* SIOCGIWAP */
     (iw_handler) NULL,                          /* -- hole -- */
-    (iw_handler) ar6000_ioctl_iwaplist,         /* SIOCGIWAPLIST */
-    (iw_handler) ar6000_ioctl_siwscan,          /* SIOCSIWSCAN */
-    (iw_handler) ar6000_ioctl_giwscan,          /* SIOCGIWSCAN */
-    (iw_handler) ar6000_ioctl_siwessid,         /* SIOCSIWESSID */
-    (iw_handler) ar6000_ioctl_giwessid,         /* SIOCGIWESSID */
+    (iw_handler) lock_ar6000_ioctl_iwaplist,         /* SIOCGIWAPLIST */
+    (iw_handler) lock_ar6000_ioctl_siwscan,          /* SIOCSIWSCAN */
+    (iw_handler) lock_ar6000_ioctl_giwscan,          /* SIOCGIWSCAN */
+    (iw_handler) lock_ar6000_ioctl_siwessid,         /* SIOCSIWESSID */
+    (iw_handler) lock_ar6000_ioctl_giwessid,         /* SIOCGIWESSID */
     (iw_handler) NULL,                          /* SIOCSIWNICKN */
     (iw_handler) NULL,                          /* SIOCGIWNICKN */
     (iw_handler) NULL,                          /* -- hole -- */
     (iw_handler) NULL,                          /* -- hole -- */
-    (iw_handler) ar6000_ioctl_siwrate,          /* SIOCSIWRATE */
-    (iw_handler) ar6000_ioctl_giwrate,          /* SIOCGIWRATE */
+    (iw_handler) lock_ar6000_ioctl_siwrate,          /* SIOCSIWRATE */
+    (iw_handler) lock_ar6000_ioctl_giwrate,          /* SIOCGIWRATE */
     (iw_handler) NULL,           /* SIOCSIWRTS */
     (iw_handler) NULL,           /* SIOCGIWRTS */
     (iw_handler) NULL,          /* SIOCSIWFRAG */
     (iw_handler) NULL,          /* SIOCGIWFRAG */
-    (iw_handler) ar6000_ioctl_siwtxpow,         /* SIOCSIWTXPOW */
-    (iw_handler) ar6000_ioctl_giwtxpow,         /* SIOCGIWTXPOW */
-    (iw_handler) ar6000_ioctl_siwretry,         /* SIOCSIWRETRY */
-    (iw_handler) ar6000_ioctl_giwretry,         /* SIOCGIWRETRY */
-    (iw_handler) ar6000_ioctl_siwencode,        /* SIOCSIWENCODE */
-    (iw_handler) ar6000_ioctl_giwencode,        /* SIOCGIWENCODE */
-    (iw_handler) ar6000_ioctl_siwpower,         /* SIOCSIWPOWER */
-    (iw_handler) ar6000_ioctl_giwpower,         /* SIOCGIWPOWER */
+    (iw_handler) lock_ar6000_ioctl_siwtxpow,         /* SIOCSIWTXPOW */
+    (iw_handler) lock_ar6000_ioctl_giwtxpow,         /* SIOCGIWTXPOW */
+    (iw_handler) lock_ar6000_ioctl_siwretry,         /* SIOCSIWRETRY */
+    (iw_handler) lock_ar6000_ioctl_giwretry,         /* SIOCGIWRETRY */
+    (iw_handler) lock_ar6000_ioctl_siwencode,        /* SIOCSIWENCODE */
+    (iw_handler) lock_ar6000_ioctl_giwencode,        /* SIOCGIWENCODE */
+    (iw_handler) lock_ar6000_ioctl_siwpower,         /* SIOCSIWPOWER */
+    (iw_handler) lock_ar6000_ioctl_giwpower,         /* SIOCGIWPOWER */
     (iw_handler) NULL,	/* -- hole -- */
     (iw_handler) NULL,	/* -- hole -- */
-    (iw_handler) ar6000_ioctl_siwgenie,	/* SIOCSIWGENIE */
-    (iw_handler) ar6000_ioctl_giwgenie,	/* SIOCGIWGENIE */
-    (iw_handler) ar6000_ioctl_siwauth,	/* SIOCSIWAUTH */
-    (iw_handler) ar6000_ioctl_giwauth,	/* SIOCGIWAUTH */
-    (iw_handler) ar6000_ioctl_siwencodeext,/* SIOCSIWENCODEEXT */
-    (iw_handler) ar6000_ioctl_giwencodeext,/* SIOCGIWENCODEEXT */
+    (iw_handler) lock_ar6000_ioctl_siwgenie,	/* SIOCSIWGENIE */
+    (iw_handler) lock_ar6000_ioctl_giwgenie,	/* SIOCGIWGENIE */
+    (iw_handler) lock_ar6000_ioctl_siwauth,	/* SIOCSIWAUTH */
+    (iw_handler) lock_ar6000_ioctl_giwauth,	/* SIOCGIWAUTH */
+    (iw_handler) lock_ar6000_ioctl_siwencodeext,/* SIOCSIWENCODEEXT */
+    (iw_handler) lock_ar6000_ioctl_giwencodeext,/* SIOCGIWENCODEEXT */
     (iw_handler) NULL,		/* SIOCSIWPMKSA */
 };
 
 static const iw_handler ath_priv_handlers[] = {
-    (iw_handler) ar6000_ioctl_setparam,         /* SIOCWFIRSTPRIV+0 */
-    (iw_handler) ar6000_ioctl_getparam,         /* SIOCWFIRSTPRIV+1 */
-    (iw_handler) ar6000_ioctl_setkey,           /* SIOCWFIRSTPRIV+2 */
-    (iw_handler) ar6000_ioctl_setwmmparams,     /* SIOCWFIRSTPRIV+3 */
-    (iw_handler) ar6000_ioctl_delkey,           /* SIOCWFIRSTPRIV+4 */
-    (iw_handler) ar6000_ioctl_getwmmparams,     /* SIOCWFIRSTPRIV+5 */
-    (iw_handler) ar6000_ioctl_setoptie,         /* SIOCWFIRSTPRIV+6 */
-    (iw_handler) ar6000_ioctl_setmlme,          /* SIOCWFIRSTPRIV+7 */
-    (iw_handler) ar6000_ioctl_addpmkid,         /* SIOCWFIRSTPRIV+8 */
+    (iw_handler) lock_ar6000_ioctl_setparam,         /* SIOCWFIRSTPRIV+0 */
+    (iw_handler) lock_ar6000_ioctl_getparam,         /* SIOCWFIRSTPRIV+1 */
+    (iw_handler) lock_ar6000_ioctl_setkey,           /* SIOCWFIRSTPRIV+2 */
+    (iw_handler) lock_ar6000_ioctl_setwmmparams,     /* SIOCWFIRSTPRIV+3 */
+    (iw_handler) lock_ar6000_ioctl_delkey,           /* SIOCWFIRSTPRIV+4 */
+    (iw_handler) lock_ar6000_ioctl_getwmmparams,     /* SIOCWFIRSTPRIV+5 */
+    (iw_handler) lock_ar6000_ioctl_setoptie,         /* SIOCWFIRSTPRIV+6 */
+    (iw_handler) lock_ar6000_ioctl_setmlme,          /* SIOCWFIRSTPRIV+7 */
+    (iw_handler) lock_ar6000_ioctl_addpmkid,         /* SIOCWFIRSTPRIV+8 */
 };
 
 #define IW_PRIV_TYPE_KEY \
-- 
1.6.3.3


--------------040209030403080108050906--



More information about the openmoko-kernel mailing list