4 ksmbd SMB3 server fixes, most also for stable

-----BEGIN PGP SIGNATURE-----
 
 iQGzBAABCgAdFiEE6fsu8pdIjtWE/DpLiiy9cAdyT1EFAmgcFAMACgkQiiy9cAdy
 T1EIYQv9FUOa+A86sVkOunLFw0h0+F28lrHKzRvzm3hMqOzOvY79sZv1bdltgWm/
 4yy0kT+gmmrHxH4aka2oegt3pOSTjJgpJsgzDNddg/FLHP9u1p39qr++7FZjsTg1
 +rly6N1fdsfaVbxSUNXyq+VzszqPJLYfKgGRlX/8LgS0z/U1hI9h24GP0u1kfS/l
 ScKlA+Kvt59dmQ5W2exg6DMMQGP6Q79SbobpdN9AKO4cpxFDQCIIoe1hzGc8S5h3
 FjH/pVC+J/xBdVLQFFvpuNxU/uCx7YmvqdG9WeYTKxOyfmcI203eHuBwYwdi8khm
 h/UNh0R3w83WDHkAB9KdHac2LPO6agJgz1ED37fN0G7bmxVwavSRX19roCNlaoQV
 zLqSYpaHsCv2zcvKwhDJwdjtfUTncfXnzVDGSid5AEF4amOQhKBmXJUXS/BflN36
 AgowoLZ8Sg7wa1VCWHHADaga4FPVSszWetEQ3yx+YEqlzgf2R5TtqVaZe73EFPwb
 eEJKmV86
 =soic
 -----END PGP SIGNATURE-----

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
This commit is contained in:
Linus Torvalds 2025-05-08 08:22:35 -07:00
commit 80ae5fb229
4 changed files with 43 additions and 9 deletions

View File

@ -1496,7 +1496,7 @@ struct lease_ctx_info *parse_lease_state(void *open_req)
if (le16_to_cpu(cc->DataOffset) + le32_to_cpu(cc->DataLength) <
sizeof(struct create_lease_v2) - 4)
return NULL;
goto err_out;
memcpy(lreq->lease_key, lc->lcontext.LeaseKey, SMB2_LEASE_KEY_SIZE);
lreq->req_state = lc->lcontext.LeaseState;
@ -1512,7 +1512,7 @@ struct lease_ctx_info *parse_lease_state(void *open_req)
if (le16_to_cpu(cc->DataOffset) + le32_to_cpu(cc->DataLength) <
sizeof(struct create_lease))
return NULL;
goto err_out;
memcpy(lreq->lease_key, lc->lcontext.LeaseKey, SMB2_LEASE_KEY_SIZE);
lreq->req_state = lc->lcontext.LeaseState;
@ -1521,6 +1521,9 @@ struct lease_ctx_info *parse_lease_state(void *open_req)
lreq->version = 1;
}
return lreq;
err_out:
kfree(lreq);
return NULL;
}
/**

View File

@ -633,6 +633,11 @@ smb2_get_name(const char *src, const int maxlen, struct nls_table *local_nls)
return name;
}
if (*name == '\0') {
kfree(name);
return ERR_PTR(-EINVAL);
}
if (*name == '\\') {
pr_err("not allow directory name included leading slash\n");
kfree(name);

View File

@ -426,6 +426,13 @@ static int ksmbd_vfs_stream_write(struct ksmbd_file *fp, char *buf, loff_t *pos,
goto out;
}
if (v_len <= *pos) {
pr_err("stream write position %lld is out of bounds (stream length: %zd)\n",
*pos, v_len);
err = -EINVAL;
goto out;
}
if (v_len < size) {
wbuf = kvzalloc(size, KSMBD_DEFAULT_GFP);
if (!wbuf) {

View File

@ -661,21 +661,40 @@ __close_file_table_ids(struct ksmbd_file_table *ft,
bool (*skip)(struct ksmbd_tree_connect *tcon,
struct ksmbd_file *fp))
{
unsigned int id;
struct ksmbd_file *fp;
int num = 0;
struct ksmbd_file *fp;
unsigned int id = 0;
int num = 0;
idr_for_each_entry(ft->idr, fp, id) {
if (skip(tcon, fp))
while (1) {
write_lock(&ft->lock);
fp = idr_get_next(ft->idr, &id);
if (!fp) {
write_unlock(&ft->lock);
break;
}
if (skip(tcon, fp) ||
!atomic_dec_and_test(&fp->refcount)) {
id++;
write_unlock(&ft->lock);
continue;
}
set_close_state_blocked_works(fp);
idr_remove(ft->idr, fp->volatile_id);
fp->volatile_id = KSMBD_NO_FID;
write_unlock(&ft->lock);
down_write(&fp->f_ci->m_lock);
list_del_init(&fp->node);
up_write(&fp->f_ci->m_lock);
if (!atomic_dec_and_test(&fp->refcount))
continue;
__ksmbd_close_fd(ft, fp);
num++;
id++;
}
return num;
}