dlm: fix user space lkb refcounting
authorAlexander Aring <aahringo@redhat.com>
Tue, 12 Mar 2024 17:05:07 +0000 (13:05 -0400)
committerDavid Teigland <teigland@redhat.com>
Tue, 12 Mar 2024 17:12:52 +0000 (12:12 -0500)
This patch fixes to check on the right return value if it was the last
callback. The rv variable got overwritten by the return of
copy_result_to_user(). Fixing it by introducing a second variable for
the return value and don't let rv being overwritten.

Cc: stable@vger.kernel.org
Fixes: 61bed0baa4db ("fs: dlm: use a non-static queue for callbacks")
Reported-by: Valentin Vidić <vvidic@valentin-vidic.from.hr>
Closes: https://lore.kernel.org/gfs2/Ze4qSvzGJDt5yxC3@valentin-vidic.from.hr
Signed-off-by: Alexander Aring <aahringo@redhat.com>
Signed-off-by: David Teigland <teigland@redhat.com>
fs/dlm/user.c

index 695e691b38b318395f241de0a2f28c5e48e30a4f..9f9b68448830ece12fd342e79ef1f2ccf6f9f1ae 100644 (file)
@@ -806,7 +806,7 @@ static ssize_t device_read(struct file *file, char __user *buf, size_t count,
        struct dlm_lkb *lkb;
        DECLARE_WAITQUEUE(wait, current);
        struct dlm_callback *cb;
-       int rv, copy_lvb = 0;
+       int rv, ret, copy_lvb = 0;
        int old_mode, new_mode;
 
        if (count == sizeof(struct dlm_device_version)) {
@@ -906,9 +906,9 @@ static ssize_t device_read(struct file *file, char __user *buf, size_t count,
                trace_dlm_ast(lkb->lkb_resource->res_ls, lkb);
        }
 
-       rv = copy_result_to_user(lkb->lkb_ua,
-                                test_bit(DLM_PROC_FLAGS_COMPAT, &proc->flags),
-                                cb->flags, cb->mode, copy_lvb, buf, count);
+       ret = copy_result_to_user(lkb->lkb_ua,
+                                 test_bit(DLM_PROC_FLAGS_COMPAT, &proc->flags),
+                                 cb->flags, cb->mode, copy_lvb, buf, count);
 
        kref_put(&cb->ref, dlm_release_callback);
 
@@ -916,7 +916,7 @@ static ssize_t device_read(struct file *file, char __user *buf, size_t count,
        if (rv == DLM_DEQUEUE_CALLBACK_LAST)
                dlm_put_lkb(lkb);
 
-       return rv;
+       return ret;
 }
 
 static __poll_t device_poll(struct file *file, poll_table *wait)