FAILED: patch "[PATCH] ksmbd: prevent out-of-bounds reads in share config responses" failed to apply to 6.6-stable tree
Subsystems (2)
[email protected]
maintainerThe patch below does not apply to the 6.6-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 <[email protected]>.
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.6.y
git checkout FETCH_HEAD
git cherry-pick -x f25e93768fcc5d8287e50b1ec52a42e4c276df34
# <resolve conflicts, build, test, etc.>
git commit -s
git send-email --to '<[email protected]>' --in-reply-to '2026091411-kept-parish-8e82@gregkh' --subject-prefix 'PATCH 6.6.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 <[email protected]>
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.
fs/smb/server/mgmt/share_config.c +27 -13
@@ -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 ] =='/' )
fs/smb/server/transport_ipc.c +14 -7
@@ -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 :
Sasha Levin
maintainerPATCH 1/2 ksmbd: use __GFP_RETRY_MAYFAIL
From: Namjae Jeon <[email protected]>
[ 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.
Stable dependency adaptation for f25e93768fcc5d8287e50b1ec52a42e4c276df34:
Limit the allocation-flag conversion to share configuration and retain KSMBD_DEFAULT_GFP in glob.h. Drop the other subsystem conversions, which are unnecessary for the target and conflict with stable's existing ID, RPC locking, lease, ACL-buffer and network-interface implementations.
Include the existing-function share_config_request() error handling from a74668eb2c0b8 (path allocation failure) and the share_config.c changes from d2ccf905f47d2 (name allocation failure). These provide the target's patch context and ensure veto-list parsing cannot overwrite a failed path allocation or the target's invalid-path error. No functions are added.
[ sashal: Reduced backport -- upstream 0066f623bce8f touches 24 file(s), this
backport carries 2. 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 14 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")
--- fs/smb/server/glob.h | 2 ++ fs/smb/server/mgmt/share_config.c | 29 +++++++++++++++++++---------- 2 files changed, 21 insertions(+), 10 deletions(-)
fs/smb/server/glob.h +2 -0
@@ -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 */
fs/smb/server/mgmt/share_config.c +19 -10
@@ -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,19 @@ 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 (!share->name) { +kill_share (share); + share =NULL ; + goto out; + }if (!test_share_config_flag (share,KSMBD_SHARE_FLAG_PIPE )) {int path_len =PATH_MAX ;
@@ -166,8 +171,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 +187,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);
@@ -199,7 +208,7 @@ static struct ksmbd_share_config *share_config_request(struct ksmbd_work *work, share->path =NULL ; } } -if (ret || !share->name) { +if (ret) {kill_share (share); share =NULL ; goto out;
Signature · 1 line
2.53.0
Sasha Levin
maintainerPATCH 2/2 ksmbd: prevent out-of-bounds reads in share config responses
From: Namjae Jeon <[email protected]>
[ 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.
--- fs/smb/server/mgmt/share_config.c | 40 +++++++++++++++++++++---------- fs/smb/server/transport_ipc.c | 21 ++++++++++------ 2 files changed, 41 insertions(+), 20 deletions(-)
fs/smb/server/mgmt/share_config.c +27 -13
@@ -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 ); }
@@ -165,17 +168,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 ; - -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 ] =='/' )
fs/smb/server/transport_ipc.c +14 -7
@@ -524,14 +524,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 :
Signature · 1 line
2.53.0