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 'v7.0-rc2-smb3-client-fixes' of git://git.samba.org/sfrench/cifs-2.6

Pull smb client fixes from Steve French:

- Fix potential oops on open failure

- Fix unmount to better free deferred closes

- Use proper constant-time MAC comparison function

- Two buffer allocation size fixes

- Two minor cleanups

- make SMB2 kunit tests a distinct module

* tag 'v7.0-rc2-smb3-client-fixes' of git://git.samba.org/sfrench/cifs-2.6:
smb: client: fix oops due to uninitialised var in smb2_unlink()
cifs: open files should not hold ref on superblock
smb: client: Compare MACs in constant time
smb/client: remove unused SMB311_posix_query_info()
smb/client: fix buffer size for smb311_posix_qinfo in SMB311_posix_query_info()
smb/client: fix buffer size for smb311_posix_qinfo in smb2_compound_op()
smb: update some doc references
smb/client: make SMB2 maperror KUnit tests a separate module

+107 -58
+2
fs/smb/client/Makefile
··· 56 56 quiet_cmd_gen_smb2_mapping = GEN $@ 57 57 cmd_gen_smb2_mapping = perl $(src)/gen_smb2_mapping $< $@ 58 58 59 + obj-$(CONFIG_SMB_KUNIT_TESTS) += smb2maperror_test.o 60 + 59 61 clean-files += smb2_mapping_table.c
+5 -2
fs/smb/client/cifsfs.c
··· 332 332 333 333 /* 334 334 * We need to release all dentries for the cached directories 335 - * before we kill the sb. 335 + * and close all deferred file handles before we kill the sb. 336 336 */ 337 337 if (cifs_sb->root) { 338 338 close_all_cached_dirs(cifs_sb); 339 + cifs_close_all_deferred_files_sb(cifs_sb); 340 + 341 + /* Wait for all pending oplock breaks to complete */ 342 + flush_workqueue(cifsoplockd_wq); 339 343 340 344 /* finally release root dentry */ 341 345 dput(cifs_sb->root); ··· 872 868 spin_unlock(&tcon->tc_lock); 873 869 spin_unlock(&cifs_tcp_ses_lock); 874 870 875 - cifs_close_all_deferred_files(tcon); 876 871 /* cancel_brl_requests(tcon); */ /* BB mark all brl mids as exiting */ 877 872 /* cancel_notify_requests(tcon); */ 878 873 if (tcon->ses && tcon->ses->server) {
+1
fs/smb/client/cifsproto.h
··· 261 261 262 262 void cifs_close_all_deferred_files(struct cifs_tcon *tcon); 263 263 264 + void cifs_close_all_deferred_files_sb(struct cifs_sb_info *cifs_sb); 264 265 void cifs_close_deferred_file_under_dentry(struct cifs_tcon *tcon, 265 266 struct dentry *dentry); 266 267
-11
fs/smb/client/file.c
··· 711 711 mutex_init(&cfile->fh_mutex); 712 712 spin_lock_init(&cfile->file_info_lock); 713 713 714 - cifs_sb_active(inode->i_sb); 715 - 716 714 /* 717 715 * If the server returned a read oplock and we have mandatory brlocks, 718 716 * set oplock level to None. ··· 765 767 struct inode *inode = d_inode(cifs_file->dentry); 766 768 struct cifsInodeInfo *cifsi = CIFS_I(inode); 767 769 struct cifsLockInfo *li, *tmp; 768 - struct super_block *sb = inode->i_sb; 769 770 770 771 /* 771 772 * Delete any outstanding lock records. We'll lose them when the file ··· 782 785 783 786 cifs_put_tlink(cifs_file->tlink); 784 787 dput(cifs_file->dentry); 785 - cifs_sb_deactive(sb); 786 788 kfree(cifs_file->symlink_target); 787 789 kfree(cifs_file); 788 790 } ··· 3159 3163 __u64 persistent_fid, volatile_fid; 3160 3164 __u16 net_fid; 3161 3165 3162 - /* 3163 - * Hold a reference to the superblock to prevent it and its inodes from 3164 - * being freed while we are accessing cinode. Otherwise, _cifsFileInfo_put() 3165 - * may release the last reference to the sb and trigger inode eviction. 3166 - */ 3167 - cifs_sb_active(sb); 3168 3166 wait_on_bit(&cinode->flags, CIFS_INODE_PENDING_WRITERS, 3169 3167 TASK_UNINTERRUPTIBLE); 3170 3168 ··· 3243 3253 cifs_put_tlink(tlink); 3244 3254 out: 3245 3255 cifs_done_oplock_break(cinode); 3246 - cifs_sb_deactive(sb); 3247 3256 } 3248 3257 3249 3258 static int cifs_swap_activate(struct swap_info_struct *sis,
+42
fs/smb/client/misc.c
··· 28 28 #include "fs_context.h" 29 29 #include "cached_dir.h" 30 30 31 + struct tcon_list { 32 + struct list_head entry; 33 + struct cifs_tcon *tcon; 34 + }; 35 + 31 36 /* The xid serves as a useful identifier for each incoming vfs request, 32 37 in a similar way to the mid which is useful to track each sent smb, 33 38 and CurrentXid can also provide a running counter (although it ··· 555 550 list_for_each_entry_safe(tmp_list, tmp_next_list, &file_head, list) { 556 551 _cifsFileInfo_put(tmp_list->cfile, true, false); 557 552 list_del(&tmp_list->list); 553 + kfree(tmp_list); 554 + } 555 + } 556 + 557 + void cifs_close_all_deferred_files_sb(struct cifs_sb_info *cifs_sb) 558 + { 559 + struct rb_root *root = &cifs_sb->tlink_tree; 560 + struct rb_node *node; 561 + struct cifs_tcon *tcon; 562 + struct tcon_link *tlink; 563 + struct tcon_list *tmp_list, *q; 564 + LIST_HEAD(tcon_head); 565 + 566 + spin_lock(&cifs_sb->tlink_tree_lock); 567 + for (node = rb_first(root); node; node = rb_next(node)) { 568 + tlink = rb_entry(node, struct tcon_link, tl_rbnode); 569 + tcon = tlink_tcon(tlink); 570 + if (IS_ERR(tcon)) 571 + continue; 572 + tmp_list = kmalloc_obj(struct tcon_list, GFP_ATOMIC); 573 + if (tmp_list == NULL) 574 + break; 575 + tmp_list->tcon = tcon; 576 + /* Take a reference on tcon to prevent it from being freed */ 577 + spin_lock(&tcon->tc_lock); 578 + ++tcon->tc_count; 579 + trace_smb3_tcon_ref(tcon->debug_id, tcon->tc_count, 580 + netfs_trace_tcon_ref_get_close_defer_files); 581 + spin_unlock(&tcon->tc_lock); 582 + list_add_tail(&tmp_list->entry, &tcon_head); 583 + } 584 + spin_unlock(&cifs_sb->tlink_tree_lock); 585 + 586 + list_for_each_entry_safe(tmp_list, q, &tcon_head, entry) { 587 + cifs_close_all_deferred_files(tmp_list->tcon); 588 + list_del(&tmp_list->entry); 589 + cifs_put_tcon(tmp_list->tcon, netfs_trace_tcon_ref_put_close_defer_files); 558 590 kfree(tmp_list); 559 591 } 560 592 }
+2 -1
fs/smb/client/smb1encrypt.c
··· 11 11 12 12 #include <linux/fips.h> 13 13 #include <crypto/md5.h> 14 + #include <crypto/utils.h> 14 15 #include "cifsproto.h" 15 16 #include "smb1proto.h" 16 17 #include "cifs_debug.h" ··· 132 131 /* cifs_dump_mem("what we think it should be: ", 133 132 what_we_think_sig_should_be, 16); */ 134 133 135 - if (memcmp(server_response_sig, what_we_think_sig_should_be, 8)) 134 + if (crypto_memneq(server_response_sig, what_we_think_sig_should_be, 8)) 136 135 return -EACCES; 137 136 else 138 137 return 0;
+12
fs/smb/client/smb2glob.h
··· 46 46 #define END_OF_CHAIN 4 47 47 #define RELATED_REQUEST 8 48 48 49 + /* 50 + ***************************************************************** 51 + * Struct definitions go here 52 + ***************************************************************** 53 + */ 54 + 55 + struct status_to_posix_error { 56 + __u32 smb2_status; 57 + int posix_error; 58 + char *status_string; 59 + }; 60 + 49 61 #endif /* _SMB2_GLOB_H */
+5 -3
fs/smb/client/smb2inode.c
··· 325 325 cfile->fid.volatile_fid, 326 326 SMB_FIND_FILE_POSIX_INFO, 327 327 SMB2_O_INFO_FILE, 0, 328 - sizeof(struct smb311_posix_qinfo *) + 328 + sizeof(struct smb311_posix_qinfo) + 329 329 (PATH_MAX * 2) + 330 330 (sizeof(struct smb_sid) * 2), 0, NULL); 331 331 } else { ··· 335 335 COMPOUND_FID, 336 336 SMB_FIND_FILE_POSIX_INFO, 337 337 SMB2_O_INFO_FILE, 0, 338 - sizeof(struct smb311_posix_qinfo *) + 338 + sizeof(struct smb311_posix_qinfo) + 339 339 (PATH_MAX * 2) + 340 340 (sizeof(struct smb_sid) * 2), 0, NULL); 341 341 } ··· 1216 1216 memset(resp_buftype, 0, sizeof(resp_buftype)); 1217 1217 memset(rsp_iov, 0, sizeof(rsp_iov)); 1218 1218 1219 + memset(open_iov, 0, sizeof(open_iov)); 1219 1220 rqst[0].rq_iov = open_iov; 1220 1221 rqst[0].rq_nvec = ARRAY_SIZE(open_iov); 1221 1222 ··· 1241 1240 creq = rqst[0].rq_iov[0].iov_base; 1242 1241 creq->ShareAccess = FILE_SHARE_DELETE_LE; 1243 1242 1243 + memset(&close_iov, 0, sizeof(close_iov)); 1244 1244 rqst[1].rq_iov = &close_iov; 1245 1245 rqst[1].rq_nvec = 1; 1246 1246 1247 1247 rc = SMB2_close_init(tcon, server, &rqst[1], 1248 1248 COMPOUND_FID, COMPOUND_FID, false); 1249 - smb2_set_related(&rqst[1]); 1250 1249 if (rc) 1251 1250 goto err_free; 1251 + smb2_set_related(&rqst[1]); 1252 1252 1253 1253 if (retries) { 1254 1254 /* Back-off before retry */
+15 -13
fs/smb/client/smb2maperror.c
··· 8 8 * 9 9 */ 10 10 #include <linux/errno.h> 11 - #include "cifsglob.h" 12 11 #include "cifsproto.h" 13 12 #include "cifs_debug.h" 14 13 #include "smb2proto.h" 15 14 #include "smb2glob.h" 16 15 #include "../common/smb2status.h" 17 16 #include "trace.h" 18 - 19 - struct status_to_posix_error { 20 - __u32 smb2_status; 21 - int posix_error; 22 - char *status_string; 23 - }; 24 17 25 18 static const struct status_to_posix_error smb2_error_map_table[] = { 26 19 /* ··· 108 115 return 0; 109 116 } 110 117 111 - #define SMB_CLIENT_KUNIT_AVAILABLE \ 112 - ((IS_MODULE(CONFIG_CIFS) && IS_ENABLED(CONFIG_KUNIT)) || \ 113 - (IS_BUILTIN(CONFIG_CIFS) && IS_BUILTIN(CONFIG_KUNIT))) 118 + #if IS_ENABLED(CONFIG_SMB_KUNIT_TESTS) 119 + /* Previous prototype for eliminating the build warning. */ 120 + const struct status_to_posix_error *smb2_get_err_map_test(__u32 smb2_status); 114 121 115 - #if SMB_CLIENT_KUNIT_AVAILABLE && IS_ENABLED(CONFIG_SMB_KUNIT_TESTS) 116 - #include "smb2maperror_test.c" 117 - #endif /* CONFIG_SMB_KUNIT_TESTS */ 122 + const struct status_to_posix_error *smb2_get_err_map_test(__u32 smb2_status) 123 + { 124 + return smb2_get_err_map(smb2_status); 125 + } 126 + EXPORT_SYMBOL_GPL(smb2_get_err_map_test); 127 + 128 + const struct status_to_posix_error *smb2_error_map_table_test = smb2_error_map_table; 129 + EXPORT_SYMBOL_GPL(smb2_error_map_table_test); 130 + 131 + unsigned int smb2_error_map_num = ARRAY_SIZE(smb2_error_map_table); 132 + EXPORT_SYMBOL_GPL(smb2_error_map_num); 133 + #endif
+9 -3
fs/smb/client/smb2maperror_test.c
··· 9 9 */ 10 10 11 11 #include <kunit/test.h> 12 + #include "smb2glob.h" 13 + 14 + const struct status_to_posix_error *smb2_get_err_map_test(__u32 smb2_status); 15 + extern const struct status_to_posix_error *smb2_error_map_table_test; 16 + extern unsigned int smb2_error_map_num; 12 17 13 18 static void 14 19 test_cmp_map(struct kunit *test, const struct status_to_posix_error *expect) 15 20 { 16 21 const struct status_to_posix_error *result; 17 22 18 - result = smb2_get_err_map(expect->smb2_status); 23 + result = smb2_get_err_map_test(expect->smb2_status); 19 24 KUNIT_EXPECT_PTR_NE(test, NULL, result); 20 25 KUNIT_EXPECT_EQ(test, expect->smb2_status, result->smb2_status); 21 26 KUNIT_EXPECT_EQ(test, expect->posix_error, result->posix_error); ··· 31 26 { 32 27 unsigned int i; 33 28 34 - for (i = 0; i < ARRAY_SIZE(smb2_error_map_table); i++) 35 - test_cmp_map(test, &smb2_error_map_table[i]); 29 + for (i = 0; i < smb2_error_map_num; i++) 30 + test_cmp_map(test, &smb2_error_map_table_test[i]); 36 31 } 37 32 38 33 static struct kunit_case maperror_test_cases[] = { ··· 48 43 kunit_test_suite(maperror_suite); 49 44 50 45 MODULE_LICENSE("GPL"); 46 + MODULE_DESCRIPTION("KUnit tests of SMB2 maperror");
-18
fs/smb/client/smb2pdu.c
··· 3989 3989 NULL); 3990 3990 } 3991 3991 3992 - #if 0 3993 - /* currently unused, as now we are doing compounding instead (see smb311_posix_query_path_info) */ 3994 - int 3995 - SMB311_posix_query_info(const unsigned int xid, struct cifs_tcon *tcon, 3996 - u64 persistent_fid, u64 volatile_fid, 3997 - struct smb311_posix_qinfo *data, u32 *plen) 3998 - { 3999 - size_t output_len = sizeof(struct smb311_posix_qinfo *) + 4000 - (sizeof(struct smb_sid) * 2) + (PATH_MAX * 2); 4001 - *plen = 0; 4002 - 4003 - return query_info(xid, tcon, persistent_fid, volatile_fid, 4004 - SMB_FIND_FILE_POSIX_INFO, SMB2_O_INFO_FILE, 0, 4005 - output_len, sizeof(struct smb311_posix_qinfo), (void **)&data, plen); 4006 - /* Note caller must free "data" (passed in above). It may be allocated in query_info call */ 4007 - } 4008 - #endif 4009 - 4010 3992 int 4011 3993 SMB2_query_acl(const unsigned int xid, struct cifs_tcon *tcon, 4012 3994 u64 persistent_fid, u64 volatile_fid,
+5 -2
fs/smb/client/smb2pdu.h
··· 224 224 __le32 Tag; 225 225 } __packed; 226 226 227 - /* See MS-FSCC 2.4.21 */ 227 + /* See MS-FSCC 2.4.26 */ 228 228 struct smb2_file_id_information { 229 229 __le64 VolumeSerialNumber; 230 230 __u64 PersistentFileId; /* opaque endianness */ ··· 251 251 252 252 extern char smb2_padding[7]; 253 253 254 - /* equivalent of the contents of SMB3.1.1 POSIX open context response */ 254 + /* 255 + * See POSIX-SMB2 2.2.14.2.16 256 + * Link: https://gitlab.com/samba-team/smb3-posix-spec/-/blob/master/smb3_posix_extensions.md 257 + */ 255 258 struct create_posix_rsp { 256 259 u32 nlink; 257 260 u32 reparse_tag;
-3
fs/smb/client/smb2proto.h
··· 167 167 struct cifs_tcon *tcon, struct TCP_Server_Info *server, 168 168 u64 persistent_fid, u64 volatile_fid); 169 169 void SMB2_flush_free(struct smb_rqst *rqst); 170 - int SMB311_posix_query_info(const unsigned int xid, struct cifs_tcon *tcon, 171 - u64 persistent_fid, u64 volatile_fid, 172 - struct smb311_posix_qinfo *data, u32 *plen); 173 170 int SMB2_query_info(const unsigned int xid, struct cifs_tcon *tcon, 174 171 u64 persistent_fid, u64 volatile_fid, 175 172 struct smb2_file_all_info *data);
+3 -1
fs/smb/client/smb2transport.c
··· 20 20 #include <linux/highmem.h> 21 21 #include <crypto/aead.h> 22 22 #include <crypto/sha2.h> 23 + #include <crypto/utils.h> 23 24 #include "cifsglob.h" 24 25 #include "cifsproto.h" 25 26 #include "smb2proto.h" ··· 618 617 if (rc) 619 618 return rc; 620 619 621 - if (memcmp(server_response_sig, shdr->Signature, SMB2_SIGNATURE_SIZE)) { 620 + if (crypto_memneq(server_response_sig, shdr->Signature, 621 + SMB2_SIGNATURE_SIZE)) { 622 622 cifs_dbg(VFS, "sign fail cmd 0x%x message id 0x%llx\n", 623 623 shdr->Command, shdr->MessageId); 624 624 return -EACCES;
+2
fs/smb/client/trace.h
··· 176 176 EM(netfs_trace_tcon_ref_get_cached_laundromat, "GET Ch-Lau") \ 177 177 EM(netfs_trace_tcon_ref_get_cached_lease_break, "GET Ch-Lea") \ 178 178 EM(netfs_trace_tcon_ref_get_cancelled_close, "GET Cn-Cls") \ 179 + EM(netfs_trace_tcon_ref_get_close_defer_files, "GET Cl-Def") \ 179 180 EM(netfs_trace_tcon_ref_get_dfs_refer, "GET DfsRef") \ 180 181 EM(netfs_trace_tcon_ref_get_find, "GET Find ") \ 181 182 EM(netfs_trace_tcon_ref_get_find_sess_tcon, "GET FndSes") \ ··· 188 187 EM(netfs_trace_tcon_ref_put_cancelled_close, "PUT Cn-Cls") \ 189 188 EM(netfs_trace_tcon_ref_put_cancelled_close_fid, "PUT Cn-Fid") \ 190 189 EM(netfs_trace_tcon_ref_put_cancelled_mid, "PUT Cn-Mid") \ 190 + EM(netfs_trace_tcon_ref_put_close_defer_files, "PUT Cl-Def") \ 191 191 EM(netfs_trace_tcon_ref_put_mnt_ctx, "PUT MntCtx") \ 192 192 EM(netfs_trace_tcon_ref_put_dfs_refer, "PUT DfsRfr") \ 193 193 EM(netfs_trace_tcon_ref_put_reconnect_server, "PUT Reconn") \
+4 -1
fs/smb/server/smb2pdu.h
··· 83 83 } Data; 84 84 } __packed; 85 85 86 - /* equivalent of the contents of SMB3.1.1 POSIX open context response */ 86 + /* 87 + * See POSIX-SMB2 2.2.14.2.16 88 + * Link: https://gitlab.com/samba-team/smb3-posix-spec/-/blob/master/smb3_posix_extensions.md 89 + */ 87 90 struct create_posix_rsp { 88 91 struct create_context_hdr ccontext; 89 92 __u8 Name[16];