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 '5.17-rc3-ksmbd-server-fixes' of git://git.samba.org/ksmbd

Pull ksmbd server fixes from Steve French:

- NTLMSSP authentication improvement

- RDMA (smbdirect) fix allowing broader set of NICs to be supported

- improved buffer validation

- additional small fixes, including a posix extensions fix for stable

* tag '5.17-rc3-ksmbd-server-fixes' of git://git.samba.org/ksmbd:
ksmbd: add support for key exchange
ksmbd: reduce smb direct max read/write size
ksmbd: don't align last entry offset in smb2 query directory
ksmbd: fix same UniqueId for dot and dotdot entries
ksmbd: smbd: validate buffer descriptor structures
ksmbd: fix SMB 3.11 posix extension mount failure

+70 -14
+2 -2
fs/Kconfig
··· 369 369 370 370 config SMBFS_COMMON 371 371 tristate 372 - default y if CIFS=y 373 - default m if CIFS=m 372 + default y if CIFS=y || SMB_SERVER=y 373 + default m if CIFS=m || SMB_SERVER=m 374 374 375 375 source "fs/coda/Kconfig" 376 376 source "fs/afs/Kconfig"
+27
fs/ksmbd/auth.c
··· 29 29 #include "mgmt/user_config.h" 30 30 #include "crypto_ctx.h" 31 31 #include "transport_ipc.h" 32 + #include "../smbfs_common/arc4.h" 32 33 33 34 /* 34 35 * Fixed format data defining GSS header and fixed string ··· 337 336 nt_len - CIFS_ENCPWD_SIZE, 338 337 domain_name, conn->ntlmssp.cryptkey); 339 338 kfree(domain_name); 339 + 340 + /* The recovered secondary session key */ 341 + if (conn->ntlmssp.client_flags & NTLMSSP_NEGOTIATE_KEY_XCH) { 342 + struct arc4_ctx *ctx_arc4; 343 + unsigned int sess_key_off, sess_key_len; 344 + 345 + sess_key_off = le32_to_cpu(authblob->SessionKey.BufferOffset); 346 + sess_key_len = le16_to_cpu(authblob->SessionKey.Length); 347 + 348 + if (blob_len < (u64)sess_key_off + sess_key_len) 349 + return -EINVAL; 350 + 351 + ctx_arc4 = kmalloc(sizeof(*ctx_arc4), GFP_KERNEL); 352 + if (!ctx_arc4) 353 + return -ENOMEM; 354 + 355 + cifs_arc4_setkey(ctx_arc4, sess->sess_key, 356 + SMB2_NTLMV2_SESSKEY_SIZE); 357 + cifs_arc4_crypt(ctx_arc4, sess->sess_key, 358 + (char *)authblob + sess_key_off, sess_key_len); 359 + kfree_sensitive(ctx_arc4); 360 + } 361 + 340 362 return ret; 341 363 } 342 364 ··· 431 407 if (conn->use_spnego && 432 408 (cflags & NTLMSSP_NEGOTIATE_EXTENDED_SEC)) 433 409 flags |= NTLMSSP_NEGOTIATE_EXTENDED_SEC; 410 + 411 + if (cflags & NTLMSSP_NEGOTIATE_KEY_XCH) 412 + flags |= NTLMSSP_NEGOTIATE_KEY_XCH; 434 413 435 414 chgblob->NegotiateFlags = cpu_to_le32(flags); 436 415 len = strlen(ksmbd_netbios_name());
+35 -10
fs/ksmbd/smb2pdu.c
··· 2688 2688 (struct create_posix *)context; 2689 2689 if (le16_to_cpu(context->DataOffset) + 2690 2690 le32_to_cpu(context->DataLength) < 2691 - sizeof(struct create_posix)) { 2691 + sizeof(struct create_posix) - 4) { 2692 2692 rc = -EINVAL; 2693 2693 goto err_out1; 2694 2694 } ··· 3422 3422 goto free_conv_name; 3423 3423 } 3424 3424 3425 - struct_sz = readdir_info_level_struct_sz(info_level); 3426 - next_entry_offset = ALIGN(struct_sz - 1 + conv_len, 3427 - KSMBD_DIR_INFO_ALIGNMENT); 3425 + struct_sz = readdir_info_level_struct_sz(info_level) - 1 + conv_len; 3426 + next_entry_offset = ALIGN(struct_sz, KSMBD_DIR_INFO_ALIGNMENT); 3427 + d_info->last_entry_off_align = next_entry_offset - struct_sz; 3428 3428 3429 3429 if (next_entry_offset > d_info->out_buf_len) { 3430 3430 d_info->out_buf_len = 0; ··· 3976 3976 ((struct file_directory_info *) 3977 3977 ((char *)rsp->Buffer + d_info.last_entry_offset)) 3978 3978 ->NextEntryOffset = 0; 3979 + d_info.data_count -= d_info.last_entry_off_align; 3979 3980 3980 3981 rsp->StructureSize = cpu_to_le16(9); 3981 3982 rsp->OutputBufferOffset = cpu_to_le16(72); ··· 6127 6126 __le16 ChannelInfoOffset, 6128 6127 __le16 ChannelInfoLength) 6129 6128 { 6129 + unsigned int i, ch_count; 6130 + 6130 6131 if (work->conn->dialect == SMB30_PROT_ID && 6131 6132 Channel != SMB2_CHANNEL_RDMA_V1) 6132 6133 return -EINVAL; 6133 6134 6134 - if (ChannelInfoOffset == 0 || 6135 - le16_to_cpu(ChannelInfoLength) < sizeof(*desc)) 6135 + ch_count = le16_to_cpu(ChannelInfoLength) / sizeof(*desc); 6136 + if (ksmbd_debug_types & KSMBD_DEBUG_RDMA) { 6137 + for (i = 0; i < ch_count; i++) { 6138 + pr_info("RDMA r/w request %#x: token %#x, length %#x\n", 6139 + i, 6140 + le32_to_cpu(desc[i].token), 6141 + le32_to_cpu(desc[i].length)); 6142 + } 6143 + } 6144 + if (ch_count != 1) { 6145 + ksmbd_debug(RDMA, "RDMA multiple buffer descriptors %d are not supported yet\n", 6146 + ch_count); 6136 6147 return -EINVAL; 6148 + } 6137 6149 6138 6150 work->need_invalidate_rkey = 6139 6151 (Channel == SMB2_CHANNEL_RDMA_V1_INVALIDATE); ··· 6199 6185 6200 6186 if (req->Channel == SMB2_CHANNEL_RDMA_V1_INVALIDATE || 6201 6187 req->Channel == SMB2_CHANNEL_RDMA_V1) { 6188 + unsigned int ch_offset = le16_to_cpu(req->ReadChannelInfoOffset); 6189 + 6190 + if (ch_offset < offsetof(struct smb2_read_req, Buffer)) { 6191 + err = -EINVAL; 6192 + goto out; 6193 + } 6202 6194 err = smb2_set_remote_key_for_rdma(work, 6203 6195 (struct smb2_buffer_desc_v1 *) 6204 - &req->Buffer[0], 6196 + ((char *)req + ch_offset), 6205 6197 req->Channel, 6206 6198 req->ReadChannelInfoOffset, 6207 6199 req->ReadChannelInfoLength); ··· 6448 6428 6449 6429 if (req->Channel == SMB2_CHANNEL_RDMA_V1 || 6450 6430 req->Channel == SMB2_CHANNEL_RDMA_V1_INVALIDATE) { 6451 - if (req->Length != 0 || req->DataOffset != 0) 6452 - return -EINVAL; 6431 + unsigned int ch_offset = le16_to_cpu(req->WriteChannelInfoOffset); 6432 + 6433 + if (req->Length != 0 || req->DataOffset != 0 || 6434 + ch_offset < offsetof(struct smb2_write_req, Buffer)) { 6435 + err = -EINVAL; 6436 + goto out; 6437 + } 6453 6438 err = smb2_set_remote_key_for_rdma(work, 6454 6439 (struct smb2_buffer_desc_v1 *) 6455 - &req->Buffer[0], 6440 + ((char *)req + ch_offset), 6456 6441 req->Channel, 6457 6442 req->WriteChannelInfoOffset, 6458 6443 req->WriteChannelInfoLength);
+4 -1
fs/ksmbd/smb_common.c
··· 308 308 for (i = 0; i < 2; i++) { 309 309 struct kstat kstat; 310 310 struct ksmbd_kstat ksmbd_kstat; 311 + struct dentry *dentry; 311 312 312 313 if (!dir->dot_dotdot[i]) { /* fill dot entry info */ 313 314 if (i == 0) { 314 315 d_info->name = "."; 315 316 d_info->name_len = 1; 317 + dentry = dir->filp->f_path.dentry; 316 318 } else { 317 319 d_info->name = ".."; 318 320 d_info->name_len = 2; 321 + dentry = dir->filp->f_path.dentry->d_parent; 319 322 } 320 323 321 324 if (!match_pattern(d_info->name, d_info->name_len, ··· 330 327 ksmbd_kstat.kstat = &kstat; 331 328 ksmbd_vfs_fill_dentry_attrs(work, 332 329 user_ns, 333 - dir->filp->f_path.dentry->d_parent, 330 + dentry, 334 331 &ksmbd_kstat); 335 332 rc = fn(conn, info_level, d_info, &ksmbd_kstat); 336 333 if (rc)
+1 -1
fs/ksmbd/transport_rdma.c
··· 80 80 /* The maximum single-message size which can be received */ 81 81 static int smb_direct_max_receive_size = 8192; 82 82 83 - static int smb_direct_max_read_write_size = 1048512; 83 + static int smb_direct_max_read_write_size = 524224; 84 84 85 85 static int smb_direct_max_outstanding_rw_ops = 8; 86 86
+1
fs/ksmbd/vfs.h
··· 47 47 int last_entry_offset; 48 48 bool hide_dot_file; 49 49 int flags; 50 + int last_entry_off_align; 50 51 }; 51 52 52 53 struct ksmbd_readdir_data {