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

Pull ksmbd server fixes from Steve French:

- return less confusing messages on unsupported dialects
(STATUS_NOT_SUPPORTED instead of I/O error)

- fix for overly frequent inactive session termination

- fix refcount leak

- fix bounds check problems found by static checkers

- fix to advertise named stream support correctly

- Fix AES256 signing bug when connected to from MacOS

* tag '6.3-rc3-ksmbd-smb3-server-fixes' of git://git.samba.org/ksmbd:
ksmbd: return unsupported error on smb1 mount
ksmbd: return STATUS_NOT_SUPPORTED on unsupported smb2.0 dialect
ksmbd: don't terminate inactive sessions after a few seconds
ksmbd: fix possible refcount leak in smb2_open()
ksmbd: add low bound validation to FSCTL_QUERY_ALLOCATED_RANGES
ksmbd: add low bound validation to FSCTL_SET_ZERO_DATA
ksmbd: set FILE_NAMED_STREAMS attribute in FS_ATTRIBUTE_INFORMATION
ksmbd: fix wrong signingkey creation when encryption is AES256

+78 -55
+3 -2
fs/ksmbd/auth.c
··· 727 727 goto smb3signkey_ret; 728 728 } 729 729 730 - if (conn->cipher_type == SMB2_ENCRYPTION_AES256_CCM || 731 - conn->cipher_type == SMB2_ENCRYPTION_AES256_GCM) 730 + if (key_size == SMB3_ENC_DEC_KEY_SIZE && 731 + (conn->cipher_type == SMB2_ENCRYPTION_AES256_CCM || 732 + conn->cipher_type == SMB2_ENCRYPTION_AES256_GCM)) 732 733 rc = crypto_shash_update(CRYPTO_HMACSHA256(ctx), L256, 4); 733 734 else 734 735 rc = crypto_shash_update(CRYPTO_HMACSHA256(ctx), L128, 4);
+4 -7
fs/ksmbd/connection.c
··· 298 298 kvfree(conn->request_buf); 299 299 conn->request_buf = NULL; 300 300 301 - size = t->ops->read(t, hdr_buf, sizeof(hdr_buf)); 301 + size = t->ops->read(t, hdr_buf, sizeof(hdr_buf), -1); 302 302 if (size != sizeof(hdr_buf)) 303 303 break; 304 304 ··· 319 319 } 320 320 321 321 /* 322 - * Check if pdu size is valid (min : smb header size, 323 - * max : 0x00FFFFFF). 322 + * Check maximum pdu size(0x00FFFFFF). 324 323 */ 325 - if (pdu_size < __SMB2_HEADER_STRUCTURE_SIZE || 326 - pdu_size > MAX_STREAM_PROT_LEN) { 324 + if (pdu_size > MAX_STREAM_PROT_LEN) 327 325 break; 328 - } 329 326 330 327 /* 4 for rfc1002 length field */ 331 328 size = pdu_size + 4; ··· 341 344 * We already read 4 bytes to find out PDU size, now 342 345 * read in PDU 343 346 */ 344 - size = t->ops->read(t, conn->request_buf + 4, pdu_size); 347 + size = t->ops->read(t, conn->request_buf + 4, pdu_size, 2); 345 348 if (size < 0) { 346 349 pr_err("sock_read failed: %d\n", size); 347 350 break;
+2 -1
fs/ksmbd/connection.h
··· 114 114 int (*prepare)(struct ksmbd_transport *t); 115 115 void (*disconnect)(struct ksmbd_transport *t); 116 116 void (*shutdown)(struct ksmbd_transport *t); 117 - int (*read)(struct ksmbd_transport *t, char *buf, unsigned int size); 117 + int (*read)(struct ksmbd_transport *t, char *buf, 118 + unsigned int size, int max_retries); 118 119 int (*writev)(struct ksmbd_transport *t, struct kvec *iovs, int niov, 119 120 int size, bool need_invalidate_rkey, 120 121 unsigned int remote_key);
+15 -5
fs/ksmbd/smb2pdu.c
··· 2977 2977 sizeof(struct smb_acl) + 2978 2978 sizeof(struct smb_ace) * ace_num * 2, 2979 2979 GFP_KERNEL); 2980 - if (!pntsd) 2980 + if (!pntsd) { 2981 + posix_acl_release(fattr.cf_acls); 2982 + posix_acl_release(fattr.cf_dacls); 2981 2983 goto err_out; 2984 + } 2982 2985 2983 2986 rc = build_sec_desc(idmap, 2984 2987 pntsd, NULL, 0, ··· 4936 4933 FILE_SUPPORTS_BLOCK_REFCOUNTING); 4937 4934 4938 4935 info->Attributes |= cpu_to_le32(server_conf.share_fake_fscaps); 4936 + 4937 + if (test_share_config_flag(work->tcon->share_conf, 4938 + KSMBD_SHARE_FLAG_STREAMS)) 4939 + info->Attributes |= cpu_to_le32(FILE_NAMED_STREAMS); 4939 4940 4940 4941 info->MaxPathNameComponentLength = cpu_to_le32(stfs.f_namelen); 4941 4942 len = smbConvertToUTF16((__le16 *)info->FileSystemName, ··· 7451 7444 if (in_count == 0) 7452 7445 return -EINVAL; 7453 7446 7447 + start = le64_to_cpu(qar_req->file_offset); 7448 + length = le64_to_cpu(qar_req->length); 7449 + 7450 + if (start < 0 || length < 0) 7451 + return -EINVAL; 7452 + 7454 7453 fp = ksmbd_lookup_fd_fast(work, id); 7455 7454 if (!fp) 7456 7455 return -ENOENT; 7457 - 7458 - start = le64_to_cpu(qar_req->file_offset); 7459 - length = le64_to_cpu(qar_req->length); 7460 7456 7461 7457 ret = ksmbd_vfs_fqar_lseek(fp, start, length, 7462 7458 qar_rsp, in_count, out_count); ··· 7761 7751 7762 7752 off = le64_to_cpu(zero_data->FileOffset); 7763 7753 bfz = le64_to_cpu(zero_data->BeyondFinalZero); 7764 - if (off > bfz) { 7754 + if (off < 0 || bfz < 0 || off > bfz) { 7765 7755 ret = -EINVAL; 7766 7756 goto out; 7767 7757 }
+22 -5
fs/ksmbd/smb_common.c
··· 434 434 435 435 static int __smb2_negotiate(struct ksmbd_conn *conn) 436 436 { 437 - return (conn->dialect >= SMB21_PROT_ID && 437 + return (conn->dialect >= SMB20_PROT_ID && 438 438 conn->dialect <= SMB311_PROT_ID); 439 439 } 440 440 ··· 442 442 { 443 443 struct smb_negotiate_rsp *neg_rsp = work->response_buf; 444 444 445 - ksmbd_debug(SMB, "Unsupported SMB protocol\n"); 446 - neg_rsp->hdr.Status.CifsError = STATUS_INVALID_LOGON_TYPE; 447 - return -EINVAL; 445 + ksmbd_debug(SMB, "Unsupported SMB1 protocol\n"); 446 + 447 + /* 448 + * Remove 4 byte direct TCP header, add 2 byte bcc and 449 + * 2 byte DialectIndex. 450 + */ 451 + *(__be32 *)work->response_buf = 452 + cpu_to_be32(sizeof(struct smb_hdr) - 4 + 2 + 2); 453 + neg_rsp->hdr.Status.CifsError = STATUS_SUCCESS; 454 + 455 + neg_rsp->hdr.Command = SMB_COM_NEGOTIATE; 456 + *(__le32 *)neg_rsp->hdr.Protocol = SMB1_PROTO_NUMBER; 457 + neg_rsp->hdr.Flags = SMBFLG_RESPONSE; 458 + neg_rsp->hdr.Flags2 = SMBFLG2_UNICODE | SMBFLG2_ERR_STATUS | 459 + SMBFLG2_EXT_SEC | SMBFLG2_IS_LONG_NAME; 460 + 461 + neg_rsp->hdr.WordCount = 1; 462 + neg_rsp->DialectIndex = cpu_to_le16(work->conn->dialect); 463 + neg_rsp->ByteCount = 0; 464 + return 0; 448 465 } 449 466 450 467 int ksmbd_smb_negotiate_common(struct ksmbd_work *work, unsigned int command) ··· 482 465 } 483 466 } 484 467 485 - if (command == SMB2_NEGOTIATE_HE && __smb2_negotiate(conn)) { 468 + if (command == SMB2_NEGOTIATE_HE) { 486 469 ret = smb2_handle_negotiate(work); 487 470 init_smb2_neg_rsp(work); 488 471 return ret;
+8 -22
fs/ksmbd/smb_common.h
··· 158 158 159 159 #define SMB1_PROTO_NUMBER cpu_to_le32(0x424d53ff) 160 160 #define SMB_COM_NEGOTIATE 0x72 161 - 162 161 #define SMB1_CLIENT_GUID_SIZE (16) 162 + 163 + #define SMBFLG_RESPONSE 0x80 /* this PDU is a response from server */ 164 + 165 + #define SMBFLG2_IS_LONG_NAME cpu_to_le16(0x40) 166 + #define SMBFLG2_EXT_SEC cpu_to_le16(0x800) 167 + #define SMBFLG2_ERR_STATUS cpu_to_le16(0x4000) 168 + #define SMBFLG2_UNICODE cpu_to_le16(0x8000) 169 + 163 170 struct smb_hdr { 164 171 __be32 smb_buf_length; 165 172 __u8 Protocol[4]; ··· 206 199 struct smb_negotiate_rsp { 207 200 struct smb_hdr hdr; /* wct = 17 */ 208 201 __le16 DialectIndex; /* 0xFFFF = no dialect acceptable */ 209 - __u8 SecurityMode; 210 - __le16 MaxMpxCount; 211 - __le16 MaxNumberVcs; 212 - __le32 MaxBufferSize; 213 - __le32 MaxRawSize; 214 - __le32 SessionKey; 215 - __le32 Capabilities; /* see below */ 216 - __le32 SystemTimeLow; 217 - __le32 SystemTimeHigh; 218 - __le16 ServerTimeZone; 219 - __u8 EncryptionKeyLength; 220 202 __le16 ByteCount; 221 - union { 222 - unsigned char EncryptionKey[8]; /* cap extended security off */ 223 - /* followed by Domain name - if extended security is off */ 224 - /* followed by 16 bytes of server GUID */ 225 - /* then security blob if cap_extended_security negotiated */ 226 - struct { 227 - unsigned char GUID[SMB1_CLIENT_GUID_SIZE]; 228 - unsigned char SecurityBlob[1]; 229 - } __packed extended_response; 230 - } __packed u; 231 203 } __packed; 232 204 233 205 struct filesystem_attribute_info {
+1 -1
fs/ksmbd/transport_rdma.c
··· 670 670 } 671 671 672 672 static int smb_direct_read(struct ksmbd_transport *t, char *buf, 673 - unsigned int size) 673 + unsigned int size, int unused) 674 674 { 675 675 struct smb_direct_recvmsg *recvmsg; 676 676 struct smb_direct_data_transfer *data_transfer;
+23 -12
fs/ksmbd/transport_tcp.c
··· 291 291 292 292 /** 293 293 * ksmbd_tcp_readv() - read data from socket in given iovec 294 - * @t: TCP transport instance 295 - * @iov_orig: base IO vector 296 - * @nr_segs: number of segments in base iov 297 - * @to_read: number of bytes to read from socket 294 + * @t: TCP transport instance 295 + * @iov_orig: base IO vector 296 + * @nr_segs: number of segments in base iov 297 + * @to_read: number of bytes to read from socket 298 + * @max_retries: maximum retry count 298 299 * 299 300 * Return: on success return number of bytes read from socket, 300 301 * otherwise return error number 301 302 */ 302 303 static int ksmbd_tcp_readv(struct tcp_transport *t, struct kvec *iov_orig, 303 - unsigned int nr_segs, unsigned int to_read) 304 + unsigned int nr_segs, unsigned int to_read, 305 + int max_retries) 304 306 { 305 307 int length = 0; 306 308 int total_read; ··· 310 308 struct msghdr ksmbd_msg; 311 309 struct kvec *iov; 312 310 struct ksmbd_conn *conn = KSMBD_TRANS(t)->conn; 313 - int max_retry = 2; 314 311 315 312 iov = get_conn_iovec(t, nr_segs); 316 313 if (!iov) ··· 336 335 } else if (conn->status == KSMBD_SESS_NEED_RECONNECT) { 337 336 total_read = -EAGAIN; 338 337 break; 339 - } else if ((length == -ERESTARTSYS || length == -EAGAIN) && 340 - max_retry) { 338 + } else if (length == -ERESTARTSYS || length == -EAGAIN) { 339 + /* 340 + * If max_retries is negative, Allow unlimited 341 + * retries to keep connection with inactive sessions. 342 + */ 343 + if (max_retries == 0) { 344 + total_read = length; 345 + break; 346 + } else if (max_retries > 0) { 347 + max_retries--; 348 + } 349 + 341 350 usleep_range(1000, 2000); 342 351 length = 0; 343 - max_retry--; 344 352 continue; 345 353 } else if (length <= 0) { 346 - total_read = -EAGAIN; 354 + total_read = length; 347 355 break; 348 356 } 349 357 } ··· 368 358 * Return: on success return number of bytes read from socket, 369 359 * otherwise return error number 370 360 */ 371 - static int ksmbd_tcp_read(struct ksmbd_transport *t, char *buf, unsigned int to_read) 361 + static int ksmbd_tcp_read(struct ksmbd_transport *t, char *buf, 362 + unsigned int to_read, int max_retries) 372 363 { 373 364 struct kvec iov; 374 365 375 366 iov.iov_base = buf; 376 367 iov.iov_len = to_read; 377 368 378 - return ksmbd_tcp_readv(TCP_TRANS(t), &iov, 1, to_read); 369 + return ksmbd_tcp_readv(TCP_TRANS(t), &iov, 1, to_read, max_retries); 379 370 } 380 371 381 372 static int ksmbd_tcp_writev(struct ksmbd_transport *t, struct kvec *iov,