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.18rc4-SMB-client-fixes' of git://git.samba.org/sfrench/cifs-2.6

Pull smb client fixes from Steve French:

- Fix change notify packet validation check

- Refcount fix (e.g. rename error paths)

- Fix potential UAF due to missing locks on directory lease refcount

* tag 'v6.18rc4-SMB-client-fixes' of git://git.samba.org/sfrench/cifs-2.6:
smb: client: validate change notify buffer before copy
smb: client: fix refcount leak in smb2_set_path_attr
smb: client: fix potential UAF in smb2_close_cached_fid()

+16 -9
+9 -7
fs/smb/client/cached_dir.c
··· 388 388 * lease. Release one here, and the second below. 389 389 */ 390 390 cfid->has_lease = false; 391 - kref_put(&cfid->refcount, smb2_close_cached_fid); 391 + close_cached_dir(cfid); 392 392 } 393 393 spin_unlock(&cfids->cfid_list_lock); 394 394 395 - kref_put(&cfid->refcount, smb2_close_cached_fid); 395 + close_cached_dir(cfid); 396 396 } else { 397 397 *ret_cfid = cfid; 398 398 atomic_inc(&tcon->num_remote_opens); ··· 438 438 439 439 static void 440 440 smb2_close_cached_fid(struct kref *ref) 441 + __releases(&cfid->cfids->cfid_list_lock) 441 442 { 442 443 struct cached_fid *cfid = container_of(ref, struct cached_fid, 443 444 refcount); 444 445 int rc; 445 446 446 - spin_lock(&cfid->cfids->cfid_list_lock); 447 + lockdep_assert_held(&cfid->cfids->cfid_list_lock); 448 + 447 449 if (cfid->on_list) { 448 450 list_del(&cfid->entry); 449 451 cfid->on_list = false; ··· 480 478 spin_lock(&cfid->cfids->cfid_list_lock); 481 479 if (cfid->has_lease) { 482 480 cfid->has_lease = false; 483 - kref_put(&cfid->refcount, smb2_close_cached_fid); 481 + close_cached_dir(cfid); 484 482 } 485 483 spin_unlock(&cfid->cfids->cfid_list_lock); 486 484 close_cached_dir(cfid); ··· 489 487 490 488 void close_cached_dir(struct cached_fid *cfid) 491 489 { 492 - kref_put(&cfid->refcount, smb2_close_cached_fid); 490 + kref_put_lock(&cfid->refcount, smb2_close_cached_fid, &cfid->cfids->cfid_list_lock); 493 491 } 494 492 495 493 /* ··· 598 596 599 597 WARN_ON(cfid->on_list); 600 598 601 - kref_put(&cfid->refcount, smb2_close_cached_fid); 599 + close_cached_dir(cfid); 602 600 cifs_put_tcon(tcon, netfs_trace_tcon_ref_put_cached_close); 603 601 } 604 602 ··· 764 762 * Drop the ref-count from above, either the lease-ref (if there 765 763 * was one) or the extra one acquired. 766 764 */ 767 - kref_put(&cfid->refcount, smb2_close_cached_fid); 765 + close_cached_dir(cfid); 768 766 } 769 767 queue_delayed_work(cfid_put_wq, &cfids->laundromat_work, 770 768 dir_cache_timeout * HZ);
+2
fs/smb/client/smb2inode.c
··· 1294 1294 smb2_to_name = cifs_convert_path_to_utf16(to_name, cifs_sb); 1295 1295 if (smb2_to_name == NULL) { 1296 1296 rc = -ENOMEM; 1297 + if (cfile) 1298 + cifsFileInfo_put(cfile); 1297 1299 goto smb2_rename_path; 1298 1300 } 1299 1301 in_iov.iov_base = smb2_to_name;
+5 -2
fs/smb/client/smb2pdu.c
··· 4054 4054 4055 4055 smb_rsp = (struct smb2_change_notify_rsp *)rsp_iov.iov_base; 4056 4056 4057 - smb2_validate_iov(le16_to_cpu(smb_rsp->OutputBufferOffset), 4058 - le32_to_cpu(smb_rsp->OutputBufferLength), &rsp_iov, 4057 + rc = smb2_validate_iov(le16_to_cpu(smb_rsp->OutputBufferOffset), 4058 + le32_to_cpu(smb_rsp->OutputBufferLength), 4059 + &rsp_iov, 4059 4060 sizeof(struct file_notify_information)); 4061 + if (rc) 4062 + goto cnotify_exit; 4060 4063 4061 4064 *out_data = kmemdup((char *)smb_rsp + le16_to_cpu(smb_rsp->OutputBufferOffset), 4062 4065 le32_to_cpu(smb_rsp->OutputBufferLength), GFP_KERNEL);