* FAILED: patch "[PATCH] ksmbd: prevent out-of-bounds reads in share config responses" failed to apply to 6.1-stable tree
@ 2026-09-14 11:03 gregkh
2026-09-14 15:30 ` [PATCH 6.1.y 1/5] ksmbd: Use struct_size() to improve smb_direct_rdma_xmit() Sasha Levin
0 siblings, 1 reply; 6+ messages in thread
From: gregkh @ 2026-09-14 11:03 UTC (permalink / raw)
To: linkinjeon, farhad.alemi, kpskanna1915; +Cc: stable
The patch below does not apply to the 6.1-stable tree.
If someone wants it applied there, or to any other stable or longterm
tree, then please email the backport, including the original git commit
id to <stable@vger.kernel.org>.
To reproduce the conflict and resubmit, you may use the following commands:
git fetch https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/ linux-6.1.y
git checkout FETCH_HEAD
git cherry-pick -x f25e93768fcc5d8287e50b1ec52a42e4c276df34
# <resolve conflicts, build, test, etc.>
git commit -s
git send-email --to '<stable@vger.kernel.org>' --in-reply-to '2026091412-bottom-cadillac-a0fb@gregkh' --subject-prefix 'PATCH 6.1.y' 'HEAD^..'
Possible dependencies:
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From f25e93768fcc5d8287e50b1ec52a42e4c276df34 Mon Sep 17 00:00:00 2001
From: Namjae Jeon <linkinjeon@kernel.org>
Date: Fri, 28 Aug 2026 08:39:57 +0900
Subject: [PATCH] ksmbd: prevent out-of-bounds reads in share config responses
Validate IPC share configuration payload sizes before consuming
variable-length fields. Bound veto list parsing and account for
the separator byte when deriving the path length.
Fixes: a677ebd8ca2f ("ksmbd: validate payload size in ipc response")
Reported-by: Kanishka De Silva <kpskanna1915@gmail.com>
Reported-by: Farhad Alemi <farhad.alemi@berkeley.edu>
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
diff --git a/fs/smb/server/mgmt/share_config.c b/fs/smb/server/mgmt/share_config.c
index b2d9580bddc6..cc9f18ede80d 100644
--- a/fs/smb/server/mgmt/share_config.c
+++ b/fs/smb/server/mgmt/share_config.c
@@ -146,9 +146,9 @@ static struct ksmbd_share_config *__share_lookup(const char *name)
static int parse_veto_list(struct ksmbd_share_config *share,
char *veto_list,
- int veto_list_sz)
+ size_t veto_list_sz)
{
- int sz = 0;
+ size_t sz;
if (!veto_list_sz)
return 0;
@@ -156,7 +156,7 @@ static int parse_veto_list(struct ksmbd_share_config *share,
while (veto_list_sz > 0) {
struct ksmbd_veto_pattern *p;
- sz = strlen(veto_list);
+ sz = strnlen(veto_list, veto_list_sz);
if (!sz)
break;
@@ -164,7 +164,7 @@ static int parse_veto_list(struct ksmbd_share_config *share,
if (!p)
return -ENOMEM;
- p->pattern = kstrdup(veto_list, KSMBD_DEFAULT_GFP);
+ p->pattern = kstrndup(veto_list, sz, KSMBD_DEFAULT_GFP);
if (!p->pattern) {
kfree(p);
return -ENOMEM;
@@ -172,6 +172,9 @@ static int parse_veto_list(struct ksmbd_share_config *share,
list_add(&p->list, &share->veto_list);
+ if (sz == veto_list_sz)
+ break;
+
veto_list += sz + 1;
veto_list_sz -= (sz + 1);
}
@@ -224,17 +227,28 @@ static struct ksmbd_share_config *share_config_request(struct ksmbd_work *work,
}
if (!test_share_config_flag(share, KSMBD_SHARE_FLAG_PIPE)) {
- int path_len = PATH_MAX;
+ size_t path_len;
- if (resp->payload_sz)
- path_len = resp->payload_sz - resp->veto_list_sz;
-
- share->path = kstrndup(ksmbd_share_config_path(resp), path_len,
- KSMBD_DEFAULT_GFP);
- if (!share->path) {
- ret = -ENOMEM;
+ if (resp->payload_sz <= resp->veto_list_sz) {
+ ret = -EINVAL;
} else {
- ret = 0;
+ path_len = resp->payload_sz - resp->veto_list_sz;
+ if (resp->veto_list_sz)
+ path_len--;
+
+ if (!path_len) {
+ ret = -EINVAL;
+ } else {
+ share->path = kstrndup(
+ ksmbd_share_config_path(resp),
+ path_len, KSMBD_DEFAULT_GFP);
+ if (!share->path)
+ ret = -ENOMEM;
+ else
+ ret = 0;
+ }
+ }
+ if (share->path) {
share->path_sz = strlen(share->path);
while (share->path_sz > 1 &&
share->path[share->path_sz - 1] == '/')
diff --git a/fs/smb/server/transport_ipc.c b/fs/smb/server/transport_ipc.c
index 4b0b572a3e1b..e550aa41ad2c 100644
--- a/fs/smb/server/transport_ipc.c
+++ b/fs/smb/server/transport_ipc.c
@@ -532,14 +532,21 @@ static int ipc_validate_msg(struct ipc_msg_table_entry *entry)
if (entry->msg_sz < sizeof(struct ksmbd_share_config_response))
return -EINVAL;
- if (resp->payload_sz) {
- if (resp->payload_sz < resp->veto_list_sz)
- return -EINVAL;
+ if (strnlen(resp->share_name, sizeof(resp->share_name)) ==
+ sizeof(resp->share_name))
+ return -EINVAL;
- if (check_add_overflow(sizeof(struct ksmbd_share_config_response),
- resp->payload_sz, &msg_sz))
- return -EINVAL;
- }
+ if (resp->veto_list_sz > resp->payload_sz)
+ return -EINVAL;
+
+ if (resp->flags != KSMBD_SHARE_FLAG_INVALID &&
+ !(resp->flags & KSMBD_SHARE_FLAG_PIPE) &&
+ resp->payload_sz <= resp->veto_list_sz)
+ return -EINVAL;
+
+ if (check_add_overflow(sizeof(struct ksmbd_share_config_response),
+ resp->payload_sz, &msg_sz))
+ return -EINVAL;
break;
}
case KSMBD_EVENT_LOGIN_REQUEST_EXT:
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH 6.1.y 1/5] ksmbd: Use struct_size() to improve smb_direct_rdma_xmit()
2026-09-14 11:03 FAILED: patch "[PATCH] ksmbd: prevent out-of-bounds reads in share config responses" failed to apply to 6.1-stable tree gregkh
@ 2026-09-14 15:30 ` Sasha Levin
2026-09-14 15:30 ` [PATCH 6.1.y 2/5] ksmbd: use __GFP_RETRY_MAYFAIL Sasha Levin
` (3 more replies)
0 siblings, 4 replies; 6+ messages in thread
From: Sasha Levin @ 2026-09-14 15:30 UTC (permalink / raw)
To: stable; +Cc: Thorsten Blum, Namjae Jeon, Steve French, Sasha Levin
From: Thorsten Blum <thorsten.blum@linux.dev>
[ Upstream commit 9c383396362a4d1db99ed5240f4708d443361ef3 ]
Use struct_size() to calculate the number of bytes to allocate for a
new message.
Signed-off-by: Thorsten Blum <thorsten.blum@linux.dev>
Acked-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Steve French <stfrench@microsoft.com>
Stable-dep-of: f25e93768fcc ("ksmbd: prevent out-of-bounds reads in share config responses")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/smb/server/transport_rdma.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/fs/smb/server/transport_rdma.c b/fs/smb/server/transport_rdma.c
index 1290c0fa7dd18..6a58675deb5a8 100644
--- a/fs/smb/server/transport_rdma.c
+++ b/fs/smb/server/transport_rdma.c
@@ -1397,8 +1397,8 @@ static int smb_direct_rdma_xmit(struct smb_direct_transport *t,
/* build rdma_rw_ctx for each descriptor */
desc_buf = buf;
for (i = 0; i < desc_num; i++) {
- msg = kzalloc(offsetof(struct smb_direct_rdma_rw_msg, sg_list) +
- sizeof(struct scatterlist) * SG_CHUNK_SIZE, GFP_KERNEL);
+ msg = kzalloc(struct_size(msg, sg_list, SG_CHUNK_SIZE),
+ GFP_KERNEL);
if (!msg) {
ret = -ENOMEM;
goto out;
--
2.53.0
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH 6.1.y 2/5] ksmbd: use __GFP_RETRY_MAYFAIL
2026-09-14 15:30 ` [PATCH 6.1.y 1/5] ksmbd: Use struct_size() to improve smb_direct_rdma_xmit() Sasha Levin
@ 2026-09-14 15:30 ` Sasha Levin
2026-09-14 15:30 ` [PATCH 6.1.y 3/5] ksmbd: validate response sizes in ipc_validate_msg() Sasha Levin
` (2 subsequent siblings)
3 siblings, 0 replies; 6+ messages in thread
From: Sasha Levin @ 2026-09-14 15:30 UTC (permalink / raw)
To: stable; +Cc: Namjae Jeon, Steve French, Sasha Levin
From: Namjae Jeon <linkinjeon@kernel.org>
[ Upstream commit 0066f623bce8f98b69b752ee03d46a5047c281b8 ]
Prefer to report ENOMEM rather than incur the oom for allocations in
ksmbd. __GFP_NORETRY could not achieve that, It would fail the allocations
just too easily. __GFP_RETRY_MAYFAIL will keep retrying the allocation
until there is no more progress and fail the allocation instead go OOM
and let the caller to deal with it.
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Steve French <stfrench@microsoft.com>
[ Stable dependency adaptation for f25e93768fcc5d8287e50b1ec52a42e4c276df34:
Keep the default allocation mask and its uses in share_config.c and
transport_ipc.c. Drop unrelated allocation conversions, including the
hunks that require IDA, supplementary-group, RPC, interface, or durable
handle code not present in this stable tree.
Prepare the existing share-config path for the target by retaining path
allocation failures and only parsing the veto list on success, as in
a74668eb2c0b. Convert the existing IPC validator to a switch for its three
supported request types; add the share-response header-length check and
checked size addition needed by the target, from e9b33376bd07 and
d6a6aa81eac2. Do not introduce extended-login support or new functions. ]
[ sashal: Reduced backport -- upstream 0066f623bce8f touches 24 file(s), this
backport carries 3. Not backported here:
fs/smb/server/asn1.c
fs/smb/server/auth.c
fs/smb/server/connection.c
fs/smb/server/crypto_ctx.c
fs/smb/server/ksmbd_work.c
fs/smb/server/mgmt/ksmbd_ida.c
fs/smb/server/mgmt/tree_connect.c
fs/smb/server/mgmt/user_config.c
... and 13 more
This note is generated from the file lists only; see the resolution record
for the reasoning. ]
Stable-dep-of: f25e93768fcc ("ksmbd: prevent out-of-bounds reads in share config responses")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/smb/server/glob.h | 2 ++
fs/smb/server/mgmt/share_config.c | 22 +++++++++++++---------
fs/smb/server/transport_ipc.c | 31 +++++++++++++++++++++++--------
3 files changed, 38 insertions(+), 17 deletions(-)
diff --git a/fs/smb/server/glob.h b/fs/smb/server/glob.h
index 5b8f3e0ebdb36..3ce12b60e46fe 100644
--- a/fs/smb/server/glob.h
+++ b/fs/smb/server/glob.h
@@ -46,4 +46,6 @@ extern int ksmbd_debug_types;
#define UNICODE_LEN(x) ((x) * 2)
+#define KSMBD_DEFAULT_GFP (GFP_KERNEL | __GFP_RETRY_MAYFAIL)
+
#endif /* __KSMBD_GLOB_H */
diff --git a/fs/smb/server/mgmt/share_config.c b/fs/smb/server/mgmt/share_config.c
index d8d03070ae44b..7f519a280188a 100644
--- a/fs/smb/server/mgmt/share_config.c
+++ b/fs/smb/server/mgmt/share_config.c
@@ -102,11 +102,11 @@ static int parse_veto_list(struct ksmbd_share_config *share,
if (!sz)
break;
- p = kzalloc(sizeof(struct ksmbd_veto_pattern), GFP_KERNEL);
+ p = kzalloc(sizeof(struct ksmbd_veto_pattern), KSMBD_DEFAULT_GFP);
if (!p)
return -ENOMEM;
- p->pattern = kstrdup(veto_list, GFP_KERNEL);
+ p->pattern = kstrdup(veto_list, KSMBD_DEFAULT_GFP);
if (!p->pattern) {
kfree(p);
return -ENOMEM;
@@ -150,14 +150,14 @@ static struct ksmbd_share_config *share_config_request(struct ksmbd_work *work,
goto out;
}
- share = kzalloc(sizeof(struct ksmbd_share_config), GFP_KERNEL);
+ share = kzalloc(sizeof(struct ksmbd_share_config), KSMBD_DEFAULT_GFP);
if (!share)
goto out;
share->flags = resp->flags;
atomic_set(&share->refcount, 1);
INIT_LIST_HEAD(&share->veto_list);
- share->name = kstrdup(name, GFP_KERNEL);
+ share->name = kstrdup(name, KSMBD_DEFAULT_GFP);
if (!test_share_config_flag(share, KSMBD_SHARE_FLAG_PIPE)) {
int path_len = PATH_MAX;
@@ -166,8 +166,11 @@ static struct ksmbd_share_config *share_config_request(struct ksmbd_work *work,
path_len = resp->payload_sz - resp->veto_list_sz;
share->path = kstrndup(ksmbd_share_config_path(resp), path_len,
- GFP_KERNEL);
- if (share->path) {
+ KSMBD_DEFAULT_GFP);
+ if (!share->path) {
+ ret = -ENOMEM;
+ } else {
+ ret = 0;
share->path_sz = strlen(share->path);
while (share->path_sz > 1 &&
share->path[share->path_sz - 1] == '/')
@@ -179,9 +182,10 @@ static struct ksmbd_share_config *share_config_request(struct ksmbd_work *work,
share->force_directory_mode = resp->force_directory_mode;
share->force_uid = resp->force_uid;
share->force_gid = resp->force_gid;
- ret = parse_veto_list(share,
- KSMBD_SHARE_CONFIG_VETO_LIST(resp),
- resp->veto_list_sz);
+ if (!ret)
+ ret = parse_veto_list(share,
+ KSMBD_SHARE_CONFIG_VETO_LIST(resp),
+ resp->veto_list_sz);
if (!ret && share->path) {
if (__ksmbd_override_fsids(work, share)) {
kill_share(share);
diff --git a/fs/smb/server/transport_ipc.c b/fs/smb/server/transport_ipc.c
index ed423d0ca99d6..5bf29431b4e48 100644
--- a/fs/smb/server/transport_ipc.c
+++ b/fs/smb/server/transport_ipc.c
@@ -13,6 +13,7 @@
#include <net/genetlink.h>
#include <linux/socket.h>
#include <linux/workqueue.h>
+#include <linux/overflow.h>
#include "vfs_cache.h"
#include "transport_ipc.h"
@@ -230,7 +231,7 @@ static struct ksmbd_ipc_msg *ipc_msg_alloc(size_t sz)
struct ksmbd_ipc_msg *msg;
size_t msg_sz = sz + sizeof(struct ksmbd_ipc_msg);
- msg = kvzalloc(msg_sz, GFP_KERNEL);
+ msg = kvzalloc(msg_sz, KSMBD_DEFAULT_GFP);
if (msg)
msg->sz = sz;
return msg;
@@ -276,7 +277,7 @@ static int handle_response(int type, void *payload, size_t sz)
continue;
}
- entry->response = kvzalloc(sz, GFP_KERNEL);
+ entry->response = kvzalloc(sz, KSMBD_DEFAULT_GFP);
if (!entry->response) {
ret = -ENOMEM;
break;
@@ -446,7 +447,7 @@ static int ipc_msg_send(struct ksmbd_ipc_msg *msg)
if (!ksmbd_tools_pid)
return ret;
- skb = genlmsg_new(msg->sz, GFP_KERNEL);
+ skb = genlmsg_new(msg->sz, KSMBD_DEFAULT_GFP);
if (!skb)
return -ENOMEM;
@@ -475,25 +476,39 @@ static int ipc_validate_msg(struct ipc_msg_table_entry *entry)
{
unsigned int msg_sz = entry->msg_sz;
- if (entry->type == KSMBD_EVENT_RPC_REQUEST) {
+ switch (entry->type) {
+ case KSMBD_EVENT_RPC_REQUEST:
+ {
struct ksmbd_rpc_command *resp = entry->response;
msg_sz = sizeof(struct ksmbd_rpc_command) + resp->payload_sz;
- } else if (entry->type == KSMBD_EVENT_SPNEGO_AUTHEN_REQUEST) {
+ break;
+ }
+ case KSMBD_EVENT_SPNEGO_AUTHEN_REQUEST:
+ {
struct ksmbd_spnego_authen_response *resp = entry->response;
msg_sz = sizeof(struct ksmbd_spnego_authen_response) +
resp->session_key_len + resp->spnego_blob_len;
- } else if (entry->type == KSMBD_EVENT_SHARE_CONFIG_REQUEST) {
+ break;
+ }
+ case KSMBD_EVENT_SHARE_CONFIG_REQUEST:
+ {
struct ksmbd_share_config_response *resp = entry->response;
+ if (entry->msg_sz < sizeof(struct ksmbd_share_config_response))
+ return -EINVAL;
+
if (resp->payload_sz) {
if (resp->payload_sz < resp->veto_list_sz)
return -EINVAL;
- msg_sz = sizeof(struct ksmbd_share_config_response) +
- resp->payload_sz;
+ if (check_add_overflow(sizeof(struct ksmbd_share_config_response),
+ resp->payload_sz, &msg_sz))
+ return -EINVAL;
}
+ break;
+ }
}
return entry->msg_sz != msg_sz ? -EINVAL : 0;
--
2.53.0
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH 6.1.y 3/5] ksmbd: validate response sizes in ipc_validate_msg()
2026-09-14 15:30 ` [PATCH 6.1.y 1/5] ksmbd: Use struct_size() to improve smb_direct_rdma_xmit() Sasha Levin
2026-09-14 15:30 ` [PATCH 6.1.y 2/5] ksmbd: use __GFP_RETRY_MAYFAIL Sasha Levin
@ 2026-09-14 15:30 ` Sasha Levin
2026-09-14 15:30 ` [PATCH 6.1.y 4/5] ksmbd: validate ipc response length before dereferencing its fields Sasha Levin
2026-09-14 15:30 ` [PATCH 6.1.y 5/5] ksmbd: prevent out-of-bounds reads in share config responses Sasha Levin
3 siblings, 0 replies; 6+ messages in thread
From: Sasha Levin @ 2026-09-14 15:30 UTC (permalink / raw)
To: stable; +Cc: Michael Bommarito, Namjae Jeon, Steve French, Sasha Levin
From: Michael Bommarito <michael.bommarito@gmail.com>
[ Upstream commit d6a6aa81eac2c9bff66dc6e191179cb69a14426b ]
ipc_validate_msg() computes the expected message size for each
response type by adding (or multiplying) attacker-controlled fields
from the daemon response to a fixed struct size in unsigned int
arithmetic. Three cases can overflow:
KSMBD_EVENT_RPC_REQUEST:
msg_sz = sizeof(struct ksmbd_rpc_command) + resp->payload_sz;
KSMBD_EVENT_SHARE_CONFIG_REQUEST:
msg_sz = sizeof(struct ksmbd_share_config_response) +
resp->payload_sz;
KSMBD_EVENT_LOGIN_REQUEST_EXT:
msg_sz = sizeof(struct ksmbd_login_response_ext) +
resp->ngroups * sizeof(gid_t);
resp->payload_sz is __u32 and resp->ngroups is __s32. Each addition
can wrap in unsigned int; the multiplication by sizeof(gid_t) mixes
signed and size_t, so a negative ngroups is converted to SIZE_MAX
before the multiply. A wrapped value of msg_sz that happens to
equal entry->msg_sz bypasses the size check on the next line, and
downstream consumers (smb2pdu.c:6742 memcpy using rpc_resp->payload_sz,
kmemdup in ksmbd_alloc_user using resp_ext->ngroups) then trust the
unverified length.
Use check_add_overflow() on the RPC_REQUEST and SHARE_CONFIG_REQUEST
paths to detect integer overflow without constraining functional
payload size; userspace ksmbd-tools grows NDR responses in 4096-byte
chunks for calls like NetShareEnumAll, so a hard transport cap is
unworkable on the response side. For LOGIN_REQUEST_EXT, reject
resp->ngroups outside the signed [0, NGROUPS_MAX] range up front and
report the error from ipc_validate_msg() so it fires at the IPC
boundary; with that bound the subsequent multiplication and addition
stay well below UINT_MAX. The now-redundant ngroups check and
pr_err in ksmbd_alloc_user() are removed.
This is the response-side analogue of aab98e2dbd64 ("ksmbd: fix
integer overflows on 32 bit systems"), which hardened the request
side.
Fixes: 0626e6641f6b ("cifsd: add server handler for central processing and tranport layers")
Fixes: a77e0e02af1c ("ksmbd: add support for supplementary groups")
Cc: stable@vger.kernel.org
Assisted-by: Claude:claude-opus-4-6
Assisted-by: Codex:gpt-5-4
Signed-off-by: Michael Bommarito <michael.bommarito@gmail.com>
Acked-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Steve French <stfrench@microsoft.com>
[ Stable dependency adaptation for f25e93768fcc5d8287e50b1ec52a42e4c276df34:
Retain the RPC response-size overflow check in ipc_validate_msg().
The previous dependency, 2d1f4c041770, already supplied the overflow
header and the share-response checked addition required by the target.
Drop both supplementary-group hunks: this stable tree has neither
extended-login IPC messages nor supplementary-group fields in ksmbd_user.
Keep user_config.c unchanged and do not introduce extended-login support
or any new functions. The target applies cleanly by three-way application
with the existing share-config preparation and this reduced dependency. ]
[ sashal: Reduced backport -- upstream d6a6aa81eac2c touches 2 file(s), this
backport carries 1. Not backported here:
fs/smb/server/mgmt/user_config.c
This note is generated from the file lists only; see the resolution record
for the reasoning. ]
Stable-dep-of: f25e93768fcc ("ksmbd: prevent out-of-bounds reads in share config responses")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/smb/server/transport_ipc.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/fs/smb/server/transport_ipc.c b/fs/smb/server/transport_ipc.c
index 5bf29431b4e48..dbc3c2bd241f1 100644
--- a/fs/smb/server/transport_ipc.c
+++ b/fs/smb/server/transport_ipc.c
@@ -481,7 +481,9 @@ static int ipc_validate_msg(struct ipc_msg_table_entry *entry)
{
struct ksmbd_rpc_command *resp = entry->response;
- msg_sz = sizeof(struct ksmbd_rpc_command) + resp->payload_sz;
+ if (check_add_overflow(sizeof(struct ksmbd_rpc_command),
+ resp->payload_sz, &msg_sz))
+ return -EINVAL;
break;
}
case KSMBD_EVENT_SPNEGO_AUTHEN_REQUEST:
--
2.53.0
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH 6.1.y 4/5] ksmbd: validate ipc response length before dereferencing its fields
2026-09-14 15:30 ` [PATCH 6.1.y 1/5] ksmbd: Use struct_size() to improve smb_direct_rdma_xmit() Sasha Levin
2026-09-14 15:30 ` [PATCH 6.1.y 2/5] ksmbd: use __GFP_RETRY_MAYFAIL Sasha Levin
2026-09-14 15:30 ` [PATCH 6.1.y 3/5] ksmbd: validate response sizes in ipc_validate_msg() Sasha Levin
@ 2026-09-14 15:30 ` Sasha Levin
2026-09-14 15:30 ` [PATCH 6.1.y 5/5] ksmbd: prevent out-of-bounds reads in share config responses Sasha Levin
3 siblings, 0 replies; 6+ messages in thread
From: Sasha Levin @ 2026-09-14 15:30 UTC (permalink / raw)
To: stable; +Cc: Yunseong Kim, Namjae Jeon, Sasha Levin
From: Yunseong Kim <yunseong.kim@est.tech>
[ Upstream commit e9b33376bd07bca4175f7bcc2d6034ef250f8181 ]
ipc_validate_msg() computes the expected message size by reading length
fields out of the response buffer supplied by the userspace ksmbd daemon
(payload_sz, session_key_len, ngroups, ...). Those fields are read before
the buffer is verified to be large enough to contain the struct they belong
to, so a short response makes the read land past the end of the allocation.
handle_response() sizes entry->response purely from the netlink attribute
length (nla_len()) and only guards the leading handle read, so the daemon
can install a response as small as the kmalloc-8 object seen below. When
ipc_msg_send_request() then calls ipc_validate_msg() for a
KSMBD_EVENT_RPC_REQUEST, the cast to struct ksmbd_rpc_command reads
resp->payload_sz at offset 8 of an 8-byte allocation:
[ 3697.841381] ==================================================================
[ 3697.844099] BUG: KASAN: slab-out-of-bounds in ipc_msg_send_request+0x763/0x800
[ 3697.846604] Read of size 4 at addr ffff888105f95910 by task kworker/4:3/20682
[ 3697.849061]
[ 3697.849801] CPU: 4 UID: 0 PID: 20682 Comm: kworker/4:3 Not tainted 7.2.0-rc3-next-20260717-virtme #117 PREEMPT(lazy)
[ 3697.850077] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.17.0-debian-1.17.0-1 04/01/2014
[ 3697.850303] Workqueue: ksmbd-io handle_ksmbd_work
[ 3697.850592] Call Trace:
[ 3697.850794] <TASK>
[ 3697.850952] __dump_stack+0x21/0x60
[ 3697.851239] dump_stack_lvl+0xc2/0x100
[ 3697.851528] print_address_description+0x77/0x200
[ 3697.851816] ? ipc_msg_send_request+0x763/0x800
[ 3697.852024] print_report+0x58/0x70
[ 3697.852316] kasan_report+0x117/0x150
[ 3697.852585] ? down_write+0x146/0x1f0
[ 3697.852809] ? ipc_msg_send_request+0x763/0x800
[ 3697.853082] ipc_msg_send_request+0x763/0x800
[ 3697.853385] ? __pfx_ipc_msg_send_request+0x10/0x10
[ 3697.853604] ? kasan_unpoison+0x48/0x70
[ 3697.853936] ? __pfx___up_read+0x10/0x10
[ 3697.854221] ksmbd_rpc_ioctl+0x380/0x520
[ 3697.854542] ? __pfx_ksmbd_rpc_ioctl+0x10/0x10
[ 3697.854757] ? kasan_unpoison+0x48/0x70
[ 3697.854962] ? copy_from_kernel_nofault+0x32c/0x4e0
[ 3697.855166] ? kasan_unpoison+0x48/0x70
[ 3697.855416] fsctl_pipe_transceive+0x139/0x7a0
[ 3697.855705] ? __pfx_copy_from_kernel_nofault+0x10/0x10
[ 3697.855937] ? __pfx_fsctl_pipe_transceive+0x10/0x10
[ 3697.856388] ? __sanitizer_cov_trace_switch+0x7b/0x140
[ 3697.856620] smb2_ioctl+0x1141/0x3420
[ 3697.856994] ? __pfx_smb2_ioctl+0x10/0x10
[ 3697.857182] ? get_smb2_cmd_val+0xe3/0x1c0
[ 3697.857655] handle_ksmbd_work+0x9ad/0x15e0
[ 3697.858034] ? __pfx_handle_ksmbd_work+0x10/0x10
[ 3697.858251] ? lock_release+0xf7/0x360
[ 3697.858466] ? process_scheduled_works+0x954/0x1600
[ 3697.858698] ? process_scheduled_works+0x954/0x1600
[ 3697.858905] process_scheduled_works+0xc22/0x1600
[ 3697.859368] ? __pfx_process_scheduled_works+0x10/0x10
[ 3697.859637] ? __pfx_assign_work+0x10/0x10
[ 3697.859896] ? lock_is_held_type+0x7b/0x110
[ 3697.860146] worker_thread+0x975/0xee0
[ 3697.860524] ? __pfx_do_raw_spin_lock+0x10/0x10
[ 3697.860830] ? __kthread_parkme+0x21e/0x260
[ 3697.861105] kthread+0x3a6/0x490
[ 3697.861423] ? __pfx_worker_thread+0x10/0x10
[ 3697.861643] ? __pfx_kthread+0x10/0x10
[ 3697.861878] ret_from_fork+0x55a/0xa20
[ 3697.862194] ? __pfx_ret_from_fork+0x10/0x10
[ 3697.862480] ? __pfx_kthread+0x10/0x10
[ 3697.862714] ret_from_fork_asm+0x1a/0x30
[ 3697.862965] </TASK>
[ 3697.863039]
[ 3697.938882] Allocated by task 20761:
[ 3697.940257] kasan_save_track+0x3e/0x80
[ 3697.941782] __kasan_kmalloc+0x72/0x90
[ 3697.943228] __kvmalloc_node_noprof+0x3e9/0x6a0
[ 3697.944948] handle_generic_event+0x59b/0x750
[ 3697.946592] genl_family_rcv_msg_doit+0x3d6/0x560
[ 3697.946977] genl_rcv_msg+0x67c/0x900
[ 3697.947224] netlink_rcv_skb+0x286/0x580
[ 3697.947488] genl_rcv+0x2d/0x80
[ 3697.947706] netlink_unicast+0x937/0xb70
[ 3697.947993] netlink_sendmsg+0x977/0xc10
[ 3697.948268] __sock_sendmsg+0x264/0x2d0
[ 3697.948536] __sys_sendto+0x4de/0x690
[ 3697.948789] __x64_sys_sendto+0x173/0x380
[ 3697.949069] do_syscall_64+0x13d/0x420
[ 3697.949328] entry_SYSCALL_64_after_hwframe+0x77/0x7f
[ 3697.949662]
[ 3697.949779] The buggy address belongs to the object at ffff888105f95908
[ 3697.949779] which belongs to the cache kmalloc-8 of size 8
[ 3697.950550] The buggy address is located 0 bytes to the right of
[ 3697.950550] allocated 8-byte region [ffff888105f95908, ffff888105f95910)
[ 3697.951455]
[ 3697.951574] The buggy address belongs to the physical page:
[ 3697.951958] page: refcount:0 mapcount:0 mapping:0000000000000000 index:0xffff888105f951b8 pfn:0x105f95
[ 3697.952571] flags: 0x100000000000200(workingset|node=0|zone=2)
[ 3697.952973] page_type: f5(slab)
[ 3697.953198] raw: 0100000000000200 ffff888100042640 ffffea0004063610 ffff888100040588
[ 3697.953707] raw: ffff888105f951b8 00000000001c000e 00000000f5000000 0000000000000000
[ 3697.954240] page dumped because: kasan: bad access detected
[ 3697.954616]
[ 3697.954734] Memory state around the buggy address:
[ 3697.955063] ffff888105f95800: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fa
[ 3697.955534] ffff888105f95880: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
[ 3697.956006] >ffff888105f95900: fc 00 fc fc fc fc fc fc fc fc fc fc fc fc fc fc
[ 3697.956477] ^
[ 3697.956728] ffff888105f95980: fc fc fc fa fc fc fc fc fc fc fc fc fc fc fc fc
[ 3697.957202] ffff888105f95a00: fc fc fc fc fc fa fc fc fc fc fc fc fc fc fc fc
[ 3697.957671] ==================================================================
The final "entry->msg_sz != msg_sz" comparison cannot help: the offending
read has already happened by the time it runs. Every case in the switch
shares this pattern.
Floor entry->msg_sz against the base struct of each event type before
dereferencing any of its length fields. On failure ipc_msg_send_request()
already frees the response and returns NULL, so callers stay safe.
The malformed message originates from the ksmbd.mountd daemon over genl
netlink rather than a remote SMB client, so triggering it requires a buggy
or compromised daemon; it is still an out-of-bounds read the validator is
meant to prevent.
Fixes: d6a6aa81eac2 ("ksmbd: validate response sizes in ipc_validate_msg()")
Signed-off-by: Yunseong Kim <yunseong.kim@est.tech>
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
[ Stable dependency adaptation for f25e93768fcc5d8287e50b1ec52a42e4c276df34:
Retain the minimum response-header checks for RPC and SPNEGO before
dereferencing their variable-length fields in ipc_validate_msg().
The share-config header check is already present from dependency
2d1f4c041770, so it needs no additional change here.
Drop the extended-login hunk: this stable tree has neither
KSMBD_EVENT_LOGIN_REQUEST_EXT nor struct ksmbd_login_response_ext.
Do not introduce extended-login support or any new functions.
The target applies cleanly by three-way application to this tree. ]
Stable-dep-of: f25e93768fcc ("ksmbd: prevent out-of-bounds reads in share config responses")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/smb/server/transport_ipc.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/fs/smb/server/transport_ipc.c b/fs/smb/server/transport_ipc.c
index dbc3c2bd241f1..9edd598105c4f 100644
--- a/fs/smb/server/transport_ipc.c
+++ b/fs/smb/server/transport_ipc.c
@@ -481,6 +481,9 @@ static int ipc_validate_msg(struct ipc_msg_table_entry *entry)
{
struct ksmbd_rpc_command *resp = entry->response;
+ if (entry->msg_sz < sizeof(struct ksmbd_rpc_command))
+ return -EINVAL;
+
if (check_add_overflow(sizeof(struct ksmbd_rpc_command),
resp->payload_sz, &msg_sz))
return -EINVAL;
@@ -490,6 +493,9 @@ static int ipc_validate_msg(struct ipc_msg_table_entry *entry)
{
struct ksmbd_spnego_authen_response *resp = entry->response;
+ if (entry->msg_sz < sizeof(struct ksmbd_spnego_authen_response))
+ return -EINVAL;
+
msg_sz = sizeof(struct ksmbd_spnego_authen_response) +
resp->session_key_len + resp->spnego_blob_len;
break;
--
2.53.0
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH 6.1.y 5/5] ksmbd: prevent out-of-bounds reads in share config responses
2026-09-14 15:30 ` [PATCH 6.1.y 1/5] ksmbd: Use struct_size() to improve smb_direct_rdma_xmit() Sasha Levin
` (2 preceding siblings ...)
2026-09-14 15:30 ` [PATCH 6.1.y 4/5] ksmbd: validate ipc response length before dereferencing its fields Sasha Levin
@ 2026-09-14 15:30 ` Sasha Levin
3 siblings, 0 replies; 6+ messages in thread
From: Sasha Levin @ 2026-09-14 15:30 UTC (permalink / raw)
To: stable; +Cc: Namjae Jeon, Kanishka De Silva, Farhad Alemi, Sasha Levin
From: Namjae Jeon <linkinjeon@kernel.org>
[ Upstream commit f25e93768fcc5d8287e50b1ec52a42e4c276df34 ]
Validate IPC share configuration payload sizes before consuming
variable-length fields. Bound veto list parsing and account for
the separator byte when deriving the path length.
Fixes: a677ebd8ca2f ("ksmbd: validate payload size in ipc response")
Reported-by: Kanishka De Silva <kpskanna1915@gmail.com>
Reported-by: Farhad Alemi <farhad.alemi@berkeley.edu>
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/smb/server/mgmt/share_config.c | 40 +++++++++++++++++++++----------
fs/smb/server/transport_ipc.c | 21 ++++++++++------
2 files changed, 41 insertions(+), 20 deletions(-)
diff --git a/fs/smb/server/mgmt/share_config.c b/fs/smb/server/mgmt/share_config.c
index 7f519a280188a..7c6e023abe2ed 100644
--- a/fs/smb/server/mgmt/share_config.c
+++ b/fs/smb/server/mgmt/share_config.c
@@ -88,9 +88,9 @@ static struct ksmbd_share_config *__share_lookup(const char *name)
static int parse_veto_list(struct ksmbd_share_config *share,
char *veto_list,
- int veto_list_sz)
+ size_t veto_list_sz)
{
- int sz = 0;
+ size_t sz;
if (!veto_list_sz)
return 0;
@@ -98,7 +98,7 @@ static int parse_veto_list(struct ksmbd_share_config *share,
while (veto_list_sz > 0) {
struct ksmbd_veto_pattern *p;
- sz = strlen(veto_list);
+ sz = strnlen(veto_list, veto_list_sz);
if (!sz)
break;
@@ -106,7 +106,7 @@ static int parse_veto_list(struct ksmbd_share_config *share,
if (!p)
return -ENOMEM;
- p->pattern = kstrdup(veto_list, KSMBD_DEFAULT_GFP);
+ p->pattern = kstrndup(veto_list, sz, KSMBD_DEFAULT_GFP);
if (!p->pattern) {
kfree(p);
return -ENOMEM;
@@ -114,6 +114,9 @@ static int parse_veto_list(struct ksmbd_share_config *share,
list_add(&p->list, &share->veto_list);
+ if (sz == veto_list_sz)
+ break;
+
veto_list += sz + 1;
veto_list_sz -= (sz + 1);
}
@@ -160,17 +163,28 @@ static struct ksmbd_share_config *share_config_request(struct ksmbd_work *work,
share->name = kstrdup(name, KSMBD_DEFAULT_GFP);
if (!test_share_config_flag(share, KSMBD_SHARE_FLAG_PIPE)) {
- int path_len = PATH_MAX;
-
- if (resp->payload_sz)
- path_len = resp->payload_sz - resp->veto_list_sz;
+ size_t path_len;
- share->path = kstrndup(ksmbd_share_config_path(resp), path_len,
- KSMBD_DEFAULT_GFP);
- if (!share->path) {
- ret = -ENOMEM;
+ if (resp->payload_sz <= resp->veto_list_sz) {
+ ret = -EINVAL;
} else {
- ret = 0;
+ path_len = resp->payload_sz - resp->veto_list_sz;
+ if (resp->veto_list_sz)
+ path_len--;
+
+ if (!path_len) {
+ ret = -EINVAL;
+ } else {
+ share->path = kstrndup(
+ ksmbd_share_config_path(resp),
+ path_len, KSMBD_DEFAULT_GFP);
+ if (!share->path)
+ ret = -ENOMEM;
+ else
+ ret = 0;
+ }
+ }
+ if (share->path) {
share->path_sz = strlen(share->path);
while (share->path_sz > 1 &&
share->path[share->path_sz - 1] == '/')
diff --git a/fs/smb/server/transport_ipc.c b/fs/smb/server/transport_ipc.c
index 9edd598105c4f..c02aaa549c357 100644
--- a/fs/smb/server/transport_ipc.c
+++ b/fs/smb/server/transport_ipc.c
@@ -507,14 +507,21 @@ static int ipc_validate_msg(struct ipc_msg_table_entry *entry)
if (entry->msg_sz < sizeof(struct ksmbd_share_config_response))
return -EINVAL;
- if (resp->payload_sz) {
- if (resp->payload_sz < resp->veto_list_sz)
- return -EINVAL;
+ if (strnlen(resp->share_name, sizeof(resp->share_name)) ==
+ sizeof(resp->share_name))
+ return -EINVAL;
- if (check_add_overflow(sizeof(struct ksmbd_share_config_response),
- resp->payload_sz, &msg_sz))
- return -EINVAL;
- }
+ if (resp->veto_list_sz > resp->payload_sz)
+ return -EINVAL;
+
+ if (resp->flags != KSMBD_SHARE_FLAG_INVALID &&
+ !(resp->flags & KSMBD_SHARE_FLAG_PIPE) &&
+ resp->payload_sz <= resp->veto_list_sz)
+ return -EINVAL;
+
+ if (check_add_overflow(sizeof(struct ksmbd_share_config_response),
+ resp->payload_sz, &msg_sz))
+ return -EINVAL;
break;
}
}
--
2.53.0
^ permalink raw reply related [flat|nested] 6+ messages in thread
end of thread, other threads:[~2026-09-14 15:30 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-09-14 11:03 FAILED: patch "[PATCH] ksmbd: prevent out-of-bounds reads in share config responses" failed to apply to 6.1-stable tree gregkh
2026-09-14 15:30 ` [PATCH 6.1.y 1/5] ksmbd: Use struct_size() to improve smb_direct_rdma_xmit() Sasha Levin
2026-09-14 15:30 ` [PATCH 6.1.y 2/5] ksmbd: use __GFP_RETRY_MAYFAIL Sasha Levin
2026-09-14 15:30 ` [PATCH 6.1.y 3/5] ksmbd: validate response sizes in ipc_validate_msg() Sasha Levin
2026-09-14 15:30 ` [PATCH 6.1.y 4/5] ksmbd: validate ipc response length before dereferencing its fields Sasha Levin
2026-09-14 15:30 ` [PATCH 6.1.y 5/5] ksmbd: prevent out-of-bounds reads in share config responses Sasha Levin
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox