summaryrefslogtreecommitdiff
path: root/fs/smb/server/smb2misc.c
AgeCommit message (Collapse)AuthorFilesLines
2026-08-17ksmbd: implement the command sequence windowNamjae Jeon1-0/+79
ksmbd tracked only credit counts (total_credits/outstanding_credits) and never validated the MessageId of an incoming request. As a result a request carrying a MessageId outside the granted range was accepted, a MessageId could be replayed, and a 64-bit sequence wrap was not detected. Maintain a command sequence window per connection: - [seq_low, seq_high) is the range of granted sequence numbers and seq_bitmap records which of them have been granted but not yet consumed. The window starts as { 0 } at connection setup. - smb2_set_rsp_credits() extends seq_high by the number of credits it grants (setting the corresponding bits), capped so the window never spans more than KSMBD_CMD_SEQ_WINDOW (== SMB2_MAX_CREDITS) sequence numbers. This implements the "limit the range of acceptable sequence numbers" allowance and keeps seq_bitmap usable as a ring. - smb2_check_sequence_number(), run for every SMB2 request from ksmbd_smb2_check_message(), verifies that the CreditCharge consecutive sequence numbers starting at MessageId lie within the window and have not already been consumed, then removes them and slides seq_low forward. CANCEL consumes nothing. A violation (out of window, replay, or wrap) tears the connection down. The legacy SMB1 multi-protocol negotiate occupies sequence number 0 but does not pass through ksmbd_smb2_check_message(), so it consumes that sequence number explicitly; otherwise seq_low would stay pinned at 0 after the upgrade to SMB2 and eventually stall credit grants. For an in-order client seq_high - seq_low equals total_credits, so the window-room cap never reduces the number of credits granted. it only engages for a client that withholds low sequence numbers. init_smb2_max_credits() now clamps the configured maximum to SMB2_MAX_CREDITS so the window (and its bitmap) can always represent every outstanding sequence number. Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
2026-07-16ksmbd: validate compound request size before reading StructureSize2Xiang Mei (Microsoft)1-0/+5
When ksmbd validates a compound (chained) SMB2 request, ksmbd_smb2_check_message() reads pdu->StructureSize2 without first checking that the compound element is large enough to contain it. StructureSize2 is a 2-byte field at offset 64 (__SMB2_HEADER_STRUCTURE_SIZE) from the start of each element. The compound-walking logic only guarantees that a full 64-byte SMB2 header is present for the trailing element: when NextCommand is 0, len is reduced to the number of bytes remaining after next_smb2_rcv_hdr_off. A remote client can craft a compound request whose last element has exactly 64 bytes, so the 2-byte StructureSize2 read at offset 64 extends one byte past the receive buffer, producing a slab-out-of-bounds read. BUG: KASAN: slab-out-of-bounds in ksmbd_smb2_check_message (fs/smb/server/smb2misc.c:402) Read of size 2 at addr ffff888012ae31ac by task kworker/0:1/14 The buggy address is located 172 bytes inside of allocated 173-byte region Workqueue: ksmbd-io handle_ksmbd_work Call Trace: ... kasan_report (mm/kasan/report.c:595) ksmbd_smb2_check_message (fs/smb/server/smb2misc.c:402) handle_ksmbd_work (fs/smb/server/server.c:119) process_one_work (kernel/workqueue.c:3314) worker_thread (kernel/workqueue.c:3397) kthread (kernel/kthread.c:436) ret_from_fork (arch/x86/kernel/process.c:158) ret_from_fork_asm (arch/x86/entry/entry_64.S:245) Reject any compound element that is too small to hold StructureSize2 before dereferencing it. Fixes: e2f34481b24d ("cifsd: add server-side procedures for SMB3") Reported-by: AutonomousCodeSecurity@microsoft.com Signed-off-by: Xiang Mei (Microsoft) <xmei5@asu.edu> Acked-by: Namjae Jeon <linkinjeon@kernel.org> Signed-off-by: Steve French <stfrench@microsoft.com>
2026-06-30ksmbd: fix outstanding credit leak on abort and error pathsNamjae Jeon1-3/+6
smb2_validate_credit_charge() adds the request's CreditCharge to conn->outstanding_credits when an SMB2 PDU is received, and smb2_set_rsp_credits() subtracts it again when the response is built. However smb2_set_rsp_credits() only runs on the normal response path: - __process_request() returning SERVER_HANDLER_ABORT (unimplemented command, command index out of range, signature check failure, or a handler that sets send_no_response such as a cancelled blocking lock) breaks out of the processing loop before set_rsp_credits() is called; - smb2_set_rsp_credits() itself returns early with -EINVAL (total credit overflow or insufficient credits) before the subtraction. On all of these paths the charge added at receive time is never returned, so conn->outstanding_credits only grows. Because a client can repeatedly trigger them (e.g. by sending unimplemented commands or by issuing and cancelling blocking locks), outstanding_credits eventually reaches total_credits and smb2_validate_credit_charge() then rejects every subsequent request, wedging the connection. Record the charge that was added in work->credit_charge and release any charge still pending at the single send. exit point of __handle_ksmbd_work(), which all abort and error paths fall through to. smb2_set_rsp_credits() clears work->credit_charge once it has returned the charge so the response path is unchanged and the credit is never released twice. Paths that never charged a credit (no multi-credit support, validation failure) leave work->credit_charge at zero and are unaffected. Signed-off-by: Namjae Jeon <linkinjeon@kernel.org> Signed-off-by: Steve French <stfrench@microsoft.com>
2026-06-30ksmbd: fix credit charge calculation for SMB2 QUERY_INFONamjae Jeon1-2/+7
smb2_validate_credit_charge() computes the credit charge a request is allowed to consume from the payload size: CreditCharge = (max(SendPayloadSize, ResponsePayloadSize) - 1)/65536 + 1 For SMB2 QUERY_INFO, the server must validate CreditCharge based on the *maximum* of InputBufferLength and OutputBufferLength. ksmbd instead summed the two lengths, which overestimates the required charge. As a result a single-credit QUERY_INFO whose InputBufferLength and OutputBufferLength each fit in 64KB but whose sum exceeds 64KB is rejected with STATUS_INVALID_PARAMETER, even though it is a valid request. IOCTL already uses max() of the request and response sizes; make QUERY_INFO consistent by feeding InputBufferLength as the request length and OutputBufferLength as the expected response length so that smb2_validate_credit_charge() takes their maximum. Signed-off-by: Namjae Jeon <linkinjeon@kernel.org> Signed-off-by: Steve French <stfrench@microsoft.com>
2025-12-09smb/server: remove unused nterr.hChenXiaoSong1-1/+0
KSMBD does not use these NT error code definitions. Instead, it uses the SMB2 status code definitions defined in common/smb2status.h. By the way, server/nterr.h contains the following additional definitions compared to client/nterr.h: - NT_STATUS_PENDING - NT_STATUS_INVALID_LOCK_RANGE - NT_STATUS_NETWORK_SESSION_EXPIRED - NT_STATUS_NO_PREAUTH_INTEGRITY_HASH_OVERLAP We can add them to client/nterr.h in the next patch. Signed-off-by: ChenXiaoSong <chenxiaosong@kylinos.cn> Acked-by: Namjae Jeon <linkinjeon@kernel.org> Signed-off-by: Steve French <stfrench@microsoft.com>
2025-11-30smb: move smb_version_values to common/smbglob.hZhangGuoDong1-1/+1
Merge the struct members of the server and the client: - req_capabilities: from client - header_preamble_size: from client - cap_unicode: from client - capabilities: from server, rename to req_capabilities - max_read_size: from server - max_write_size: from server - max_trans_size: from server - max_credits: from server - create_durable_size: from server - create_durable_v2_size: from server - create_mxac_size: from server - create_disk_id_size: from server - create_posix_size: from server Then move duplicate definitions to common header file. Co-developed-by: ChenXiaoSong <chenxiaosong@kylinos.cn> Signed-off-by: ChenXiaoSong <chenxiaosong@kylinos.cn> Signed-off-by: ZhangGuoDong <zhangguodong@kylinos.cn> Acked-by: Namjae Jeon <linkinjeon@kernel.org> Signed-off-by: Steve French <stfrench@microsoft.com>
2024-09-15smb: move SMB2 Status code to common header fileChenXiaoSong1-1/+1
There are only 4 different definitions between the client and server: - STATUS_SERVER_UNAVAILABLE: from client/smb2status.h - STATUS_FILE_NOT_AVAILABLE: from client/smb2status.h - STATUS_NO_PREAUTH_INTEGRITY_HASH_OVERLAP: from server/smbstatus.h - STATUS_INVALID_LOCK_RANGE: from server/smbstatus.h Rename client/smb2status.h to common/smb2status.h, and merge the 2 different definitions of server to common header file. Signed-off-by: ChenXiaoSong <chenxiaosong@kylinos.cn> Acked-by: Namjae Jeon <linkinjeon@kernel.org> Signed-off-by: Steve French <stfrench@microsoft.com>
2024-03-18ksmbd: fix potencial out-of-bounds when buffer offset is invalidNamjae Jeon1-7/+16
I found potencial out-of-bounds when buffer offset fields of a few requests is invalid. This patch set the minimum value of buffer offset field to ->Buffer offset to validate buffer length. Cc: stable@vger.kernel.org Signed-off-by: Namjae Jeon <linkinjeon@kernel.org> Signed-off-by: Steve French <stfrench@microsoft.com>
2024-03-17ksmbd: fix slab-out-of-bounds in smb_strndup_from_utf16()Namjae Jeon1-1/+4
If ->NameOffset of smb2_create_req is smaller than Buffer offset of smb2_create_req, slab-out-of-bounds read can happen from smb2_open. This patch set the minimum value of the name offset to the buffer offset to validate name length of smb2_create_req(). Cc: stable@vger.kernel.org Reported-by: Xuanzhe Yu <yuxuanzhe@outlook.com> Signed-off-by: Namjae Jeon <linkinjeon@kernel.org> Signed-off-by: Steve French <stfrench@microsoft.com>
2023-12-27ksmbd: fix slab-out-of-bounds in smb_strndup_from_utf16()Namjae Jeon1-3/+12
If ->NameOffset/Length is bigger than ->CreateContextsOffset/Length, ksmbd_check_message doesn't validate request buffer it correctly. So slab-out-of-bounds warning from calling smb_strndup_from_utf16() in smb2_open() could happen. If ->NameLength is non-zero, Set the larger of the two sums (Name and CreateContext size) as the offset and length of the data area. Reported-by: Yang Chaoming <lometsj@live.com> Cc: stable@vger.kernel.org Signed-off-by: Namjae Jeon <linkinjeon@kernel.org> Signed-off-by: Steve French <stfrench@microsoft.com>
2023-09-21ksmbd: return invalid parameter error response if smb2 request is invalidNamjae Jeon1-3/+1
If smb2 request from client is invalid, The following kernel oops could happen. The patch e2b76ab8b5c9: "ksmbd: add support for read compound" leads this issue. When request is invalid, It doesn't set anything in the response buffer. This patch add missing set invalid parameter error response. [ 673.085542] ksmbd: cli req too short, len 184 not 142. cmd:5 mid:109 [ 673.085580] BUG: kernel NULL pointer dereference, address: 0000000000000000 [ 673.085591] #PF: supervisor read access in kernel mode [ 673.085600] #PF: error_code(0x0000) - not-present page [ 673.085608] PGD 0 P4D 0 [ 673.085620] Oops: 0000 [#1] PREEMPT SMP NOPTI [ 673.085631] CPU: 3 PID: 1039 Comm: kworker/3:0 Not tainted 6.6.0-rc2-tmt #16 [ 673.085643] Hardware name: AZW U59/U59, BIOS JTKT001 05/05/2022 [ 673.085651] Workqueue: ksmbd-io handle_ksmbd_work [ksmbd] [ 673.085719] RIP: 0010:ksmbd_conn_write+0x68/0xc0 [ksmbd] [ 673.085808] RAX: 0000000000000000 RBX: ffff88811ade4f00 RCX: 0000000000000000 [ 673.085817] RDX: 0000000000000000 RSI: ffff88810c2a9780 RDI: ffff88810c2a9ac0 [ 673.085826] RBP: ffffc900005e3e00 R08: 0000000000000000 R09: 0000000000000000 [ 673.085834] R10: ffffffffa3168160 R11: 63203a64626d736b R12: ffff8881057c8800 [ 673.085842] R13: ffff8881057c8820 R14: ffff8882781b2380 R15: ffff8881057c8800 [ 673.085852] FS: 0000000000000000(0000) GS:ffff888278180000(0000) knlGS:0000000000000000 [ 673.085864] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 673.085872] CR2: 0000000000000000 CR3: 000000015b63c000 CR4: 0000000000350ee0 [ 673.085883] Call Trace: [ 673.085890] <TASK> [ 673.085900] ? show_regs+0x6a/0x80 [ 673.085916] ? __die+0x25/0x70 [ 673.085926] ? page_fault_oops+0x154/0x4b0 [ 673.085938] ? tick_nohz_tick_stopped+0x18/0x50 [ 673.085954] ? __irq_work_queue_local+0xba/0x140 [ 673.085967] ? do_user_addr_fault+0x30f/0x6c0 [ 673.085979] ? exc_page_fault+0x79/0x180 [ 673.085992] ? asm_exc_page_fault+0x27/0x30 [ 673.086009] ? ksmbd_conn_write+0x68/0xc0 [ksmbd] [ 673.086067] ? ksmbd_conn_write+0x46/0xc0 [ksmbd] [ 673.086123] handle_ksmbd_work+0x28d/0x4b0 [ksmbd] [ 673.086177] process_one_work+0x178/0x350 [ 673.086193] ? __pfx_worker_thread+0x10/0x10 [ 673.086202] worker_thread+0x2f3/0x420 [ 673.086210] ? _raw_spin_unlock_irqrestore+0x27/0x50 [ 673.086222] ? __pfx_worker_thread+0x10/0x10 [ 673.086230] kthread+0x103/0x140 [ 673.086242] ? __pfx_kthread+0x10/0x10 [ 673.086253] ret_from_fork+0x39/0x60 [ 673.086263] ? __pfx_kthread+0x10/0x10 [ 673.086274] ret_from_fork_asm+0x1b/0x30 Fixes: e2b76ab8b5c9 ("ksmbd: add support for read compound") Reported-by: Tom Talpey <tom@talpey.com> Signed-off-by: Namjae Jeon <linkinjeon@kernel.org> Signed-off-by: Steve French <stfrench@microsoft.com>
2023-08-05ksmbd: validate command request sizeLong Li1-5/+5
In commit 2b9b8f3b68ed ("ksmbd: validate command payload size"), except for SMB2_OPLOCK_BREAK_HE command, the request size of other commands is not checked, it's not expected. Fix it by add check for request size of other commands. Cc: stable@vger.kernel.org Fixes: 2b9b8f3b68ed ("ksmbd: validate command payload size") Acked-by: Namjae Jeon <linkinjeon@kernel.org> Signed-off-by: Long Li <leo.lilong@huawei.com> Signed-off-by: Steve French <stfrench@microsoft.com>
2023-06-16ksmbd: fix out-of-bound read in smb2_writeNamjae Jeon1-3/+9
ksmbd_smb2_check_message doesn't validate hdr->NextCommand. If ->NextCommand is bigger than Offset + Length of smb2 write, It will allow oversized smb2 write length. It will cause OOB read in smb2_write. Cc: stable@vger.kernel.org Reported-by: zdi-disclosures@trendmicro.com # ZDI-CAN-21164 Signed-off-by: Namjae Jeon <linkinjeon@kernel.org> Signed-off-by: Steve French <stfrench@microsoft.com>
2023-06-16ksmbd: validate command payload sizeNamjae Jeon1-11/+12
->StructureSize2 indicates command payload size. ksmbd should validate this size with rfc1002 length before accessing it. This patch remove unneeded check and add the validation for this. [ 8.912583] BUG: KASAN: slab-out-of-bounds in ksmbd_smb2_check_message+0x12a/0xc50 [ 8.913051] Read of size 2 at addr ffff88800ac7d92c by task kworker/0:0/7 ... [ 8.914967] Call Trace: [ 8.915126] <TASK> [ 8.915267] dump_stack_lvl+0x33/0x50 [ 8.915506] print_report+0xcc/0x620 [ 8.916558] kasan_report+0xae/0xe0 [ 8.917080] kasan_check_range+0x35/0x1b0 [ 8.917334] ksmbd_smb2_check_message+0x12a/0xc50 [ 8.917935] ksmbd_verify_smb_message+0xae/0xd0 [ 8.918223] handle_ksmbd_work+0x192/0x820 [ 8.918478] process_one_work+0x419/0x760 [ 8.918727] worker_thread+0x2a2/0x6f0 [ 8.919222] kthread+0x187/0x1d0 [ 8.919723] ret_from_fork+0x1f/0x30 [ 8.919954] </TASK> Cc: stable@vger.kernel.org Reported-by: Chih-Yen Chang <cc85nod@gmail.com> Signed-off-by: Namjae Jeon <linkinjeon@kernel.org> Signed-off-by: Steve French <stfrench@microsoft.com>
2023-05-24smb: move client and server files to common directory fs/smbSteve French1-0/+447
Move CIFS/SMB3 related client and server files (cifs.ko and ksmbd.ko and helper modules) to new fs/smb subdirectory: fs/cifs --> fs/smb/client fs/ksmbd --> fs/smb/server fs/smbfs_common --> fs/smb/common Suggested-by: Linus Torvalds <torvalds@linux-foundation.org> Acked-by: Namjae Jeon <linkinjeon@kernel.org> Signed-off-by: Steve French <stfrench@microsoft.com>