* FAILED: patch "[PATCH] ksmbd: validate security descriptor offsets before pointer" failed to apply to 5.15-stable tree
@ 2026-11-03 10:20 gregkh
2026-11-04 3:25 ` Backport:FAILED: " Ratnaker Gautam
0 siblings, 1 reply; 3+ messages in thread
From: gregkh @ 2026-11-03 10:20 UTC (permalink / raw)
To: linkinjeon, ratnaker.gautam; +Cc: stable
The patch below does not apply to the 5.15-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-5.15.y
git checkout FETCH_HEAD
git cherry-pick -x 3474e1a304fbf9f7c996b24adcd519e031227a90
# <resolve conflicts, build, test, etc.>
git commit -s
git send-email --to '<stable@vger.kernel.org>' --in-reply-to '2026110319-apple-willow-5e9e@gregkh' --subject-prefix 'PATCH 5.15.y' 'HEAD^..'
Possible dependencies:
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From 3474e1a304fbf9f7c996b24adcd519e031227a90 Mon Sep 17 00:00:00 2001
From: Namjae Jeon <linkinjeon@kernel.org>
Date: Sat, 17 Oct 2026 09:44:48 +0900
Subject: [PATCH] ksmbd: validate security descriptor offsets before pointer
arithmetic
parse_sec_desc() constructs SID and DACL pointers by adding untrusted
32-bit offsets to the security descriptor before checking their bounds.
The existing checks reject offsets into the descriptor header, but do
not reject offsets beyond the descriptor's length.
On a 32-bit kernel, a large offset can wrap the pointer before the
descriptor. The end-only checks in parse_sid() and parse_dacl() can then
accept it, allowing an authenticated SMB2 SET_INFO request to access
memory outside the security descriptor and fault the kernel.
Check each nonzero offset against acl_len before constructing its
pointer. Initialize the optional owner and group SID pointers to NULL
so an omitted SID remains absent when parsing the DACL.
Fixes: 0626e6641f6b ("cifsd: add server handler for central processing and tranport layers")
Cc: stable@vger.kernel.org
Reported-by: Ratnaker Gautam <ratnaker.gautam@kuleuven.be>
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
diff --git a/fs/smb/server/smbacl.c b/fs/smb/server/smbacl.c
index 96428df33b43..f3b1efd8e85a 100644
--- a/fs/smb/server/smbacl.c
+++ b/fs/smb/server/smbacl.c
@@ -900,7 +900,7 @@ int parse_sec_desc(const struct mnt_idmap *idmap, struct smb_ntsd *pntsd,
int acl_len, struct smb_fattr *fattr)
{
int rc = 0;
- struct smb_sid *owner_sid_ptr, *group_sid_ptr;
+ struct smb_sid *owner_sid_ptr = NULL, *group_sid_ptr = NULL;
struct smb_acl *dacl_ptr; /* no need for SACL ptr */
char *end_of_acl = ((char *)pntsd) + acl_len;
__u32 dacloffset;
@@ -912,12 +912,7 @@ int parse_sec_desc(const struct mnt_idmap *idmap, struct smb_ntsd *pntsd,
if (acl_len < sizeof(struct smb_ntsd))
return -EINVAL;
- owner_sid_ptr = (struct smb_sid *)((char *)pntsd +
- le32_to_cpu(pntsd->osidoffset));
- group_sid_ptr = (struct smb_sid *)((char *)pntsd +
- le32_to_cpu(pntsd->gsidoffset));
dacloffset = le32_to_cpu(pntsd->dacloffset);
- dacl_ptr = (struct smb_acl *)((char *)pntsd + dacloffset);
ksmbd_debug(SMB,
"revision %d type 0x%x ooffset 0x%x goffset 0x%x sacloffset 0x%x dacloffset 0x%x\n",
pntsd->revision, pntsd->type, le32_to_cpu(pntsd->osidoffset),
@@ -933,9 +928,12 @@ int parse_sec_desc(const struct mnt_idmap *idmap, struct smb_ntsd *pntsd,
pntsd->type = cpu_to_le16(DACL_PRESENT);
if (pntsd->osidoffset) {
- if (le32_to_cpu(pntsd->osidoffset) < sizeof(struct smb_ntsd))
+ if (le32_to_cpu(pntsd->osidoffset) < sizeof(struct smb_ntsd) ||
+ le32_to_cpu(pntsd->osidoffset) >= acl_len)
return -EINVAL;
+ owner_sid_ptr = (struct smb_sid *)((char *)pntsd +
+ le32_to_cpu(pntsd->osidoffset));
rc = parse_sid(owner_sid_ptr, end_of_acl);
if (rc) {
pr_err("%s: Error %d parsing Owner SID\n", __func__, rc);
@@ -951,9 +949,12 @@ int parse_sec_desc(const struct mnt_idmap *idmap, struct smb_ntsd *pntsd,
}
if (pntsd->gsidoffset) {
- if (le32_to_cpu(pntsd->gsidoffset) < sizeof(struct smb_ntsd))
+ if (le32_to_cpu(pntsd->gsidoffset) < sizeof(struct smb_ntsd) ||
+ le32_to_cpu(pntsd->gsidoffset) >= acl_len)
return -EINVAL;
+ group_sid_ptr = (struct smb_sid *)((char *)pntsd +
+ le32_to_cpu(pntsd->gsidoffset));
rc = parse_sid(group_sid_ptr, end_of_acl);
if (rc) {
pr_err("%s: Error %d mapping Owner SID to gid\n",
@@ -975,9 +976,10 @@ int parse_sec_desc(const struct mnt_idmap *idmap, struct smb_ntsd *pntsd,
pntsd->type |= cpu_to_le16(DACL_PROTECTED);
if (dacloffset) {
- if (dacloffset < sizeof(struct smb_ntsd))
+ if (dacloffset < sizeof(struct smb_ntsd) || dacloffset >= acl_len)
return -EINVAL;
+ dacl_ptr = (struct smb_acl *)((char *)pntsd + dacloffset);
rc = parse_dacl(idmap, dacl_ptr, end_of_acl,
owner_sid_ptr, group_sid_ptr, fattr);
if (rc)
^ permalink raw reply related [flat|nested] 3+ messages in thread
* Re: Backport:FAILED: patch "[PATCH] ksmbd: validate security descriptor offsets before pointer" failed to apply to 5.15-stable tree
2026-11-03 10:20 FAILED: patch "[PATCH] ksmbd: validate security descriptor offsets before pointer" failed to apply to 5.15-stable tree gregkh
@ 2026-11-04 3:25 ` Ratnaker Gautam
2026-11-05 4:29 ` Fixed " Ratnaker Gautam
0 siblings, 1 reply; 3+ messages in thread
From: Ratnaker Gautam @ 2026-11-04 3:25 UTC (permalink / raw)
To: gregkh@linuxfoundation.org, linkinjeon@kernel.org,
Paulo Alcantara
Cc: stable@vger.kernel.org
From: Namjae Jeon <linkinjeon@kernel.org>
[ Upstream commit 3474e1a304fbf9f7c996b24adcd519e031227a90 ]
parse_sec_desc() constructs SID and DACL pointers by adding untrusted
32-bit offsets to the security descriptor before checking their bounds.
The existing checks reject offsets into the descriptor header, but do
not reject offsets beyond the descriptor's length.
On a 32-bit kernel, a large offset can wrap the pointer before the
descriptor. The end-only checks in parse_sid() and parse_dacl() can then
accept it, allowing an authenticated SMB2 SET_INFO request to access
memory outside the security descriptor and fault the kernel.
Check each nonzero offset against acl_len before constructing its
pointer. Initialize the optional owner and group SID pointers to NULL
so an omitted SID remains absent when parsing the DACL.
The 5.15 tree keeps this code in fs/ksmbd/smbacl.c and uses a void
parse_dacl(). Preserve those interfaces in this backport.
Fixes: 0626e6641f6b ("cifsd: add server handler for central processing and tranport layers")
Cc: stable@vger.kernel.org
Reported-by: Ratnaker Gautam <ratnaker.gautam@kuleuven.be>
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
(cherry picked from commit 3474e1a304fbf9f7c996b24adcd519e031227a90)
Signed-off-by: Ratnaker Gautam <ratnaker.gautam@kuleuven.be>
---
fs/ksmbd/smbacl.c | 23 +++++++++++++++++------
1 file changed, 17 insertions(+), 6 deletions(-)
diff --git a/fs/ksmbd/smbacl.c b/fs/ksmbd/smbacl.c
index 05c768225..515830f75 100644
--- a/fs/ksmbd/smbacl.c
+++ b/fs/ksmbd/smbacl.c
@@ -830,7 +830,7 @@ int parse_sec_desc(struct user_namespace *user_ns, struct smb_ntsd *pntsd,
int acl_len, struct smb_fattr *fattr)
{
int rc = 0;
- struct smb_sid *owner_sid_ptr, *group_sid_ptr;
+ struct smb_sid *owner_sid_ptr = NULL, *group_sid_ptr = NULL;
struct smb_acl *dacl_ptr; /* no need for SACL ptr */
char *end_of_acl = ((char *)pntsd) + acl_len;
__u32 dacloffset;
@@ -842,12 +842,7 @@ int parse_sec_desc(struct user_namespace *user_ns, struct smb_ntsd *pntsd,
if (acl_len < sizeof(struct smb_ntsd))
return -EINVAL;
- owner_sid_ptr = (struct smb_sid *)((char *)pntsd +
- le32_to_cpu(pntsd->osidoffset));
- group_sid_ptr = (struct smb_sid *)((char *)pntsd +
- le32_to_cpu(pntsd->gsidoffset));
dacloffset = le32_to_cpu(pntsd->dacloffset);
- dacl_ptr = (struct smb_acl *)((char *)pntsd + dacloffset);
ksmbd_debug(SMB,
"revision %d type 0x%x ooffset 0x%x goffset 0x%x sacloffset 0x%x dacloffset 0x%x\n",
pntsd->revision, pntsd->type, le32_to_cpu(pntsd->osidoffset),
@@ -863,6 +858,12 @@ int parse_sec_desc(struct user_namespace *user_ns, struct smb_ntsd *pntsd,
pntsd->type = cpu_to_le16(DACL_PRESENT);
if (pntsd->osidoffset) {
+ if (le32_to_cpu(pntsd->osidoffset) < sizeof(struct smb_ntsd) ||
+ le32_to_cpu(pntsd->osidoffset) >= acl_len)
+ return -EINVAL;
+
+ owner_sid_ptr = (struct smb_sid *)((char *)pntsd +
+ le32_to_cpu(pntsd->osidoffset));
rc = parse_sid(owner_sid_ptr, end_of_acl);
if (rc) {
pr_err("%s: Error %d parsing Owner SID\n", __func__, rc);
@@ -878,6 +879,12 @@ int parse_sec_desc(struct user_namespace *user_ns, struct smb_ntsd *pntsd,
}
if (pntsd->gsidoffset) {
+ if (le32_to_cpu(pntsd->gsidoffset) < sizeof(struct smb_ntsd) ||
+ le32_to_cpu(pntsd->gsidoffset) >= acl_len)
+ return -EINVAL;
+
+ group_sid_ptr = (struct smb_sid *)((char *)pntsd +
+ le32_to_cpu(pntsd->gsidoffset));
rc = parse_sid(group_sid_ptr, end_of_acl);
if (rc) {
pr_err("%s: Error %d mapping Owner SID to gid\n",
@@ -899,6 +906,10 @@ int parse_sec_desc(struct user_namespace *user_ns, struct smb_ntsd *pntsd,
pntsd->type |= cpu_to_le16(DACL_PROTECTED);
if (dacloffset) {
+ if (dacloffset < sizeof(struct smb_ntsd) || dacloffset >= acl_len)
+ return -EINVAL;
+
+ dacl_ptr = (struct smb_acl *)((char *)pntsd + dacloffset);
parse_dacl(user_ns, dacl_ptr, end_of_acl,
owner_sid_ptr, group_sid_ptr, fattr);
}
--
2.43.0
^ permalink raw reply related [flat|nested] 3+ messages in thread
* Re: Fixed Backport:FAILED: patch "[PATCH] ksmbd: validate security descriptor offsets before pointer" failed to apply to 5.15-stable tree
2026-11-04 3:25 ` Backport:FAILED: " Ratnaker Gautam
@ 2026-11-05 4:29 ` Ratnaker Gautam
0 siblings, 0 replies; 3+ messages in thread
From: Ratnaker Gautam @ 2026-11-05 4:29 UTC (permalink / raw)
To: gregkh@linuxfoundation.org, linkinjeon@kernel.org,
Paulo Alcantara
Cc: stable@vger.kernel.org
From: Namjae Jeon <linkinjeon@kernel.org>
[ Upstream commit 3474e1a304fbf9f7c996b24adcd519e031227a90 ]
parse_sec_desc() constructs SID and DACL pointers by adding untrusted
32-bit offsets to the security descriptor before checking their bounds.
The existing checks reject offsets into the descriptor header, but do
not reject offsets beyond the descriptor's length.
On a 32-bit kernel, a large offset can wrap the pointer before the
descriptor. The end-only checks in parse_sid() and parse_dacl() can then
accept it, allowing an authenticated SMB2 SET_INFO request to access
memory outside the security descriptor and fault the kernel.
Check each nonzero offset against acl_len before constructing its
pointer. Initialize the optional owner and group SID pointers to NULL
so an omitted SID remains absent when parsing the DACL.
The 5.15 tree keeps this code in fs/ksmbd/smbacl.c and uses a void
parse_dacl(). Preserve those interfaces in this backport.
Fixes: 0626e6641f6b ("cifsd: add server handler for central processing and tranport layers")
Cc: stable@vger.kernel.org
Reported-by: Ratnaker Gautam <ratnaker.gautam@kuleuven.be>
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
(cherry picked from commit 3474e1a304fbf9f7c996b24adcd519e031227a90)
Signed-off-by: Ratnaker Gautam <ratnaker.gautam@kuleuven.be>
---
My earlier reply in this thread had its tabs expanded by Outlook.
Please disregard that copy.
fs/ksmbd/smbacl.c | 23 +++++++++++++++++------
1 file changed, 17 insertions(+), 6 deletions(-)
diff --git a/fs/ksmbd/smbacl.c b/fs/ksmbd/smbacl.c
index 05c768225..515830f75 100644
--- a/fs/ksmbd/smbacl.c
+++ b/fs/ksmbd/smbacl.c
@@ -830,7 +830,7 @@ int parse_sec_desc(struct user_namespace *user_ns, struct smb_ntsd *pntsd,
int acl_len, struct smb_fattr *fattr)
{
int rc = 0;
- struct smb_sid *owner_sid_ptr, *group_sid_ptr;
+ struct smb_sid *owner_sid_ptr = NULL, *group_sid_ptr = NULL;
struct smb_acl *dacl_ptr; /* no need for SACL ptr */
char *end_of_acl = ((char *)pntsd) + acl_len;
__u32 dacloffset;
@@ -842,12 +842,7 @@ int parse_sec_desc(struct user_namespace *user_ns, struct smb_ntsd *pntsd,
if (acl_len < sizeof(struct smb_ntsd))
return -EINVAL;
- owner_sid_ptr = (struct smb_sid *)((char *)pntsd +
- le32_to_cpu(pntsd->osidoffset));
- group_sid_ptr = (struct smb_sid *)((char *)pntsd +
- le32_to_cpu(pntsd->gsidoffset));
dacloffset = le32_to_cpu(pntsd->dacloffset);
- dacl_ptr = (struct smb_acl *)((char *)pntsd + dacloffset);
ksmbd_debug(SMB,
"revision %d type 0x%x ooffset 0x%x goffset 0x%x sacloffset 0x%x dacloffset 0x%x\n",
pntsd->revision, pntsd->type, le32_to_cpu(pntsd->osidoffset),
@@ -863,6 +858,12 @@ int parse_sec_desc(struct user_namespace *user_ns, struct smb_ntsd *pntsd,
pntsd->type = cpu_to_le16(DACL_PRESENT);
if (pntsd->osidoffset) {
+ if (le32_to_cpu(pntsd->osidoffset) < sizeof(struct smb_ntsd) ||
+ le32_to_cpu(pntsd->osidoffset) >= acl_len)
+ return -EINVAL;
+
+ owner_sid_ptr = (struct smb_sid *)((char *)pntsd +
+ le32_to_cpu(pntsd->osidoffset));
rc = parse_sid(owner_sid_ptr, end_of_acl);
if (rc) {
pr_err("%s: Error %d parsing Owner SID\n", __func__, rc);
@@ -878,6 +879,12 @@ int parse_sec_desc(struct user_namespace *user_ns, struct smb_ntsd *pntsd,
}
if (pntsd->gsidoffset) {
+ if (le32_to_cpu(pntsd->gsidoffset) < sizeof(struct smb_ntsd) ||
+ le32_to_cpu(pntsd->gsidoffset) >= acl_len)
+ return -EINVAL;
+
+ group_sid_ptr = (struct smb_sid *)((char *)pntsd +
+ le32_to_cpu(pntsd->gsidoffset));
rc = parse_sid(group_sid_ptr, end_of_acl);
if (rc) {
pr_err("%s: Error %d mapping Owner SID to gid\n",
@@ -899,6 +906,10 @@ int parse_sec_desc(struct user_namespace *user_ns, struct smb_ntsd *pntsd,
pntsd->type |= cpu_to_le16(DACL_PROTECTED);
if (dacloffset) {
+ if (dacloffset < sizeof(struct smb_ntsd) || dacloffset >= acl_len)
+ return -EINVAL;
+
+ dacl_ptr = (struct smb_acl *)((char *)pntsd + dacloffset);
parse_dacl(user_ns, dacl_ptr, end_of_acl,
owner_sid_ptr, group_sid_ptr, fattr);
}
--
2.43.0
^ permalink raw reply related [flat|nested] 3+ messages in thread
end of thread, other threads:[~2026-11-05 4:30 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-11-03 10:20 FAILED: patch "[PATCH] ksmbd: validate security descriptor offsets before pointer" failed to apply to 5.15-stable tree gregkh
2026-11-04 3:25 ` Backport:FAILED: " Ratnaker Gautam
2026-11-05 4:29 ` Fixed " Ratnaker Gautam
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox