ksmbd: fix possible memory leak in smb2_lock()
commitd3ca9f7aeb
upstream. argv needs to be free when setup_async_work fails or when the current process is woken up. Fixes:e2f34481b2
("cifsd: add server-side procedures for SMB3") Cc: stable@vger.kernel.org Signed-off-by: Hangyu Hua <hbh25y@gmail.com> Acked-by: Namjae Jeon <linkinjeon@kernel.org> Signed-off-by: Steve French <stfrench@microsoft.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
df6c263a31
commit
6bf555ed89
|
@ -6642,7 +6642,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",
|
||||
|
@ -6664,7 +6664,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);
|
||||
|
@ -6683,18 +6685,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;
|
||||
|
@ -7055,6 +7051,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);
|
||||
|
@ -7063,9 +7067,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);
|
||||
|
@ -7087,9 +7088,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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue