From: Hauke Mehrtens Date: Sat, 7 Jan 2023 13:41:04 +0000 (+0100) Subject: ksmbd: Fix ZDI-CAN-18259 X-Git-Url: http://git.lede-project.org./?a=commitdiff_plain;h=76c67fcc66116381c69439f20159b636573080ba;p=openwrt%2Fstaging%2Fnbd.git ksmbd: Fix ZDI-CAN-18259 This fixes a security problem in ksmbd. It currently has the ZDI-CAN-18259 ID assigned, but no CVE yet. Backported from: https://github.com/cifsd-team/ksmbd/commit/8824b7af409f51f1316e92e9887c2fd48c0b26d6 https://github.com/cifsd-team/ksmbd/commit/cc4f3b5a6ab4693aba94a45cc073188df4d67175 Signed-off-by: Hauke Mehrtens --- diff --git a/package/kernel/ksmbd/Makefile b/package/kernel/ksmbd/Makefile index 86207508e5..8a0ebc54f8 100644 --- a/package/kernel/ksmbd/Makefile +++ b/package/kernel/ksmbd/Makefile @@ -2,7 +2,7 @@ include $(TOPDIR)/rules.mk PKG_NAME:=ksmbd PKG_VERSION:=3.4.6 -PKG_RELEASE:=$(AUTORELEASE) +PKG_RELEASE:=2 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz PKG_SOURCE_URL:=https://codeload.github.com/cifsd-team/cifsd/tar.gz/$(PKG_VERSION)? diff --git a/package/kernel/ksmbd/patches/10-ksmbd-check-nt_len-to-be-at-least-CIFS_ENCPWD_SIZE-i.patch b/package/kernel/ksmbd/patches/10-ksmbd-check-nt_len-to-be-at-least-CIFS_ENCPWD_SIZE-i.patch new file mode 100644 index 0000000000..198e752106 --- /dev/null +++ b/package/kernel/ksmbd/patches/10-ksmbd-check-nt_len-to-be-at-least-CIFS_ENCPWD_SIZE-i.patch @@ -0,0 +1,36 @@ +From 8824b7af409f51f1316e92e9887c2fd48c0b26d6 Mon Sep 17 00:00:00 2001 +From: William Liu +Date: Fri, 30 Dec 2022 09:13:35 +0900 +Subject: ksmbd: check nt_len to be at least CIFS_ENCPWD_SIZE in + ksmbd_decode_ntlmssp_auth_blob +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +"nt_len - CIFS_ENCPWD_SIZE" is passed directly from +ksmbd_decode_ntlmssp_auth_blob to ksmbd_auth_ntlmv2. Malicious requests +can set nt_len to less than CIFS_ENCPWD_SIZE, which results in a negative +number (or large unsigned value) used for a subsequent memcpy in +ksmbd_auth_ntlvm2 and can cause a panic. + +Fixes: e2f3448 ("cifsd: add server-side procedures for SMB3") +Cc: stable@vger.kernel.org +Signed-off-by: William Liu +Signed-off-by: Hrvoje Mišetić +Signed-off-by: Namjae Jeon +--- + auth.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/auth.c ++++ b/auth.c +@@ -583,7 +583,8 @@ int ksmbd_decode_ntlmssp_auth_blob(struc + dn_off = le32_to_cpu(authblob->DomainName.BufferOffset); + dn_len = le16_to_cpu(authblob->DomainName.Length); + +- if (blob_len < (u64)dn_off + dn_len || blob_len < (u64)nt_off + nt_len) ++ if (blob_len < (u64)dn_off + dn_len || blob_len < (u64)nt_off + nt_len || ++ nt_len < CIFS_ENCPWD_SIZE) + return -EINVAL; + + #ifdef CONFIG_SMB_INSECURE_SERVER diff --git a/package/kernel/ksmbd/patches/11-ksmbd-fix-infinite-loop-in-ksmbd_conn_handler_loop.patch b/package/kernel/ksmbd/patches/11-ksmbd-fix-infinite-loop-in-ksmbd_conn_handler_loop.patch new file mode 100644 index 0000000000..1b3c5c1aab --- /dev/null +++ b/package/kernel/ksmbd/patches/11-ksmbd-fix-infinite-loop-in-ksmbd_conn_handler_loop.patch @@ -0,0 +1,63 @@ +From cc4f3b5a6ab4693aba94a45cc073188df4d67175 Mon Sep 17 00:00:00 2001 +From: Namjae Jeon +Date: Mon, 26 Dec 2022 01:28:52 +0900 +Subject: ksmbd: fix infinite loop in ksmbd_conn_handler_loop() + +If kernel_recvmsg() return -EAGAIN in ksmbd_tcp_readv() and go round +again, It will cause infinite loop issue. And all threads from next +connections would be doing that. This patch add max retry count(2) to +avoid it. kernel_recvmsg() will wait during 7sec timeout and try to +retry two time if -EAGAIN is returned. And add flags of kvmalloc to +__GFP_NOWARN and __GFP_NORETRY to disconnect immediately without +retrying on memory alloation failure. + +Fixes: 0626e66 ("cifsd: add server handler for central processing and tranport layers") +Cc: stable@vger.kernel.org +Reported-by: zdi-disclosures@trendmicro.com # ZDI-CAN-18259 +Reviewed-by: Sergey Senozhatsky +Signed-off-by: Namjae Jeon +--- + connection.c | 7 +++++-- + transport_tcp.c | 5 ++++- + 2 files changed, 9 insertions(+), 3 deletions(-) + +--- a/connection.c ++++ b/connection.c +@@ -337,9 +337,12 @@ int ksmbd_conn_handler_loop(void *p) + + /* 4 for rfc1002 length field */ + size = pdu_size + 4; +- conn->request_buf = kvmalloc(size, GFP_KERNEL); ++ conn->request_buf = kvmalloc(size, ++ GFP_KERNEL | ++ __GFP_NOWARN | ++ __GFP_NORETRY); + if (!conn->request_buf) +- continue; ++ break; + + memcpy(conn->request_buf, hdr_buf, sizeof(hdr_buf)); + if (!ksmbd_smb_request(conn)) +--- a/transport_tcp.c ++++ b/transport_tcp.c +@@ -323,6 +323,7 @@ static int ksmbd_tcp_readv(struct tcp_tr + struct msghdr ksmbd_msg; + struct kvec *iov; + struct ksmbd_conn *conn = KSMBD_TRANS(t)->conn; ++ int max_retry = 2; + + iov = get_conn_iovec(t, nr_segs); + if (!iov) +@@ -349,9 +350,11 @@ static int ksmbd_tcp_readv(struct tcp_tr + } else if (conn->status == KSMBD_SESS_NEED_RECONNECT) { + total_read = -EAGAIN; + break; +- } else if (length == -ERESTARTSYS || length == -EAGAIN) { ++ } else if ((length == -ERESTARTSYS || length == -EAGAIN) && ++ max_retry) { + usleep_range(1000, 2000); + length = 0; ++ max_retry--; + continue; + } else if (length <= 0) { + total_read = -EAGAIN;