FAILED: patch "[PATCH] ksmbd: fix possible memory leak in smb2_lock()" failed to apply to 5.15-stable tree
[email protected]
maintainerThe patch below does not apply to the 5.15-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.
To reproduce the conflict and resubmit, you may use the following commands:
git fetch https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/ linux-5.15.y
git checkout FETCH_HEAD
git cherry-pick -x d3ca9f7aeba793d74361d88a8800b2f205c9236b
# <resolve conflicts, build, test, etc.>
git commit -s
git send-email --to '<[email protected]>' --in-reply-to '[email protected]' --subject-prefix 'PATCH 5.15.y' HEAD^..
Possible dependencies:
d3ca9f7aeba7 ("ksmbd: fix possible memory leak in smb2_lock()") edf5f0548fbb ("ksmbd: replace usage of found with dedicated list iterator variable") cb4517201b8a ("ksmbd: remove smb2_buf_length in smb2_hdr") 341b16014bf8 ("ksmdb: use cmd helper variable in smb2_get_ksmbd_tcon()")
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From d3ca9f7aeba793d74361d88a8800b2f205c9236b Mon Sep 17 00:00:00 2001
From: Hangyu Hua <[email protected]>
Date: Fri, 17 Feb 2023 22:29:34 +0900
Subject: [PATCH] ksmbd: fix possible memory leak in smb2_lock()
argv needs to be free when setup_async_work fails or when the current process is woken up.
fs/ksmbd/smb2pdu.c +13 -15
@@ -6626,7 +6626,7 @@ int smb2_cancel(struct ksmbd_work *work)struct ksmbd_conn *conn = work->conn;struct smb2_hdr *hdr =smb2_get_msg (work->request_buf);struct smb2_hdr *chdr; -struct ksmbd_work *cancel_work =NULL , *iter; +struct ksmbd_work *iter;struct list_head *command_list; ksmbd_debug(SMB, "smb2 cancel called on mid %llu, async flags 0x%x\n",
@@ -6648,7 +6648,9 @@ int smb2_cancel(struct ksmbd_work *work)"smb2 with AsyncId %llu cancelled command = 0x%x\n" ,le64_to_cpu (hdr->Id.AsyncId), le16_to_cpu(chdr->Command)); - cancel_work = iter; + iter->state =KSMBD_WORK_CANCELLED ; +if (iter->cancel_fn) + iter->cancel_fn (iter->cancel_argv);break ; }spin_unlock (&conn->request_lock);
@@ -6667,18 +6669,12 @@ int smb2_cancel(struct ksmbd_work *work)"smb2 with mid %llu cancelled command = 0x%x\n" ,le64_to_cpu (hdr->MessageId), le16_to_cpu(chdr->Command)); - cancel_work = iter; + iter->state =KSMBD_WORK_CANCELLED ;break ; }spin_unlock (&conn->request_lock); } -if (cancel_work) { - cancel_work->state =KSMBD_WORK_CANCELLED ; -if (cancel_work->cancel_fn) - cancel_work->cancel_fn (cancel_work->cancel_argv); - } -/* For SMB2_CANCEL command itself send no response*/ work->send_no_response =1 ;return 0 ;
@@ -7043,6 +7039,14 @@ int smb2_lock(struct ksmbd_work *work)ksmbd_vfs_posix_lock_wait (flock); +spin_lock (&work->conn->request_lock); +spin_lock (&fp->f_lock); +list_del (&work->fp_entry); + work->cancel_fn =NULL ; +kfree (argv); +spin_unlock (&fp->f_lock); +spin_unlock (&work->conn->request_lock); +if (work->state !=KSMBD_WORK_ACTIVE ) {list_del (&smb_lock->llist);spin_lock (&work->conn->llist_lock);
@@ -7051,9 +7055,6 @@ int smb2_lock(struct ksmbd_work *work)locks_free_lock (flock);if (work->state ==KSMBD_WORK_CANCELLED ) { -spin_lock (&fp->f_lock); -list_del (&work->fp_entry); -spin_unlock (&fp->f_lock); rsp->hdr.Status =STATUS_CANCELLED ;kfree (smb_lock);
@@ -7075,9 +7076,6 @@ int smb2_lock(struct ksmbd_work *work)list_del (&smb_lock->clist);spin_unlock (&work->conn->llist_lock); -spin_lock (&fp->f_lock); -list_del (&work->fp_entry); -spin_unlock (&fp->f_lock); goto retry; }else if (!rc) {spin_lock (&work->conn->llist_lock);
fs/ksmbd/vfs_cache.c +2 -3
@@ -364,12 +364,11 @@ static void __put_fd_final(struct ksmbd_work *work, struct ksmbd_file *fp)static void set_close_state_blocked_works (struct ksmbd_file *fp) { -struct ksmbd_work *cancel_work, *ctmp; +struct ksmbd_work *cancel_work;spin_lock (&fp->f_lock); -list_for_each_entry_safe (cancel_work, ctmp, &fp->blocked_works, +list_for_each_entry (cancel_work, &fp->blocked_works, fp_entry) { -list_del (&cancel_work->fp_entry); cancel_work->state =KSMBD_WORK_CLOSED ; cancel_work->cancel_fn (cancel_work->cancel_argv); }