This is a note to let you know that I've just added the patch titled ksmbd: add missing compound request handing in some commands to the 5.15-stable tree which can be found at: http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary The filename of the patch is: ksmbd-add-missing-compound-request-handing-in-some-commands.patch and it can be found in the queue-5.15 subdirectory. If you, or anyone else, feels it should not be added to the stable tree, please let <stable@xxxxxxxxxxxxxxx> know about it. >From linkinjeon@xxxxxxxxx Mon Dec 18 16:41:18 2023 From: Namjae Jeon <linkinjeon@xxxxxxxxxx> Date: Tue, 19 Dec 2023 00:34:11 +0900 Subject: ksmbd: add missing compound request handing in some commands To: gregkh@xxxxxxxxxxxxxxxxxxx, stable@xxxxxxxxxxxxxxx Cc: smfrench@xxxxxxxxx, Namjae Jeon <linkinjeon@xxxxxxxxxx>, Steve French <stfrench@xxxxxxxxxxxxx> Message-ID: <20231218153454.8090-112-linkinjeon@xxxxxxxxxx> From: Namjae Jeon <linkinjeon@xxxxxxxxxx> [ Upstream commit 7b7d709ef7cf285309157fb94c33f625dd22c5e1 ] This patch add the compound request handling to the some commands. Existing clients do not send these commands as compound requests, but ksmbd should consider that they may come. Cc: stable@xxxxxxxxxxxxxxx Signed-off-by: Namjae Jeon <linkinjeon@xxxxxxxxxx> Signed-off-by: Steve French <stfrench@xxxxxxxxxxxxx> Signed-off-by: Greg Kroah-Hartman <gregkh@xxxxxxxxxxxxxxxxxxx> --- fs/ksmbd/smb2pdu.c | 78 ++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 53 insertions(+), 25 deletions(-) --- a/fs/ksmbd/smb2pdu.c +++ b/fs/ksmbd/smb2pdu.c @@ -1915,14 +1915,16 @@ out_err: int smb2_tree_connect(struct ksmbd_work *work) { struct ksmbd_conn *conn = work->conn; - struct smb2_tree_connect_req *req = smb2_get_msg(work->request_buf); - struct smb2_tree_connect_rsp *rsp = smb2_get_msg(work->response_buf); + struct smb2_tree_connect_req *req; + struct smb2_tree_connect_rsp *rsp; struct ksmbd_session *sess = work->sess; char *treename = NULL, *name = NULL; struct ksmbd_tree_conn_status status; struct ksmbd_share_config *share; int rc = -EINVAL; + WORK_BUFFERS(work, req, rsp); + treename = smb_strndup_from_utf16(req->Buffer, le16_to_cpu(req->PathLength), true, conn->local_nls); @@ -2091,19 +2093,19 @@ static int smb2_create_open_flags(bool f */ int smb2_tree_disconnect(struct ksmbd_work *work) { - struct smb2_tree_disconnect_rsp *rsp = smb2_get_msg(work->response_buf); + struct smb2_tree_disconnect_rsp *rsp; + struct smb2_tree_disconnect_req *req; struct ksmbd_session *sess = work->sess; struct ksmbd_tree_connect *tcon = work->tcon; + WORK_BUFFERS(work, req, rsp); + rsp->StructureSize = cpu_to_le16(4); inc_rfc1001_len(work->response_buf, 4); ksmbd_debug(SMB, "request\n"); if (!tcon || test_and_set_bit(TREE_CONN_EXPIRE, &tcon->status)) { - struct smb2_tree_disconnect_req *req = - smb2_get_msg(work->request_buf); - ksmbd_debug(SMB, "Invalid tid %d\n", req->hdr.Id.SyncId.TreeId); rsp->hdr.Status = STATUS_NETWORK_NAME_DELETED; @@ -2126,10 +2128,14 @@ int smb2_tree_disconnect(struct ksmbd_wo int smb2_session_logoff(struct ksmbd_work *work) { struct ksmbd_conn *conn = work->conn; - struct smb2_logoff_rsp *rsp = smb2_get_msg(work->response_buf); + struct smb2_logoff_req *req; + struct smb2_logoff_rsp *rsp; struct ksmbd_session *sess; - struct smb2_logoff_req *req = smb2_get_msg(work->request_buf); - u64 sess_id = le64_to_cpu(req->hdr.SessionId); + u64 sess_id; + + WORK_BUFFERS(work, req, rsp); + + sess_id = le64_to_cpu(req->hdr.SessionId); rsp->StructureSize = cpu_to_le16(4); inc_rfc1001_len(work->response_buf, 4); @@ -2169,12 +2175,14 @@ int smb2_session_logoff(struct ksmbd_wor */ static noinline int create_smb2_pipe(struct ksmbd_work *work) { - struct smb2_create_rsp *rsp = smb2_get_msg(work->response_buf); - struct smb2_create_req *req = smb2_get_msg(work->request_buf); + struct smb2_create_rsp *rsp; + struct smb2_create_req *req; int id; int err; char *name; + WORK_BUFFERS(work, req, rsp); + name = smb_strndup_from_utf16(req->Buffer, le16_to_cpu(req->NameLength), 1, work->conn->local_nls); if (IS_ERR(name)) { @@ -5314,8 +5322,10 @@ int smb2_query_info(struct ksmbd_work *w static noinline int smb2_close_pipe(struct ksmbd_work *work) { u64 id; - struct smb2_close_req *req = smb2_get_msg(work->request_buf); - struct smb2_close_rsp *rsp = smb2_get_msg(work->response_buf); + struct smb2_close_req *req; + struct smb2_close_rsp *rsp; + + WORK_BUFFERS(work, req, rsp); id = req->VolatileFileId; ksmbd_session_rpc_close(work->sess, id); @@ -5457,6 +5467,9 @@ int smb2_echo(struct ksmbd_work *work) { struct smb2_echo_rsp *rsp = smb2_get_msg(work->response_buf); + if (work->next_smb2_rcv_hdr_off) + rsp = ksmbd_resp_buf_next(work); + rsp->StructureSize = cpu_to_le16(4); rsp->Reserved = 0; inc_rfc1001_len(work->response_buf, 4); @@ -6093,8 +6106,10 @@ static noinline int smb2_read_pipe(struc int nbytes = 0, err; u64 id; struct ksmbd_rpc_command *rpc_resp; - struct smb2_read_req *req = smb2_get_msg(work->request_buf); - struct smb2_read_rsp *rsp = smb2_get_msg(work->response_buf); + struct smb2_read_req *req; + struct smb2_read_rsp *rsp; + + WORK_BUFFERS(work, req, rsp); id = req->VolatileFileId; @@ -6347,14 +6362,16 @@ out: */ static noinline int smb2_write_pipe(struct ksmbd_work *work) { - struct smb2_write_req *req = smb2_get_msg(work->request_buf); - struct smb2_write_rsp *rsp = smb2_get_msg(work->response_buf); + struct smb2_write_req *req; + struct smb2_write_rsp *rsp; struct ksmbd_rpc_command *rpc_resp; u64 id = 0; int err = 0, ret = 0; char *data_buf; size_t length; + WORK_BUFFERS(work, req, rsp); + length = le32_to_cpu(req->Length); id = req->VolatileFileId; @@ -6623,6 +6640,9 @@ int smb2_cancel(struct ksmbd_work *work) struct ksmbd_work *iter; struct list_head *command_list; + if (work->next_smb2_rcv_hdr_off) + hdr = ksmbd_resp_buf_next(work); + ksmbd_debug(SMB, "smb2 cancel called on mid %llu, async flags 0x%x\n", hdr->MessageId, hdr->Flags); @@ -6782,8 +6802,8 @@ static inline bool lock_defer_pending(st */ int smb2_lock(struct ksmbd_work *work) { - struct smb2_lock_req *req = smb2_get_msg(work->request_buf); - struct smb2_lock_rsp *rsp = smb2_get_msg(work->response_buf); + struct smb2_lock_req *req; + struct smb2_lock_rsp *rsp; struct smb2_lock_element *lock_ele; struct ksmbd_file *fp = NULL; struct file_lock *flock = NULL; @@ -6800,6 +6820,8 @@ int smb2_lock(struct ksmbd_work *work) LIST_HEAD(rollback_list); int prior_lock = 0; + WORK_BUFFERS(work, req, rsp); + ksmbd_debug(SMB, "Received lock request\n"); fp = ksmbd_lookup_fd_slow(work, req->VolatileFileId, req->PersistentFileId); if (!fp) { @@ -7914,8 +7936,8 @@ out: */ static void smb20_oplock_break_ack(struct ksmbd_work *work) { - struct smb2_oplock_break *req = smb2_get_msg(work->request_buf); - struct smb2_oplock_break *rsp = smb2_get_msg(work->response_buf); + struct smb2_oplock_break *req; + struct smb2_oplock_break *rsp; struct ksmbd_file *fp; struct oplock_info *opinfo = NULL; __le32 err = 0; @@ -7924,6 +7946,8 @@ static void smb20_oplock_break_ack(struc char req_oplevel = 0, rsp_oplevel = 0; unsigned int oplock_change_type; + WORK_BUFFERS(work, req, rsp); + volatile_id = req->VolatileFid; persistent_id = req->PersistentFid; req_oplevel = req->OplockLevel; @@ -8058,8 +8082,8 @@ static int check_lease_state(struct leas static void smb21_lease_break_ack(struct ksmbd_work *work) { struct ksmbd_conn *conn = work->conn; - struct smb2_lease_ack *req = smb2_get_msg(work->request_buf); - struct smb2_lease_ack *rsp = smb2_get_msg(work->response_buf); + struct smb2_lease_ack *req; + struct smb2_lease_ack *rsp; struct oplock_info *opinfo; __le32 err = 0; int ret = 0; @@ -8067,6 +8091,8 @@ static void smb21_lease_break_ack(struct __le32 lease_state; struct lease *lease; + WORK_BUFFERS(work, req, rsp); + ksmbd_debug(OPLOCK, "smb21 lease break, lease state(0x%x)\n", le32_to_cpu(req->LeaseState)); opinfo = lookup_lease_in_table(conn, req->LeaseKey); @@ -8192,8 +8218,10 @@ err_out: */ int smb2_oplock_break(struct ksmbd_work *work) { - struct smb2_oplock_break *req = smb2_get_msg(work->request_buf); - struct smb2_oplock_break *rsp = smb2_get_msg(work->response_buf); + struct smb2_oplock_break *req; + struct smb2_oplock_break *rsp; + + WORK_BUFFERS(work, req, rsp); switch (le16_to_cpu(req->StructureSize)) { case OP_BREAK_STRUCT_SIZE_20: Patches currently in stable-queue which might be from linkinjeon@xxxxxxxxx are queue-5.15/ksmbd-fix-uaf-issue-from-opinfo-conn.patch queue-5.15/ksmbd-fix-race-condition-from-parallel-smb2-lock-requests.patch queue-5.15/ksmbd-validate-session-id-and-tree-id-in-compound-request.patch queue-5.15/ksmbd-reorganize-ksmbd_iov_pin_rsp.patch queue-5.15/ksmbd-convert-to-use-sysfs_emit-sysfs_emit_at-apis.patch queue-5.15/ksmbd-validate-length-in-smb2_write.patch queue-5.15/ksmbd-add-support-for-key-exchange.patch queue-5.15/ksmbd-request-update-to-stale-share-config.patch queue-5.15/ksmbd-remove-generic_fillattr-use-in-smb2_open.patch queue-5.15/ksmbd-fix-uninitialized-pointer-read-in-smb2_create_link.patch queue-5.15/ksmbd-set-smb2_session_flag_encrypt_data-when-enforcing-data-encryption-for-this-share.patch queue-5.15/ksmbd-constify-struct-path.patch queue-5.15/ksmbd-casefold-utf-8-share-names-and-fix-ascii-lowercase-conversion.patch queue-5.15/ksmbd-validate-smb-request-protocol-id.patch queue-5.15/ksmbd-avoid-out-of-bounds-access-in-decode_preauth_ctxt.patch queue-5.15/ksmbd-release-interim-response-after-sending-status-pending-response.patch queue-5.15/ksmbd-fix-racy-issue-under-cocurrent-smb2-tree-disconnect.patch queue-5.15/ksmbd-fix-out-of-bounds-read-in-smb2_sess_setup.patch queue-5.15/ksmbd-decrease-the-number-of-smb3-smbdirect-server-sges.patch queue-5.15/ksmbd-make-utf-8-file-name-comparison-work-in-__caseless_lookup.patch queue-5.15/ksmbd-use-f_setlk-when-unlocking-a-file.patch queue-5.15/fs-introduce-lock_rename_child-helper.patch queue-5.15/ksmbd-use-kzalloc-instead-of-__gfp_zero.patch queue-5.15/ksmbd-set-ntlmssp_negotiate_seal-flag-to-challenge-blob.patch queue-5.15/ksmbd-call-ib_drain_qp-when-disconnected.patch queue-5.15/ksmbd-fix-posix_acls-and-acls-dereferencing-possible-err_ptr.patch queue-5.15/ksmbd-destroy-expired-sessions.patch queue-5.15/ksmbd-fix-resource-leak-in-smb2_lock.patch queue-5.15/ksmbd-check-iov-vector-index-in-ksmbd_conn_write.patch queue-5.15/ksmbd-hide-socket-error-message-when-ipv6-config-is-disable.patch queue-5.15/ksmbd-use-netif_is_bridge_port.patch queue-5.15/ksmbd-smbd-simplify-tracking-pending-packets.patch queue-5.15/ksmbd-implements-sess-rpc_handle_list-as-xarray.patch queue-5.15/ksmbd-remove-duplicate-flag-set-in-smb2_write.patch queue-5.15/ksmbd-separately-allocate-ci-per-dentry.patch queue-5.15/ksmbd-fix-racy-issue-from-session-setup-and-logoff.patch queue-5.15/ksmbd-fix-race-condition-between-session-lookup-and-expire.patch queue-5.15/ksmbd-fix-wrong-smbd-max-read-write-size-check.patch queue-5.15/ksmbd-replace-usage-of-found-with-dedicated-list-iterator-variable.patch queue-5.15/ksmbd-add-support-for-surrogate-pair-conversion.patch queue-5.15/ksmbd-reduce-server-smbdirect-max-send-receive-segment-sizes.patch queue-5.15/ksmbd-fix-force-create-mode-and-force-directory-mode.patch queue-5.15/ksmbd-remove-unneeded-mark_inode_dirty-in-set_info_sec.patch queue-5.15/ksmbd-fix-potential-double-free-on-smb2_read_pipe-error-path.patch queue-5.15/ksmbd-remove-unused-ksmbd_tree_conn_share-function.patch queue-5.15/ksmbd-block-asynchronous-requests-when-making-a-delay-on-session-setup.patch queue-5.15/ksmbd-call-putname-after-using-the-last-component.patch queue-5.15/ksmbd-don-t-open-code-file_path.patch queue-5.15/ksmbd-fix-passing-freed-memory-aux_payload_buf.patch queue-5.15/ksmbd-fill-sids-in-smb_find_file_posix_info-response.patch queue-5.15/ksmbd-don-t-open-code-pd.patch queue-5.15/ksmbd-shorten-experimental-warning-on-loading-the-module.patch queue-5.15/ksmbd-remove-filename-in-ksmbd_file.patch queue-5.15/ksmbd-move-oplock-handling-after-unlock-parent-dir.patch queue-5.15/ksmbd-fix-race-condition-between-tree-conn-lookup-and-disconnect.patch queue-5.15/ksmbd-smbd-introduce-read-write-credits-for-rdma-read-write.patch queue-5.15/ksmbd-fix-slab-out-of-bounds-in-init_smb2_rsp_hdr.patch queue-5.15/ksmbd-fix-recursive-locking-in-vfs-helpers.patch queue-5.15/ksmbd-fix-some-kernel-doc-comments.patch queue-5.15/ksmbd-use-struct_size-helper-in-ksmbd_negotiate_smb_dialect.patch queue-5.15/ksmbd-smbd-relax-the-count-of-sges-required.patch queue-5.15/ksmbd-fix-wrong-error-response-status-by-using-set_smb2_rsp_status.patch queue-5.15/ksmbd-fix-spelling-mistake-excceed-exceeded.patch queue-5.15/ksmbd-fix-null-pointer-dereferences-in-ksmbd_update_fstate.patch queue-5.15/ksmbd-fix-encryption-failure-issue-for-session-logoff-response.patch queue-5.15/ksmbd-prevent-memory-leak-on-error-return.patch queue-5.15/ksmbd-fix-racy-issue-from-using-d_parent-and-d_name.patch queue-5.15/ksmbd-change-security-id-to-the-one-samba-used-for-posix-extension.patch queue-5.15/ksmbd-handle-malformed-smb1-message.patch queue-5.15/ksmbd-don-t-update-op_state-as-oplock_state_none-on-error.patch queue-5.15/ksmbd-smbd-fix-connection-dropped-issue.patch queue-5.15/ksmbd-fix-racy-issue-from-smb2-close-and-logoff-with-multichannel.patch queue-5.15/ksmbd-change-the-return-value-of-ksmbd_vfs_query_maximal_access-to-void.patch queue-5.15/ksmbd-fix-slub-overflow-in-ksmbd_decode_ntlmssp_auth_blob.patch queue-5.15/ksmbd-replace-one-element-array-with-flexible-array-member.patch queue-5.15/ksmbd-fix-uninitialized-pointer-read-in-ksmbd_vfs_rename.patch queue-5.15/ksmbd-replace-one-element-arrays-with-flexible-array-members.patch queue-5.15/ksmbd-fix-unsigned-expression-compared-with-zero.patch queue-5.15/ksmbd-implements-sess-ksmbd_chann_list-as-xarray.patch queue-5.15/ksmbd-set-file-permission-mode-to-match-samba-server-posix-extension-behavior.patch queue-5.15/ksmbd-fix-wrong-interim-response-on-compound.patch queue-5.15/ksmbd-return-invalid-parameter-error-response-if-smb2-request-is-invalid.patch queue-5.15/ksmbd-smbd-validate-buffer-descriptor-structures.patch queue-5.15/ksmbd-fix-missing-rdma-capable-flag-for-ipoib-device-in-ksmbd_rdma_capable_netdev.patch queue-5.15/ksmbd-send-proper-error-response-in-smb2_tree_connect.patch queue-5.15/ksmbd-set-negotiatecontextcount-once-instead-of-every-inc.patch queue-5.15/ksmbd-fix-typo-syncronous-synchronous.patch queue-5.15/ksmbd-validate-share-name-from-share-config-response.patch queue-5.15/ksmbd-fix-possible-deadlock-in-smb2_open.patch queue-5.15/ksmbd-fix-multiple-out-of-bounds-read-during-context-decoding.patch queue-5.15/ksmbd-add-missing-calling-smb2_set_err_rsp-on-error.patch queue-5.15/ksmbd-remove-unused-ksmbd_share_configs_cleanup-function.patch queue-5.15/ksmbd-fix-out-of-bound-read-in-parse_lease_state.patch queue-5.15/ksmbd-remove-duplicated-codes.patch queue-5.15/ksmbd-remove-a-redundant-zeroing-of-memory.patch queue-5.15/ksmbd-change-leasekey-data-type-to-u8-array.patch queue-5.15/ksmbd-add-support-for-read-compound.patch queue-5.15/ksmbd-fix-kernel-doc-comment-of-ksmbd_vfs_setxattr.patch queue-5.15/ksmbd-remove-unused-compression-negotiate-ctx-packing.patch queue-5.15/ksmbd-switch-to-use-kmemdup_nul-helper.patch queue-5.15/ksmbd-fix-race-condition-from-parallel-smb2-logoff-requests.patch queue-5.15/ksmbd-fix-out-of-bound-read-in-deassemble_neg_contexts.patch queue-5.15/ksmbd-remove-unnecessary-generic_fillattr-in-smb2_open.patch queue-5.15/ksmbd-avoid-duplicate-negotiate-ctx-offset-increments.patch queue-5.15/ksmbd-remove-experimental-warning.patch queue-5.15/ksmbd-return-a-literal-instead-of-err-in-ksmbd_vfs_kern_path_locked.patch queue-5.15/ksmbd-smbd-change-prototypes-of-rdma-read-write-related-functions.patch queue-5.15/ksmbd-fix-out-of-bounds-in-init_smb2_rsp_hdr.patch queue-5.15/ksmbd-fix-possible-memory-leak-in-smb2_lock.patch queue-5.15/ksmbd-remove-unused-field-in-ksmbd_user-struct.patch queue-5.15/ksmbd-fix-one-kernel-doc-comment.patch queue-5.15/ksmbd-no-need-to-wait-for-binded-connection-termination-at-logoff.patch queue-5.15/ksmbd-fix-race-condition-with-fp.patch queue-5.15/ksmbd-fix-wrong-signingkey-creation-when-encryption-is-aes256.patch queue-5.15/ksmbd-update-kconfig-to-note-kerberos-support-and-fix-indentation.patch queue-5.15/ksmbd-move-setting-smb2_flags_async_command-and-asyncid.patch queue-5.15/smb3-fix-ksmbd-bigendian-bug-in-oplock-break-and-move-its-struct-to-smbfs_common.patch queue-5.15/ksmbd-store-fids-as-opaque-u64-integers.patch queue-5.15/ksmbd-delete-asynchronous-work-from-list.patch queue-5.15/ksmbd-use-kvzalloc-instead-of-kvmalloc.patch queue-5.15/ksmbd-smbd-change-the-return-value-of-get_sg_list.patch queue-5.15/ksmbd-add-missing-compound-request-handing-in-some-commands.patch queue-5.15/ksmbd-remove-unused-is_char_allowed-function.patch queue-5.15/ksmbd-use-oid-registry-functions-to-decode-oids.patch queue-5.15/ksmbd-fix-kernel-doc-comment-of-ksmbd_vfs_kern_path_locked.patch queue-5.15/ksmbd-use-wait_event-instead-of-schedule_timeout.patch queue-5.15/ksmbd-check-if-a-mount-point-is-crossed-during-path-lookup.patch queue-5.15/ksmbd-replace-the-ternary-conditional-operator-with-min.patch