Skip to content

Commit 80ae5fb

Browse files
committed
Merge tag 'v6.15-rc5-ksmbd-server-fixes' of git://git.samba.org/ksmbd
Pull smb server fixes from Steve French: - Fix UAF closing file table (e.g. in tree disconnect) - Fix potential out of bounds write - Fix potential memory leak parsing lease state in open - Fix oops in rename with empty target * tag 'v6.15-rc5-ksmbd-server-fixes' of git://git.samba.org/ksmbd: ksmbd: Fix UAF in __close_file_table_ids ksmbd: prevent out-of-bounds stream writes by validating *pos ksmbd: fix memory leak in parse_lease_state() ksmbd: prevent rename with empty string
2 parents d76bb1e + 36991c1 commit 80ae5fb

File tree

4 files changed

+43
-9
lines changed

4 files changed

+43
-9
lines changed

fs/smb/server/oplock.c

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1496,7 +1496,7 @@ struct lease_ctx_info *parse_lease_state(void *open_req)
14961496

14971497
if (le16_to_cpu(cc->DataOffset) + le32_to_cpu(cc->DataLength) <
14981498
sizeof(struct create_lease_v2) - 4)
1499-
return NULL;
1499+
goto err_out;
15001500

15011501
memcpy(lreq->lease_key, lc->lcontext.LeaseKey, SMB2_LEASE_KEY_SIZE);
15021502
lreq->req_state = lc->lcontext.LeaseState;
@@ -1512,7 +1512,7 @@ struct lease_ctx_info *parse_lease_state(void *open_req)
15121512

15131513
if (le16_to_cpu(cc->DataOffset) + le32_to_cpu(cc->DataLength) <
15141514
sizeof(struct create_lease))
1515-
return NULL;
1515+
goto err_out;
15161516

15171517
memcpy(lreq->lease_key, lc->lcontext.LeaseKey, SMB2_LEASE_KEY_SIZE);
15181518
lreq->req_state = lc->lcontext.LeaseState;
@@ -1521,6 +1521,9 @@ struct lease_ctx_info *parse_lease_state(void *open_req)
15211521
lreq->version = 1;
15221522
}
15231523
return lreq;
1524+
err_out:
1525+
kfree(lreq);
1526+
return NULL;
15241527
}
15251528

15261529
/**

fs/smb/server/smb2pdu.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -633,6 +633,11 @@ smb2_get_name(const char *src, const int maxlen, struct nls_table *local_nls)
633633
return name;
634634
}
635635

636+
if (*name == '\0') {
637+
kfree(name);
638+
return ERR_PTR(-EINVAL);
639+
}
640+
636641
if (*name == '\\') {
637642
pr_err("not allow directory name included leading slash\n");
638643
kfree(name);

fs/smb/server/vfs.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -426,6 +426,13 @@ static int ksmbd_vfs_stream_write(struct ksmbd_file *fp, char *buf, loff_t *pos,
426426
goto out;
427427
}
428428

429+
if (v_len <= *pos) {
430+
pr_err("stream write position %lld is out of bounds (stream length: %zd)\n",
431+
*pos, v_len);
432+
err = -EINVAL;
433+
goto out;
434+
}
435+
429436
if (v_len < size) {
430437
wbuf = kvzalloc(size, KSMBD_DEFAULT_GFP);
431438
if (!wbuf) {

fs/smb/server/vfs_cache.c

Lines changed: 26 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -661,21 +661,40 @@ __close_file_table_ids(struct ksmbd_file_table *ft,
661661
bool (*skip)(struct ksmbd_tree_connect *tcon,
662662
struct ksmbd_file *fp))
663663
{
664-
unsigned int id;
665-
struct ksmbd_file *fp;
666-
int num = 0;
664+
struct ksmbd_file *fp;
665+
unsigned int id = 0;
666+
int num = 0;
667+
668+
while (1) {
669+
write_lock(&ft->lock);
670+
fp = idr_get_next(ft->idr, &id);
671+
if (!fp) {
672+
write_unlock(&ft->lock);
673+
break;
674+
}
667675

668-
idr_for_each_entry(ft->idr, fp, id) {
669-
if (skip(tcon, fp))
676+
if (skip(tcon, fp) ||
677+
!atomic_dec_and_test(&fp->refcount)) {
678+
id++;
679+
write_unlock(&ft->lock);
670680
continue;
681+
}
671682

672683
set_close_state_blocked_works(fp);
684+
idr_remove(ft->idr, fp->volatile_id);
685+
fp->volatile_id = KSMBD_NO_FID;
686+
write_unlock(&ft->lock);
687+
688+
down_write(&fp->f_ci->m_lock);
689+
list_del_init(&fp->node);
690+
up_write(&fp->f_ci->m_lock);
673691

674-
if (!atomic_dec_and_test(&fp->refcount))
675-
continue;
676692
__ksmbd_close_fd(ft, fp);
693+
677694
num++;
695+
id++;
678696
}
697+
679698
return num;
680699
}
681700

0 commit comments

Comments
 (0)