Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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

+43 -9
+5 -2
fs/smb/server/oplock.c
··· 1496 1496 1497 1497 if (le16_to_cpu(cc->DataOffset) + le32_to_cpu(cc->DataLength) < 1498 1498 sizeof(struct create_lease_v2) - 4) 1499 - return NULL; 1499 + goto err_out; 1500 1500 1501 1501 memcpy(lreq->lease_key, lc->lcontext.LeaseKey, SMB2_LEASE_KEY_SIZE); 1502 1502 lreq->req_state = lc->lcontext.LeaseState; ··· 1512 1512 1513 1513 if (le16_to_cpu(cc->DataOffset) + le32_to_cpu(cc->DataLength) < 1514 1514 sizeof(struct create_lease)) 1515 - return NULL; 1515 + goto err_out; 1516 1516 1517 1517 memcpy(lreq->lease_key, lc->lcontext.LeaseKey, SMB2_LEASE_KEY_SIZE); 1518 1518 lreq->req_state = lc->lcontext.LeaseState; ··· 1521 1521 lreq->version = 1; 1522 1522 } 1523 1523 return lreq; 1524 + err_out: 1525 + kfree(lreq); 1526 + return NULL; 1524 1527 } 1525 1528 1526 1529 /**
+5
fs/smb/server/smb2pdu.c
··· 633 633 return name; 634 634 } 635 635 636 + if (*name == '\0') { 637 + kfree(name); 638 + return ERR_PTR(-EINVAL); 639 + } 640 + 636 641 if (*name == '\\') { 637 642 pr_err("not allow directory name included leading slash\n"); 638 643 kfree(name);
+7
fs/smb/server/vfs.c
··· 426 426 goto out; 427 427 } 428 428 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 + 429 436 if (v_len < size) { 430 437 wbuf = kvzalloc(size, KSMBD_DEFAULT_GFP); 431 438 if (!wbuf) {
+26 -7
fs/smb/server/vfs_cache.c
··· 661 661 bool (*skip)(struct ksmbd_tree_connect *tcon, 662 662 struct ksmbd_file *fp)) 663 663 { 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 667 668 - idr_for_each_entry(ft->idr, fp, id) { 669 - if (skip(tcon, fp)) 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 + } 675 + 676 + if (skip(tcon, fp) || 677 + !atomic_dec_and_test(&fp->refcount)) { 678 + id++; 679 + write_unlock(&ft->lock); 670 680 continue; 681 + } 671 682 672 683 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); 673 687 674 - if (!atomic_dec_and_test(&fp->refcount)) 675 - continue; 688 + down_write(&fp->f_ci->m_lock); 689 + list_del_init(&fp->node); 690 + up_write(&fp->f_ci->m_lock); 691 + 676 692 __ksmbd_close_fd(ft, fp); 693 + 677 694 num++; 695 + id++; 678 696 } 697 + 679 698 return num; 680 699 } 681 700