aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/cnic.c
diff options
context:
space:
mode:
authorMichael Chan <mchan@broadcom.com>2010-02-24 09:42:06 -0500
committerDavid S. Miller <davem@davemloft.net>2010-02-26 05:10:13 -0500
commitd02a5e6c2fba8b114c44cf05085fca07180f37f1 (patch)
treee91243a2c2256dec2b9f7ad20273c55cdc137358 /drivers/net/cnic.c
parent66883e90eaa0dd55d395c0f9a0c6da5d50809804 (diff)
cnic: Fix panic in cnic_iscsi_nl_msg_recv() when device is down.
Some data structures are freed when the device is down and it will crash if an ISCSI netlink message is received. Add RCU protection to prevent this. In the shutdown path, ulp_ops[CNIC_ULP_L4] is assigned NULL and rcu_synchronized before freeing the data structures. Signed-off-by: Michael Chan <mchan@broadcom.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/cnic.c')
-rw-r--r--drivers/net/cnic.c7
1 files changed, 7 insertions, 0 deletions
diff --git a/drivers/net/cnic.c b/drivers/net/cnic.c
index 40865aac2afa..45584442a35c 100644
--- a/drivers/net/cnic.c
+++ b/drivers/net/cnic.c
@@ -327,6 +327,12 @@ static int cnic_iscsi_nl_msg_recv(struct cnic_dev *dev, u32 msg_type,
327 if (l5_cid >= MAX_CM_SK_TBL_SZ) 327 if (l5_cid >= MAX_CM_SK_TBL_SZ)
328 break; 328 break;
329 329
330 rcu_read_lock();
331 if (!rcu_dereference(cp->ulp_ops[CNIC_ULP_L4])) {
332 rc = -ENODEV;
333 rcu_read_unlock();
334 break;
335 }
330 csk = &cp->csk_tbl[l5_cid]; 336 csk = &cp->csk_tbl[l5_cid];
331 csk_hold(csk); 337 csk_hold(csk);
332 if (cnic_in_use(csk)) { 338 if (cnic_in_use(csk)) {
@@ -341,6 +347,7 @@ static int cnic_iscsi_nl_msg_recv(struct cnic_dev *dev, u32 msg_type,
341 cnic_cm_set_pg(csk); 347 cnic_cm_set_pg(csk);
342 } 348 }
343 csk_put(csk); 349 csk_put(csk);
350 rcu_read_unlock();
344 rc = 0; 351 rc = 0;
345 } 352 }
346 } 353 }