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>
This commit is contained in:
parent
e54f81889c
commit
33ba0fa9f3
|
@ -829,7 +829,8 @@ static int process_event(struct iwcm_id_private *cm_id_priv,
|
||||||
*/
|
*/
|
||||||
static void cm_work_handler(void *arg)
|
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;
|
struct iwcm_id_private *cm_id_priv = work->cm_id;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
int empty;
|
int empty;
|
||||||
|
@ -842,11 +843,11 @@ static void cm_work_handler(void *arg)
|
||||||
struct iwcm_work, list);
|
struct iwcm_work, list);
|
||||||
list_del_init(&work->list);
|
list_del_init(&work->list);
|
||||||
empty = list_empty(&cm_id_priv->work_list);
|
empty = list_empty(&cm_id_priv->work_list);
|
||||||
lwork = *work;
|
levent = work->event;
|
||||||
put_work(work);
|
put_work(work);
|
||||||
spin_unlock_irqrestore(&cm_id_priv->lock, flags);
|
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) {
|
if (ret) {
|
||||||
set_bit(IWCM_F_CALLBACK_DESTROY, &cm_id_priv->flags);
|
set_bit(IWCM_F_CALLBACK_DESTROY, &cm_id_priv->flags);
|
||||||
destroy_cm_id(&cm_id_priv->id);
|
destroy_cm_id(&cm_id_priv->id);
|
||||||
|
|
Loading…
Reference in New Issue