Skip to content

Commit

Permalink
ksmbd: fix possible memory leak in smb2_lock()
Browse files Browse the repository at this point in the history
argv needs to be free when setup_async_work fails or when the current
process is woken up.

Fixes: e2f3448 ("cifsd: add server-side procedures for SMB3")
Cc: [email protected]
Signed-off-by: Hangyu Hua <[email protected]>
Acked-by: Namjae Jeon <[email protected]>
Signed-off-by: Steve French <[email protected]>
  • Loading branch information
HBh25Y authored and Steve French committed Feb 19, 2023
1 parent fb53347 commit d3ca9f7
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 18 deletions.
28 changes: 13 additions & 15 deletions fs/ksmbd/smb2pdu.c
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand All @@ -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);
Expand All @@ -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;
Expand Down Expand Up @@ -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);
Expand All @@ -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);
Expand All @@ -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);
Expand Down
5 changes: 2 additions & 3 deletions fs/ksmbd/vfs_cache.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Expand Down

0 comments on commit d3ca9f7

Please sign in to comment.