Skip to content

Commit d3ca9f7

Browse files
HBh25Ysmfrench
authored andcommitted
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: 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]>
1 parent fb53347 commit d3ca9f7

File tree

2 files changed

+15
-18
lines changed

2 files changed

+15
-18
lines changed

fs/ksmbd/smb2pdu.c

Lines changed: 13 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -6626,7 +6626,7 @@ int smb2_cancel(struct ksmbd_work *work)
66266626
struct ksmbd_conn *conn = work->conn;
66276627
struct smb2_hdr *hdr = smb2_get_msg(work->request_buf);
66286628
struct smb2_hdr *chdr;
6629-
struct ksmbd_work *cancel_work = NULL, *iter;
6629+
struct ksmbd_work *iter;
66306630
struct list_head *command_list;
66316631

66326632
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)
66486648
"smb2 with AsyncId %llu cancelled command = 0x%x\n",
66496649
le64_to_cpu(hdr->Id.AsyncId),
66506650
le16_to_cpu(chdr->Command));
6651-
cancel_work = iter;
6651+
iter->state = KSMBD_WORK_CANCELLED;
6652+
if (iter->cancel_fn)
6653+
iter->cancel_fn(iter->cancel_argv);
66526654
break;
66536655
}
66546656
spin_unlock(&conn->request_lock);
@@ -6667,18 +6669,12 @@ int smb2_cancel(struct ksmbd_work *work)
66676669
"smb2 with mid %llu cancelled command = 0x%x\n",
66686670
le64_to_cpu(hdr->MessageId),
66696671
le16_to_cpu(chdr->Command));
6670-
cancel_work = iter;
6672+
iter->state = KSMBD_WORK_CANCELLED;
66716673
break;
66726674
}
66736675
spin_unlock(&conn->request_lock);
66746676
}
66756677

6676-
if (cancel_work) {
6677-
cancel_work->state = KSMBD_WORK_CANCELLED;
6678-
if (cancel_work->cancel_fn)
6679-
cancel_work->cancel_fn(cancel_work->cancel_argv);
6680-
}
6681-
66826678
/* For SMB2_CANCEL command itself send no response*/
66836679
work->send_no_response = 1;
66846680
return 0;
@@ -7043,6 +7039,14 @@ int smb2_lock(struct ksmbd_work *work)
70437039

70447040
ksmbd_vfs_posix_lock_wait(flock);
70457041

7042+
spin_lock(&work->conn->request_lock);
7043+
spin_lock(&fp->f_lock);
7044+
list_del(&work->fp_entry);
7045+
work->cancel_fn = NULL;
7046+
kfree(argv);
7047+
spin_unlock(&fp->f_lock);
7048+
spin_unlock(&work->conn->request_lock);
7049+
70467050
if (work->state != KSMBD_WORK_ACTIVE) {
70477051
list_del(&smb_lock->llist);
70487052
spin_lock(&work->conn->llist_lock);
@@ -7051,9 +7055,6 @@ int smb2_lock(struct ksmbd_work *work)
70517055
locks_free_lock(flock);
70527056

70537057
if (work->state == KSMBD_WORK_CANCELLED) {
7054-
spin_lock(&fp->f_lock);
7055-
list_del(&work->fp_entry);
7056-
spin_unlock(&fp->f_lock);
70577058
rsp->hdr.Status =
70587059
STATUS_CANCELLED;
70597060
kfree(smb_lock);
@@ -7075,9 +7076,6 @@ int smb2_lock(struct ksmbd_work *work)
70757076
list_del(&smb_lock->clist);
70767077
spin_unlock(&work->conn->llist_lock);
70777078

7078-
spin_lock(&fp->f_lock);
7079-
list_del(&work->fp_entry);
7080-
spin_unlock(&fp->f_lock);
70817079
goto retry;
70827080
} else if (!rc) {
70837081
spin_lock(&work->conn->llist_lock);

fs/ksmbd/vfs_cache.c

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -364,12 +364,11 @@ static void __put_fd_final(struct ksmbd_work *work, struct ksmbd_file *fp)
364364

365365
static void set_close_state_blocked_works(struct ksmbd_file *fp)
366366
{
367-
struct ksmbd_work *cancel_work, *ctmp;
367+
struct ksmbd_work *cancel_work;
368368

369369
spin_lock(&fp->f_lock);
370-
list_for_each_entry_safe(cancel_work, ctmp, &fp->blocked_works,
370+
list_for_each_entry(cancel_work, &fp->blocked_works,
371371
fp_entry) {
372-
list_del(&cancel_work->fp_entry);
373372
cancel_work->state = KSMBD_WORK_CLOSED;
374373
cancel_work->cancel_fn(cancel_work->cancel_argv);
375374
}

0 commit comments

Comments
 (0)