diff mbox

[06/19] brcmfmac: correct handling IF firmware event

Message ID 1352947583-25341-7-git-send-email-frankyl@broadcom.com (mailing list archive)
State Not Applicable, archived
Headers show

Commit Message

Franky Lin Nov. 15, 2012, 2:46 a.m. UTC
From: Arend van Spriel <arend@broadcom.com>

Testing revealed the IF ADD event contains the interface
index of the new interface. This would result in a NULL
pointer access when handling the event.

Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
Reviewed-by: Hante Meuleman <meuleman@broadcom.com>
Signed-off-by: Arend van Spriel <arend@broadcom.com>
Signed-off-by: Franky Lin <frankyl@broadcom.com>
---
 drivers/net/wireless/brcm80211/brcmfmac/fweh.c |   66 +++++++++++-------------
 1 file changed, 31 insertions(+), 35 deletions(-)
diff mbox

Patch

diff --git a/drivers/net/wireless/brcm80211/brcmfmac/fweh.c b/drivers/net/wireless/brcm80211/brcmfmac/fweh.c
index 825be26..e1521af 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/fweh.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/fweh.c
@@ -191,42 +191,13 @@  static const char *brcmf_fweh_event_name(enum brcmf_fweh_event_code code)
 /**
  * brcmf_fweh_queue_event() - create and queue event.
  *
- * @ifp: firmware interface object.
- * @code: event code.
- * @pkt: event ether packet.
+ * @fweh: firmware event handling info.
+ * @event: event queue entry.
  */
-static void brcmf_fweh_queue_event(struct brcmf_if *ifp,
-				   enum brcmf_fweh_event_code code,
-				   struct brcmf_event *pkt)
+static void brcmf_fweh_queue_event(struct brcmf_fweh_info *fweh,
+				   struct brcmf_fweh_queue_item *event)
 {
-	struct brcmf_fweh_info *fweh = &ifp->drvr->fweh;
-	struct brcmf_fweh_queue_item *event;
-	gfp_t alloc_flag = GFP_KERNEL;
 	ulong flags;
-	void *data;
-	u32 datalen;
-
-	/* determine event data */
-	datalen = get_unaligned_be32(&pkt->msg.datalen);
-	data = &pkt[1];
-
-	if (!ifp->ndev || (code != BRCMF_E_IF && !fweh->evt_handler[code])) {
-		brcmf_dbg(EVENT, "event ignored: code=%d\n", code);
-		brcmf_dbg_hex_dump(BRCMF_EVENT_ON(), data, datalen, "event:");
-		return;
-	}
-
-	if (in_interrupt())
-		alloc_flag = GFP_ATOMIC;
-
-	event = kzalloc(sizeof(*event) + datalen, alloc_flag);
-	event->code = code;
-	event->ifidx = ifp->idx;
-
-	/* use memcpy to get aligned event message */
-	memcpy(&event->emsg, &pkt->msg, sizeof(event->emsg));
-	memcpy(event->data, data, datalen);
-	memcpy(event->ifaddr, pkt->eth.h_dest, ETH_ALEN);
 
 	spin_lock_irqsave(&fweh->evt_q_lock, flags);
 	list_add_tail(&event->q, &fweh->event_q);
@@ -489,10 +460,35 @@  void brcmf_fweh_process_event(struct brcmf_pub *drvr,
 			      struct brcmf_event *event_packet, u8 *ifidx)
 {
 	enum brcmf_fweh_event_code code;
+	struct brcmf_fweh_info *fweh = &drvr->fweh;
+	struct brcmf_fweh_queue_item *event;
+	gfp_t alloc_flag = GFP_KERNEL;
+	void *data;
+	u32 datalen;
 
-	/* determine event code and interface index */
+	/* get event info */
 	code = get_unaligned_be32(&event_packet->msg.event_type);
+	datalen = get_unaligned_be32(&event_packet->msg.datalen);
 	*ifidx = event_packet->msg.ifidx;
+	data = &event_packet[1];
+
+	if (code != BRCMF_E_IF && !fweh->evt_handler[code]) {
+		brcmf_dbg(EVENT, "event ignored: code=%d\n", code);
+		brcmf_dbg_hex_dump(BRCMF_EVENT_ON(), data, datalen, "event:");
+		return;
+	}
+
+	if (in_interrupt())
+		alloc_flag = GFP_ATOMIC;
+
+	event = kzalloc(sizeof(*event) + datalen, alloc_flag);
+	event->code = code;
+	event->ifidx = *ifidx;
+
+	/* use memcpy to get aligned event message */
+	memcpy(&event->emsg, &event_packet->msg, sizeof(event->emsg));
+	memcpy(event->data, data, datalen);
+	memcpy(event->ifaddr, event_packet->eth.h_dest, ETH_ALEN);
 
-	brcmf_fweh_queue_event(drvr->iflist[*ifidx], code, event_packet);
+	brcmf_fweh_queue_event(fweh, event);
 }