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

Pull ksmbd server fixes from Steve French:
"Four fixes, three for stable:

- slab out of bounds fix

- lock cancellation fix

- minor cleanup to address clang warning

- fix for xfstest 551 (wrong parms passed to kvmalloc)"

* tag '6.3-rc5-ksmbd-server-fixes' of git://git.samba.org/ksmbd:
ksmbd: fix slab-out-of-bounds in init_smb2_rsp_hdr
ksmbd: delete asynchronous work from list
ksmbd: remove unused is_char_allowed function
ksmbd: do not call kvmalloc() with __GFP_NORETRY | __GFP_NO_WARN

+141 -80
+6 -11
fs/ksmbd/connection.c
··· 112 112 struct ksmbd_conn *conn = work->conn; 113 113 struct list_head *requests_queue = NULL; 114 114 115 - if (conn->ops->get_cmd_val(work) != SMB2_CANCEL_HE) { 115 + if (conn->ops->get_cmd_val(work) != SMB2_CANCEL_HE) 116 116 requests_queue = &conn->requests; 117 - work->synchronous = true; 118 - } 119 117 120 118 if (requests_queue) { 121 119 atomic_inc(&conn->req_running); ··· 134 136 135 137 if (!work->multiRsp) 136 138 atomic_dec(&conn->req_running); 137 - spin_lock(&conn->request_lock); 138 139 if (!work->multiRsp) { 140 + spin_lock(&conn->request_lock); 139 141 list_del_init(&work->request_entry); 140 - if (!work->synchronous) 141 - list_del_init(&work->async_request_entry); 142 + spin_unlock(&conn->request_lock); 143 + if (work->asynchronous) 144 + release_async_work(work); 142 145 ret = 0; 143 146 } 144 - spin_unlock(&conn->request_lock); 145 147 146 148 wake_up_all(&conn->req_running_q); 147 149 return ret; ··· 324 326 325 327 /* 4 for rfc1002 length field */ 326 328 size = pdu_size + 4; 327 - conn->request_buf = kvmalloc(size, 328 - GFP_KERNEL | 329 - __GFP_NOWARN | 330 - __GFP_NORETRY); 329 + conn->request_buf = kvmalloc(size, GFP_KERNEL); 331 330 if (!conn->request_buf) 332 331 break; 333 332
+1 -1
fs/ksmbd/ksmbd_work.h
··· 68 68 /* Request is encrypted */ 69 69 bool encrypted:1; 70 70 /* Is this SYNC or ASYNC ksmbd_work */ 71 - bool synchronous:1; 71 + bool asynchronous:1; 72 72 bool need_invalidate_rkey:1; 73 73 74 74 unsigned int remote_key;
+1 -4
fs/ksmbd/server.c
··· 289 289 work->request_buf = conn->request_buf; 290 290 conn->request_buf = NULL; 291 291 292 - if (ksmbd_init_smb_server(work)) { 293 - ksmbd_free_work_struct(work); 294 - return -EINVAL; 295 - } 292 + ksmbd_init_smb_server(work); 296 293 297 294 ksmbd_conn_enqueue_request(work); 298 295 atomic_inc(&conn->r_count);
+21 -15
fs/ksmbd/smb2pdu.c
··· 229 229 struct smb2_negotiate_rsp *rsp; 230 230 struct ksmbd_conn *conn = work->conn; 231 231 232 - if (conn->need_neg == false) 233 - return -EINVAL; 234 - 235 232 *(__be32 *)work->response_buf = 236 233 cpu_to_be32(conn->vals->header_size); 237 234 ··· 495 498 rsp_hdr->SessionId = rcv_hdr->SessionId; 496 499 memcpy(rsp_hdr->Signature, rcv_hdr->Signature, 16); 497 500 498 - work->synchronous = true; 499 - if (work->async_id) { 500 - ksmbd_release_id(&conn->async_ida, work->async_id); 501 - work->async_id = 0; 502 - } 503 - 504 501 return 0; 505 502 } 506 503 ··· 635 644 pr_err("Failed to alloc async message id\n"); 636 645 return id; 637 646 } 638 - work->synchronous = false; 647 + work->asynchronous = true; 639 648 work->async_id = id; 640 649 rsp_hdr->Id.AsyncId = cpu_to_le64(id); 641 650 ··· 653 662 } 654 663 655 664 return 0; 665 + } 666 + 667 + void release_async_work(struct ksmbd_work *work) 668 + { 669 + struct ksmbd_conn *conn = work->conn; 670 + 671 + spin_lock(&conn->request_lock); 672 + list_del_init(&work->async_request_entry); 673 + spin_unlock(&conn->request_lock); 674 + 675 + work->asynchronous = 0; 676 + work->cancel_fn = NULL; 677 + kfree(work->cancel_argv); 678 + work->cancel_argv = NULL; 679 + if (work->async_id) { 680 + ksmbd_release_id(&conn->async_ida, work->async_id); 681 + work->async_id = 0; 682 + } 656 683 } 657 684 658 685 void smb2_send_interim_resp(struct ksmbd_work *work, __le32 status) ··· 7054 7045 7055 7046 ksmbd_vfs_posix_lock_wait(flock); 7056 7047 7057 - spin_lock(&work->conn->request_lock); 7058 7048 spin_lock(&fp->f_lock); 7059 7049 list_del(&work->fp_entry); 7060 - work->cancel_fn = NULL; 7061 - kfree(argv); 7062 7050 spin_unlock(&fp->f_lock); 7063 - spin_unlock(&work->conn->request_lock); 7064 7051 7065 7052 if (work->state != KSMBD_WORK_ACTIVE) { 7066 7053 list_del(&smb_lock->llist); ··· 7074 7069 work->send_no_response = 1; 7075 7070 goto out; 7076 7071 } 7072 + 7077 7073 init_smb2_rsp_hdr(work); 7078 7074 smb2_set_err_rsp(work); 7079 7075 rsp->hdr.Status = ··· 7087 7081 spin_lock(&work->conn->llist_lock); 7088 7082 list_del(&smb_lock->clist); 7089 7083 spin_unlock(&work->conn->llist_lock); 7090 - 7084 + release_async_work(work); 7091 7085 goto retry; 7092 7086 } else if (!rc) { 7093 7087 spin_lock(&work->conn->llist_lock);
+1
fs/ksmbd/smb2pdu.h
··· 486 486 struct file_lock *smb_flock_init(struct file *f); 487 487 int setup_async_work(struct ksmbd_work *work, void (*fn)(void **), 488 488 void **arg); 489 + void release_async_work(struct ksmbd_work *work); 489 490 void smb2_send_interim_resp(struct ksmbd_work *work, __le32 status); 490 491 struct channel *lookup_chann_list(struct ksmbd_session *sess, 491 492 struct ksmbd_conn *conn);
+110 -30
fs/ksmbd/smb_common.c
··· 283 283 return BAD_PROT_ID; 284 284 } 285 285 286 - int ksmbd_init_smb_server(struct ksmbd_work *work) 287 - { 288 - struct ksmbd_conn *conn = work->conn; 286 + #define SMB_COM_NEGOTIATE_EX 0x0 289 287 290 - if (conn->need_neg == false) 288 + /** 289 + * get_smb1_cmd_val() - get smb command value from smb header 290 + * @work: smb work containing smb header 291 + * 292 + * Return: smb command value 293 + */ 294 + static u16 get_smb1_cmd_val(struct ksmbd_work *work) 295 + { 296 + return SMB_COM_NEGOTIATE_EX; 297 + } 298 + 299 + /** 300 + * init_smb1_rsp_hdr() - initialize smb negotiate response header 301 + * @work: smb work containing smb request 302 + * 303 + * Return: 0 on success, otherwise -EINVAL 304 + */ 305 + static int init_smb1_rsp_hdr(struct ksmbd_work *work) 306 + { 307 + struct smb_hdr *rsp_hdr = (struct smb_hdr *)work->response_buf; 308 + struct smb_hdr *rcv_hdr = (struct smb_hdr *)work->request_buf; 309 + 310 + /* 311 + * Remove 4 byte direct TCP header. 312 + */ 313 + *(__be32 *)work->response_buf = 314 + cpu_to_be32(sizeof(struct smb_hdr) - 4); 315 + 316 + rsp_hdr->Command = SMB_COM_NEGOTIATE; 317 + *(__le32 *)rsp_hdr->Protocol = SMB1_PROTO_NUMBER; 318 + rsp_hdr->Flags = SMBFLG_RESPONSE; 319 + rsp_hdr->Flags2 = SMBFLG2_UNICODE | SMBFLG2_ERR_STATUS | 320 + SMBFLG2_EXT_SEC | SMBFLG2_IS_LONG_NAME; 321 + rsp_hdr->Pid = rcv_hdr->Pid; 322 + rsp_hdr->Mid = rcv_hdr->Mid; 323 + return 0; 324 + } 325 + 326 + /** 327 + * smb1_check_user_session() - check for valid session for a user 328 + * @work: smb work containing smb request buffer 329 + * 330 + * Return: 0 on success, otherwise error 331 + */ 332 + static int smb1_check_user_session(struct ksmbd_work *work) 333 + { 334 + unsigned int cmd = work->conn->ops->get_cmd_val(work); 335 + 336 + if (cmd == SMB_COM_NEGOTIATE_EX) 291 337 return 0; 292 338 293 - init_smb3_11_server(conn); 339 + return -EINVAL; 340 + } 294 341 295 - if (conn->ops->get_cmd_val(work) != SMB_COM_NEGOTIATE) 296 - conn->need_neg = false; 342 + /** 343 + * smb1_allocate_rsp_buf() - allocate response buffer for a command 344 + * @work: smb work containing smb request 345 + * 346 + * Return: 0 on success, otherwise -ENOMEM 347 + */ 348 + static int smb1_allocate_rsp_buf(struct ksmbd_work *work) 349 + { 350 + work->response_buf = kmalloc(MAX_CIFS_SMALL_BUFFER_SIZE, 351 + GFP_KERNEL | __GFP_ZERO); 352 + work->response_sz = MAX_CIFS_SMALL_BUFFER_SIZE; 353 + 354 + if (!work->response_buf) { 355 + pr_err("Failed to allocate %u bytes buffer\n", 356 + MAX_CIFS_SMALL_BUFFER_SIZE); 357 + return -ENOMEM; 358 + } 359 + 297 360 return 0; 361 + } 362 + 363 + static struct smb_version_ops smb1_server_ops = { 364 + .get_cmd_val = get_smb1_cmd_val, 365 + .init_rsp_hdr = init_smb1_rsp_hdr, 366 + .allocate_rsp_buf = smb1_allocate_rsp_buf, 367 + .check_user_session = smb1_check_user_session, 368 + }; 369 + 370 + static int smb1_negotiate(struct ksmbd_work *work) 371 + { 372 + return ksmbd_smb_negotiate_common(work, SMB_COM_NEGOTIATE); 373 + } 374 + 375 + static struct smb_version_cmds smb1_server_cmds[1] = { 376 + [SMB_COM_NEGOTIATE_EX] = { .proc = smb1_negotiate, }, 377 + }; 378 + 379 + static void init_smb1_server(struct ksmbd_conn *conn) 380 + { 381 + conn->ops = &smb1_server_ops; 382 + conn->cmds = smb1_server_cmds; 383 + conn->max_cmds = ARRAY_SIZE(smb1_server_cmds); 384 + } 385 + 386 + void ksmbd_init_smb_server(struct ksmbd_work *work) 387 + { 388 + struct ksmbd_conn *conn = work->conn; 389 + __le32 proto; 390 + 391 + if (conn->need_neg == false) 392 + return; 393 + 394 + proto = *(__le32 *)((struct smb_hdr *)work->request_buf)->Protocol; 395 + if (proto == SMB1_PROTO_NUMBER) 396 + init_smb1_server(conn); 397 + else 398 + init_smb3_11_server(conn); 298 399 } 299 400 300 401 int ksmbd_populate_dot_dotdot_entries(struct ksmbd_work *work, int info_level, ··· 545 444 546 445 ksmbd_debug(SMB, "Unsupported SMB1 protocol\n"); 547 446 548 - /* 549 - * Remove 4 byte direct TCP header, add 2 byte bcc and 550 - * 2 byte DialectIndex. 551 - */ 552 - *(__be32 *)work->response_buf = 553 - cpu_to_be32(sizeof(struct smb_hdr) - 4 + 2 + 2); 447 + /* Add 2 byte bcc and 2 byte DialectIndex. */ 448 + inc_rfc1001_len(work->response_buf, 4); 554 449 neg_rsp->hdr.Status.CifsError = STATUS_SUCCESS; 555 - 556 - neg_rsp->hdr.Command = SMB_COM_NEGOTIATE; 557 - *(__le32 *)neg_rsp->hdr.Protocol = SMB1_PROTO_NUMBER; 558 - neg_rsp->hdr.Flags = SMBFLG_RESPONSE; 559 - neg_rsp->hdr.Flags2 = SMBFLG2_UNICODE | SMBFLG2_ERR_STATUS | 560 - SMBFLG2_EXT_SEC | SMBFLG2_IS_LONG_NAME; 561 450 562 451 neg_rsp->hdr.WordCount = 1; 563 452 neg_rsp->DialectIndex = cpu_to_le16(work->conn->dialect); ··· 565 474 ksmbd_debug(SMB, "conn->dialect 0x%x\n", conn->dialect); 566 475 567 476 if (command == SMB2_NEGOTIATE_HE) { 568 - struct smb2_hdr *smb2_hdr = smb2_get_msg(work->request_buf); 569 - 570 - if (smb2_hdr->ProtocolId != SMB2_PROTO_NUMBER) { 571 - ksmbd_debug(SMB, "Downgrade to SMB1 negotiation\n"); 572 - command = SMB_COM_NEGOTIATE; 573 - } 574 - } 575 - 576 - if (command == SMB2_NEGOTIATE_HE) { 577 477 ret = smb2_handle_negotiate(work); 578 - init_smb2_neg_rsp(work); 579 478 return ret; 580 479 } 581 480 582 481 if (command == SMB_COM_NEGOTIATE) { 583 482 if (__smb2_negotiate(conn)) { 584 - conn->need_neg = true; 585 483 init_smb3_11_server(conn); 586 484 init_smb2_neg_rsp(work); 587 485 ksmbd_debug(SMB, "Upgrade to SMB2 negotiation\n");
+1 -1
fs/ksmbd/smb_common.h
··· 427 427 428 428 int ksmbd_lookup_dialect_by_id(__le16 *cli_dialects, __le16 dialects_count); 429 429 430 - int ksmbd_init_smb_server(struct ksmbd_work *work); 430 + void ksmbd_init_smb_server(struct ksmbd_work *work); 431 431 432 432 struct ksmbd_kstat; 433 433 int ksmbd_populate_dot_dotdot_entries(struct ksmbd_work *work,
-18
fs/ksmbd/unicode.c
··· 114 114 } 115 115 116 116 /* 117 - * is_char_allowed() - check for valid character 118 - * @ch: input character to be checked 119 - * 120 - * Return: 1 if char is allowed, otherwise 0 121 - */ 122 - static inline int is_char_allowed(char *ch) 123 - { 124 - /* check for control chars, wildcards etc. */ 125 - if (!(*ch & 0x80) && 126 - (*ch <= 0x1f || 127 - *ch == '?' || *ch == '"' || *ch == '<' || 128 - *ch == '>' || *ch == '|')) 129 - return 0; 130 - 131 - return 1; 132 - } 133 - 134 - /* 135 117 * smb_from_utf16() - convert utf16le string to local charset 136 118 * @to: destination buffer 137 119 * @from: source buffer