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 '6.1-rc1-smb3-fixes' of git://git.samba.org/sfrench/cifs-2.6

Pull cifs fixes from Steve French:

- memory leak fixes

- fixes for directory leases, including an important one which fixes a
problem noticed by git functional tests

- fixes relating to missing free_xid calls (helpful for
tracing/debugging of entry/exit into cifs.ko)

- a multichannel fix

- a small cleanup fix (use of list_move instead of list_del/list_add)

* tag '6.1-rc1-smb3-fixes' of git://git.samba.org/sfrench/cifs-2.6:
cifs: update internal module number
cifs: fix memory leaks in session setup
cifs: drop the lease for cached directories on rmdir or rename
smb3: interface count displayed incorrectly
cifs: Fix memory leak when build ntlmssp negotiate blob failed
cifs: set rc to -ENOENT if we can not get a dentry for the cached dir
cifs: use LIST_HEAD() and list_move() to simplify code
cifs: Fix xid leak in cifs_get_file_info_unix()
cifs: Fix xid leak in cifs_ses_add_channel()
cifs: Fix xid leak in cifs_flock()
cifs: Fix xid leak in cifs_copy_file_range()
cifs: Fix xid leak in cifs_create()

+68 -32
+29 -10
fs/cifs/cached_dir.c
··· 253 253 dentry = dget(cifs_sb->root); 254 254 else { 255 255 dentry = path_to_dentry(cifs_sb, path); 256 - if (IS_ERR(dentry)) 256 + if (IS_ERR(dentry)) { 257 + rc = -ENOENT; 257 258 goto oshr_free; 259 + } 258 260 } 259 261 cfid->dentry = dentry; 260 262 cfid->tcon = tcon; ··· 340 338 free_cached_dir(cfid); 341 339 } 342 340 341 + void drop_cached_dir_by_name(const unsigned int xid, struct cifs_tcon *tcon, 342 + const char *name, struct cifs_sb_info *cifs_sb) 343 + { 344 + struct cached_fid *cfid = NULL; 345 + int rc; 346 + 347 + rc = open_cached_dir(xid, tcon, name, cifs_sb, true, &cfid); 348 + if (rc) { 349 + cifs_dbg(FYI, "no cached dir found for rmdir(%s)\n", name); 350 + return; 351 + } 352 + spin_lock(&cfid->cfids->cfid_list_lock); 353 + if (cfid->has_lease) { 354 + cfid->has_lease = false; 355 + kref_put(&cfid->refcount, smb2_close_cached_fid); 356 + } 357 + spin_unlock(&cfid->cfids->cfid_list_lock); 358 + close_cached_dir(cfid); 359 + } 360 + 361 + 343 362 void close_cached_dir(struct cached_fid *cfid) 344 363 { 345 364 kref_put(&cfid->refcount, smb2_close_cached_fid); ··· 401 378 { 402 379 struct cached_fids *cfids = tcon->cfids; 403 380 struct cached_fid *cfid, *q; 404 - struct list_head entry; 381 + LIST_HEAD(entry); 405 382 406 - INIT_LIST_HEAD(&entry); 407 383 spin_lock(&cfids->cfid_list_lock); 408 384 list_for_each_entry_safe(cfid, q, &cfids->entries, entry) { 409 - list_del(&cfid->entry); 410 - list_add(&cfid->entry, &entry); 385 + list_move(&cfid->entry, &entry); 411 386 cfids->num_entries--; 412 387 cfid->is_open = false; 388 + cfid->on_list = false; 413 389 /* To prevent race with smb2_cached_lease_break() */ 414 390 kref_get(&cfid->refcount); 415 391 } 416 392 spin_unlock(&cfids->cfid_list_lock); 417 393 418 394 list_for_each_entry_safe(cfid, q, &entry, entry) { 419 - cfid->on_list = false; 420 395 list_del(&cfid->entry); 421 396 cancel_work_sync(&cfid->lease_break); 422 397 if (cfid->has_lease) { ··· 539 518 void free_cached_dirs(struct cached_fids *cfids) 540 519 { 541 520 struct cached_fid *cfid, *q; 542 - struct list_head entry; 521 + LIST_HEAD(entry); 543 522 544 - INIT_LIST_HEAD(&entry); 545 523 spin_lock(&cfids->cfid_list_lock); 546 524 list_for_each_entry_safe(cfid, q, &cfids->entries, entry) { 547 525 cfid->on_list = false; 548 526 cfid->is_open = false; 549 - list_del(&cfid->entry); 550 - list_add(&cfid->entry, &entry); 527 + list_move(&cfid->entry, &entry); 551 528 } 552 529 spin_unlock(&cfids->cfid_list_lock); 553 530
+4
fs/cifs/cached_dir.h
··· 69 69 struct dentry *dentry, 70 70 struct cached_fid **cfid); 71 71 extern void close_cached_dir(struct cached_fid *cfid); 72 + extern void drop_cached_dir_by_name(const unsigned int xid, 73 + struct cifs_tcon *tcon, 74 + const char *name, 75 + struct cifs_sb_info *cifs_sb); 72 76 extern void close_all_cached_dirs(struct cifs_sb_info *cifs_sb); 73 77 extern void invalidate_all_cached_dirs(struct cifs_tcon *tcon); 74 78 extern int cached_dir_lease_break(struct cifs_tcon *tcon, __u8 lease_key[16]);
+5 -2
fs/cifs/cifsfs.c
··· 1302 1302 ssize_t rc; 1303 1303 struct cifsFileInfo *cfile = dst_file->private_data; 1304 1304 1305 - if (cfile->swapfile) 1306 - return -EOPNOTSUPP; 1305 + if (cfile->swapfile) { 1306 + rc = -EOPNOTSUPP; 1307 + free_xid(xid); 1308 + return rc; 1309 + } 1307 1310 1308 1311 rc = cifs_file_copychunk_range(xid, src_file, off, dst_file, destoff, 1309 1312 len, flags);
+2 -2
fs/cifs/cifsfs.h
··· 153 153 #endif /* CONFIG_CIFS_NFSD_EXPORT */ 154 154 155 155 /* when changing internal version - update following two lines at same time */ 156 - #define SMB3_PRODUCT_BUILD 39 157 - #define CIFS_VERSION "2.39" 156 + #define SMB3_PRODUCT_BUILD 40 157 + #define CIFS_VERSION "2.40" 158 158 #endif /* _CIFSFS_H */
+4 -2
fs/cifs/dir.c
··· 543 543 cifs_dbg(FYI, "cifs_create parent inode = 0x%p name is: %pd and dentry = 0x%p\n", 544 544 inode, direntry, direntry); 545 545 546 - if (unlikely(cifs_forced_shutdown(CIFS_SB(inode->i_sb)))) 547 - return -EIO; 546 + if (unlikely(cifs_forced_shutdown(CIFS_SB(inode->i_sb)))) { 547 + rc = -EIO; 548 + goto out_free_xid; 549 + } 548 550 549 551 tlink = cifs_sb_tlink(CIFS_SB(inode->i_sb)); 550 552 rc = PTR_ERR(tlink);
+7 -4
fs/cifs/file.c
··· 1885 1885 struct cifsFileInfo *cfile; 1886 1886 __u32 type; 1887 1887 1888 - rc = -EACCES; 1889 1888 xid = get_xid(); 1890 1889 1891 - if (!(fl->fl_flags & FL_FLOCK)) 1892 - return -ENOLCK; 1890 + if (!(fl->fl_flags & FL_FLOCK)) { 1891 + rc = -ENOLCK; 1892 + free_xid(xid); 1893 + return rc; 1894 + } 1893 1895 1894 1896 cfile = (struct cifsFileInfo *)file->private_data; 1895 1897 tcon = tlink_tcon(cfile->tlink); ··· 1910 1908 * if no lock or unlock then nothing to do since we do not 1911 1909 * know what it is 1912 1910 */ 1911 + rc = -EOPNOTSUPP; 1913 1912 free_xid(xid); 1914 - return -EOPNOTSUPP; 1913 + return rc; 1915 1914 } 1916 1915 1917 1916 rc = cifs_setlk(file, fl, type, wait_flag, posix_lck, lock, unlock,
+4 -2
fs/cifs/inode.c
··· 368 368 369 369 if (cfile->symlink_target) { 370 370 fattr.cf_symlink_target = kstrdup(cfile->symlink_target, GFP_KERNEL); 371 - if (!fattr.cf_symlink_target) 372 - return -ENOMEM; 371 + if (!fattr.cf_symlink_target) { 372 + rc = -ENOMEM; 373 + goto cifs_gfiunix_out; 374 + } 373 375 } 374 376 375 377 rc = CIFSSMBUnixQFileInfo(xid, tcon, cfile->fid.netfid, &find_data);
+1
fs/cifs/sess.c
··· 496 496 cifs_put_tcp_session(chan->server, 0); 497 497 } 498 498 499 + free_xid(xid); 499 500 return rc; 500 501 } 501 502
+2
fs/cifs/smb2inode.c
··· 655 655 smb2_rmdir(const unsigned int xid, struct cifs_tcon *tcon, const char *name, 656 656 struct cifs_sb_info *cifs_sb) 657 657 { 658 + drop_cached_dir_by_name(xid, tcon, name, cifs_sb); 658 659 return smb2_compound_op(xid, tcon, cifs_sb, name, DELETE, FILE_OPEN, 659 660 CREATE_NOT_FILE, ACL_NO_MODE, 660 661 NULL, SMB2_OP_RMDIR, NULL, NULL, NULL); ··· 699 698 { 700 699 struct cifsFileInfo *cfile; 701 700 701 + drop_cached_dir_by_name(xid, tcon, from_name, cifs_sb); 702 702 cifs_get_writable_path(tcon, from_name, FIND_WR_WITH_DELETE, &cfile); 703 703 704 704 return smb2_set_path_attr(xid, tcon, from_name, to_name,
+2 -1
fs/cifs/smb2ops.c
··· 530 530 p = buf; 531 531 532 532 spin_lock(&ses->iface_lock); 533 + ses->iface_count = 0; 533 534 /* 534 535 * Go through iface_list and do kref_put to remove 535 536 * any unused ifaces. ifaces in use will be removed ··· 652 651 kref_put(&iface->refcount, release_iface); 653 652 } else 654 653 list_add_tail(&info->iface_head, &ses->iface_list); 655 - spin_unlock(&ses->iface_lock); 656 654 657 655 ses->iface_count++; 656 + spin_unlock(&ses->iface_lock); 658 657 ses->iface_last_update = jiffies; 659 658 next_iface: 660 659 nb_iface++;
+8 -9
fs/cifs/smb2pdu.c
··· 1341 1341 static void 1342 1342 SMB2_sess_free_buffer(struct SMB2_sess_data *sess_data) 1343 1343 { 1344 - int i; 1344 + struct kvec *iov = sess_data->iov; 1345 1345 1346 - /* zero the session data before freeing, as it might contain sensitive info (keys, etc) */ 1347 - for (i = 0; i < 2; i++) 1348 - if (sess_data->iov[i].iov_base) 1349 - memzero_explicit(sess_data->iov[i].iov_base, sess_data->iov[i].iov_len); 1346 + /* iov[1] is already freed by caller */ 1347 + if (sess_data->buf0_type != CIFS_NO_BUFFER && iov[0].iov_base) 1348 + memzero_explicit(iov[0].iov_base, iov[0].iov_len); 1350 1349 1351 - free_rsp_buf(sess_data->buf0_type, sess_data->iov[0].iov_base); 1350 + free_rsp_buf(sess_data->buf0_type, iov[0].iov_base); 1352 1351 sess_data->buf0_type = CIFS_NO_BUFFER; 1353 1352 } 1354 1353 ··· 1530 1531 &blob_length, ses, server, 1531 1532 sess_data->nls_cp); 1532 1533 if (rc) 1533 - goto out_err; 1534 + goto out; 1534 1535 1535 1536 if (use_spnego) { 1536 1537 /* BB eventually need to add this */ ··· 1577 1578 } 1578 1579 1579 1580 out: 1580 - memzero_explicit(ntlmssp_blob, blob_length); 1581 + kfree_sensitive(ntlmssp_blob); 1581 1582 SMB2_sess_free_buffer(sess_data); 1582 1583 if (!rc) { 1583 1584 sess_data->result = 0; ··· 1661 1662 } 1662 1663 #endif 1663 1664 out: 1664 - memzero_explicit(ntlmssp_blob, blob_length); 1665 + kfree_sensitive(ntlmssp_blob); 1665 1666 SMB2_sess_free_buffer(sess_data); 1666 1667 kfree_sensitive(ses->ntlmssp); 1667 1668 ses->ntlmssp = NULL;