aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband/core/iwcm.c
diff options
context:
space:
mode:
authorKrishna Kumar <krkumar2@in.ibm.com>2006-11-09 09:30:34 +0530
committerRoland Dreier <rolandd@cisco.com>2006-11-29 15:33:07 -0800
commit33ba0fa9f315ce32fbb86fa671c131f5355b52a1 (patch)
tree3b6bd7f9efe82fe4e7298497c312b9ee71f4911c /drivers/infiniband/core/iwcm.c
parentIB: Convert kmem_cache_t -> struct kmem_cache (diff)
downloadlinux-dev-33ba0fa9f315ce32fbb86fa671c131f5355b52a1.tar.xz
linux-dev-33ba0fa9f315ce32fbb86fa671c131f5355b52a1.zip
RDMA/iwcm: Fix memory corruption bug in cm_work_handler()
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>
Diffstat (limited to 'drivers/infiniband/core/iwcm.c')
-rw-r--r--drivers/infiniband/core/iwcm.c7
1 files changed, 4 insertions, 3 deletions
diff --git a/drivers/infiniband/core/iwcm.c b/drivers/infiniband/core/iwcm.c
index 2bbcfa5c6e27..22d498c9a68b 100644
--- a/drivers/infiniband/core/iwcm.c
+++ b/drivers/infiniband/core/iwcm.c
@@ -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);