]> err.no Git - linux-2.6/commitdiff
RDMA/iwcm: Fix memory corruption bug in cm_work_handler()
authorKrishna Kumar <krkumar2@in.ibm.com>
Thu, 9 Nov 2006 04:00:34 +0000 (09:30 +0530)
committerRoland Dreier <rolandd@cisco.com>
Wed, 29 Nov 2006 23:33:07 +0000 (15:33 -0800)
Possible memory corruption scenario: after putting the work entry back
on the work_free_list, we call process_event() which dereferences
work->event, which could have been modified to another value
meanwhile.

Signed-off-by: Krishna Kumar <krkumar2@in.ibm.com>
Acked-by: Steve Wise <swise@opengridcomputing.com>
Signed-off-by: Roland Dreier <rolandd@cisco.com>
drivers/infiniband/core/iwcm.c

index 2bbcfa5c6e27c03249d1d48c0031322f71414901..22d498c9a68bdf5dbaf07b05833dc45c47bffbe4 100644 (file)
@@ -829,7 +829,8 @@ static int process_event(struct iwcm_id_private *cm_id_priv,
  */
 static void cm_work_handler(void *arg)
 {
-       struct iwcm_work *work = arg, lwork;
+       struct iwcm_work *work = arg;
+       struct iw_cm_event levent;
        struct iwcm_id_private *cm_id_priv = work->cm_id;
        unsigned long flags;
        int empty;
@@ -842,11 +843,11 @@ static void cm_work_handler(void *arg)
                                  struct iwcm_work, list);
                list_del_init(&work->list);
                empty = list_empty(&cm_id_priv->work_list);
-               lwork = *work;
+               levent = work->event;
                put_work(work);
                spin_unlock_irqrestore(&cm_id_priv->lock, flags);
 
-               ret = process_event(cm_id_priv, &work->event);
+               ret = process_event(cm_id_priv, &levent);
                if (ret) {
                        set_bit(IWCM_F_CALLBACK_DESTROY, &cm_id_priv->flags);
                        destroy_cm_id(&cm_id_priv->id);