| Age | Commit message (Collapse) | Author | Files | Lines |
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
->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>
|
|
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>
|