mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-16 16:54:20 +08:00
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.
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>
This commit is contained in:
parent
fb533473d1
commit
d3ca9f7aeb
@ -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 @@ skip:
|
||||
|
||||
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 @@ skip:
|
||||
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 @@ skip:
|
||||
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
Block a user