Named pipe handles are tracked in sess->rpc_handle_list rather than sess->file_table.idr. The generic IOCTL file lookup therefore returns -ENOENT and STATUS_OBJECT_NAME_NOT_FOUND for valid Windows 11 FSCTL_PIPE_TRANSCEIVE requests. Validate the RPC handle under rpc_lock and bypass the regular file lookup only when the handle exists. Return STATUS_FILE_CLOSED for invalid handles. Populate the response file IDs before dispatching the transceive request. Assisted-by: OpenCode:gpt-6-astra Signed-off-by: Omkar Chandorkar --- fs/smb/server/smb2pdu.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/fs/smb/server/smb2pdu.c b/fs/smb/server/smb2pdu.c index 619ef0e11..76f98ab4f 100644 --- a/fs/smb/server/smb2pdu.c +++ b/fs/smb/server/smb2pdu.c @@ -9662,6 +9662,26 @@ int smb2_ioctl(struct ksmbd_work *work) case FSCTL_PIPE_WAIT: no_fileid_ioctl = true; break; + case FSCTL_PIPE_TRANSCEIVE: + if (!test_share_config_flag(work->tcon->share_conf, + KSMBD_SHARE_FLAG_PIPE)) { + ret = -EOPNOTSUPP; + goto out; + } + + /* RPC pipe handles are not in the regular file table. */ + if (has_file_id(id) && !pid) { + down_read(&work->sess->rpc_lock); + no_fileid_ioctl = + ksmbd_session_rpc_method(work->sess, id) != 0; + up_read(&work->sess->rpc_lock); + } + if (!no_fileid_ioctl) { + ret = -EBADF; + rsp->hdr.Status = STATUS_FILE_CLOSED; + goto out2; + } + break; default: break; } @@ -9790,6 +9810,8 @@ int smb2_ioctl(struct ksmbd_work *work) break; } case FSCTL_PIPE_TRANSCEIVE: + rsp->PersistentFileId = pid; + rsp->VolatileFileId = id; out_buf_len = min_t(u32, KSMBD_IPC_MAX_PAYLOAD, out_buf_len); nbytes = fsctl_pipe_transceive(work, id, out_buf_len, req, rsp); break; -- 2.55.0