On 1/23/2012 10:51 AM, Parikh, Neerav wrote:


-----Original Message-----
From: devel-boun...@open-fcoe.org [mailto:devel-boun...@open-fcoe.org]
On Behalf Of Bhanu Prakash Gollapudi
Sent: Friday, January 20, 2012 4:00 PM
To: devel@open-fcoe.org
Subject: [Open-FCoE] [PATCH] libfc: Fix panic in fc_exch_recv

Adding and removing the host into the zone causes this panic.

BUG: unable to handle kernel NULL pointer dereference at
00000000000000a0
IP: [<ffffffffa0491707>] fc_exch_recv+0xc57/0xe70 [libfc]
Call Trace:
[<ffffffffa050e04b>] bnx2fc_l2_rcv_thread+0x37b/0x430 [bnx2fc]
[<ffffffffa050dcd0>] ? bnx2fc_l2_rcv_thread+0x0/0x430 [bnx2fc]
[<ffffffff81090886>] kthread+0x96/0xa0
[<ffffffff8100c14a>] child_rip+0xa/0x20
[<ffffffff810907f0>] ? kthread+0x0/0xa0
[<ffffffff8100c140>] ? child_rip+0x0/0x20

During fc_exch_reset, the active exchanges are aborted and the exch is
deleted.
As part of processing ABTS response, due to 'ep' being NULL, any access
to ep in
fc_exch_recv_bls() causes this panic. Fixed to return without accessing
ep, if
NULL.
Can you explain where in fc_exch_recv_bls() "ep" is accessed when it's NULL?
As, looking at the code for that function it doesn't seem like there is any
flow that may cause a NULL pointer dereference accessing "ep" if it is NULL.
It accesses ep here:
                default:
                        FC_EXCH_DBG(ep, "BLS rctl %x - %s received",
                                    fh->fh_r_ctl,
                                    fc_exch_rctl_name(fh->fh_r_ctl));
                        break;
                }

In f_ctl, we have both FC_FC_EX_CTX and FC_FC_SEQ_CTX set. This happens because, with one of the recent changes, fc_exch_reset issues LOGO and immediately sends ABTS for that LOGO. If the target sees ABTS before processing LOGO, it can reply with both these bits set in the response.

however, in fc_exch_reset, we would have free'd up the ep, and hence the code path goes here. Since it is not class 2, it tries printing the debug message references NULL ep.


For the fc_exch_recv_abts() where the "ep" is passed as it is the function
handles the case where "ep" might be NULL. Also, prior to the change
fc_exch_recv_abts() function sent out a BA_RJT in case "ep" was NULL but after
the proposed change that will not be the case, so there is an impact there that
perhaps changes the behavior for the target mode.
Yes, it did not go into this code path, and you are right. So, we have to check for NULL ep, case-by-case basis. We should check for NULL ep for dbg case and before calling fc_exch_abts_resp().

If you do not have objections, I'll send a v2 patch.

thanks.


Thanks,
Neerav


Signed-off-by: Bhanu Prakash Gollapudi<bprak...@broadcom.com>
---
  drivers/scsi/libfc/fc_exch.c |   12 ++++++------
  1 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/scsi/libfc/fc_exch.c
b/drivers/scsi/libfc/fc_exch.c
index 4d70d96..23d3075 100644
--- a/drivers/scsi/libfc/fc_exch.c
+++ b/drivers/scsi/libfc/fc_exch.c
@@ -1632,6 +1632,10 @@ static void fc_exch_recv_bls(struct fc_exch_mgr
*mp, struct fc_frame *fp)
                ep->esb_stat |= ESB_ST_SEQ_INIT;
                spin_unlock_bh(&ep->ex_lock);
        }
+       if (!ep) {
+               fc_frame_free(fp);
+               return;
+       }
        if (f_ctl&  FC_FC_SEQ_CTX) {
                /*
                 * A response to a sequence we initiated.
@@ -1652,10 +1656,7 @@ static void fc_exch_recv_bls(struct fc_exch_mgr
*mp, struct fc_frame *fp)
                switch (fh->fh_r_ctl) {
                case FC_RCTL_BA_RJT:
                case FC_RCTL_BA_ACC:
-                       if (ep)
-                               fc_exch_abts_resp(ep, fp);
-                       else
-                               fc_frame_free(fp);
+                       fc_exch_abts_resp(ep, fp);
                        break;
                case FC_RCTL_BA_ABTS:
                        fc_exch_recv_abts(ep, fp);
@@ -1665,8 +1666,7 @@ static void fc_exch_recv_bls(struct fc_exch_mgr
*mp, struct fc_frame *fp)
                        break;
                }
        }
-       if (ep)
-               fc_exch_release(ep);    /* release hold taken by
fc_exch_find */
+       fc_exch_release(ep);    /* release hold taken by fc_exch_find */
  }

  /**
--
1.7.0.6


_______________________________________________
devel mailing list
devel@open-fcoe.org
https://lists.open-fcoe.org/mailman/listinfo/devel



_______________________________________________
devel mailing list
devel@open-fcoe.org
https://lists.open-fcoe.org/mailman/listinfo/devel

Reply via email to