Commit 3b761030 authored by Alexander Aring's avatar Alexander Aring Committed by David Teigland

fs: dlm: fix possible use after free if tracing

This patch fixes a possible use after free if tracing for the specific
event is enabled. To avoid the use after free we introduce a out_put
label like all other user lock specific requests and safe in a boolean
to do a put or not which depends on the execution path of
dlm_user_request().

Cc: stable@vger.kernel.org
Fixes: 7a3de732 ("fs: dlm: trace user space callbacks")
Reported-by: default avatarDan Carpenter <dan.carpenter@oracle.com>
Signed-off-by: default avatarAlexander Aring <aahringo@redhat.com>
Signed-off-by: default avatarDavid Teigland <teigland@redhat.com>
parent 56171e0d
...@@ -5835,6 +5835,7 @@ int dlm_user_request(struct dlm_ls *ls, struct dlm_user_args *ua, ...@@ -5835,6 +5835,7 @@ int dlm_user_request(struct dlm_ls *ls, struct dlm_user_args *ua,
{ {
struct dlm_lkb *lkb; struct dlm_lkb *lkb;
struct dlm_args args; struct dlm_args args;
bool do_put = true;
int error; int error;
dlm_lock_recovery(ls); dlm_lock_recovery(ls);
...@@ -5851,9 +5852,8 @@ int dlm_user_request(struct dlm_ls *ls, struct dlm_user_args *ua, ...@@ -5851,9 +5852,8 @@ int dlm_user_request(struct dlm_ls *ls, struct dlm_user_args *ua,
ua->lksb.sb_lvbptr = kzalloc(DLM_USER_LVB_LEN, GFP_NOFS); ua->lksb.sb_lvbptr = kzalloc(DLM_USER_LVB_LEN, GFP_NOFS);
if (!ua->lksb.sb_lvbptr) { if (!ua->lksb.sb_lvbptr) {
kfree(ua); kfree(ua);
__put_lkb(ls, lkb);
error = -ENOMEM; error = -ENOMEM;
goto out_trace_end; goto out_put;
} }
} }
#ifdef CONFIG_DLM_DEPRECATED_API #ifdef CONFIG_DLM_DEPRECATED_API
...@@ -5867,8 +5867,7 @@ int dlm_user_request(struct dlm_ls *ls, struct dlm_user_args *ua, ...@@ -5867,8 +5867,7 @@ int dlm_user_request(struct dlm_ls *ls, struct dlm_user_args *ua,
kfree(ua->lksb.sb_lvbptr); kfree(ua->lksb.sb_lvbptr);
ua->lksb.sb_lvbptr = NULL; ua->lksb.sb_lvbptr = NULL;
kfree(ua); kfree(ua);
__put_lkb(ls, lkb); goto out_put;
goto out_trace_end;
} }
/* After ua is attached to lkb it will be freed by dlm_free_lkb(). /* After ua is attached to lkb it will be freed by dlm_free_lkb().
...@@ -5887,8 +5886,7 @@ int dlm_user_request(struct dlm_ls *ls, struct dlm_user_args *ua, ...@@ -5887,8 +5886,7 @@ int dlm_user_request(struct dlm_ls *ls, struct dlm_user_args *ua,
error = 0; error = 0;
fallthrough; fallthrough;
default: default:
__put_lkb(ls, lkb); goto out_put;
goto out_trace_end;
} }
/* add this new lkb to the per-process list of locks */ /* add this new lkb to the per-process list of locks */
...@@ -5896,8 +5894,11 @@ int dlm_user_request(struct dlm_ls *ls, struct dlm_user_args *ua, ...@@ -5896,8 +5894,11 @@ int dlm_user_request(struct dlm_ls *ls, struct dlm_user_args *ua,
hold_lkb(lkb); hold_lkb(lkb);
list_add_tail(&lkb->lkb_ownqueue, &ua->proc->locks); list_add_tail(&lkb->lkb_ownqueue, &ua->proc->locks);
spin_unlock(&ua->proc->locks_spin); spin_unlock(&ua->proc->locks_spin);
out_trace_end: do_put = false;
out_put:
trace_dlm_lock_end(ls, lkb, name, namelen, mode, flags, error, false); trace_dlm_lock_end(ls, lkb, name, namelen, mode, flags, error, false);
if (do_put)
__put_lkb(ls, lkb);
out: out:
dlm_unlock_recovery(ls); dlm_unlock_recovery(ls);
return error; return error;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment