diff options
author | Alexander Aring <aahringo@redhat.com> | 2022-09-01 12:05:32 -0400 |
---|---|---|
committer | David Teigland <teigland@redhat.com> | 2022-09-26 09:58:07 -0500 |
commit | 3b7610302a75fc1032a6c9462862bec6948f85c9 (patch) | |
tree | 33b042a6dd910cf283144770ee9000e49b554205 /fs/dlm | |
parent | 56171e0db23a5e0edce1596dd2792b95ffe57bd3 (diff) |
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: 7a3de7324c2b ("fs: dlm: trace user space callbacks")
Reported-by: Dan Carpenter <dan.carpenter@oracle.com>
Signed-off-by: Alexander Aring <aahringo@redhat.com>
Signed-off-by: David Teigland <teigland@redhat.com>
Diffstat (limited to 'fs/dlm')
-rw-r--r-- | fs/dlm/lock.c | 15 |
1 files changed, 8 insertions, 7 deletions
diff --git a/fs/dlm/lock.c b/fs/dlm/lock.c index c830feb26384..94a72ede5764 100644 --- a/fs/dlm/lock.c +++ b/fs/dlm/lock.c @@ -5835,6 +5835,7 @@ int dlm_user_request(struct dlm_ls *ls, struct dlm_user_args *ua, { struct dlm_lkb *lkb; struct dlm_args args; + bool do_put = true; int error; dlm_lock_recovery(ls); @@ -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); if (!ua->lksb.sb_lvbptr) { kfree(ua); - __put_lkb(ls, lkb); error = -ENOMEM; - goto out_trace_end; + goto out_put; } } #ifdef CONFIG_DLM_DEPRECATED_API @@ -5867,8 +5867,7 @@ int dlm_user_request(struct dlm_ls *ls, struct dlm_user_args *ua, kfree(ua->lksb.sb_lvbptr); ua->lksb.sb_lvbptr = NULL; kfree(ua); - __put_lkb(ls, lkb); - goto out_trace_end; + goto out_put; } /* 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, error = 0; fallthrough; default: - __put_lkb(ls, lkb); - goto out_trace_end; + goto out_put; } /* 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, hold_lkb(lkb); list_add_tail(&lkb->lkb_ownqueue, &ua->proc->locks); 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); + if (do_put) + __put_lkb(ls, lkb); out: dlm_unlock_recovery(ls); return error; |