From: Frank Sorenson <sorenson@redhat.com>
To: linux-cifs@vger.kernel.org
Cc: pc@manguebit.org, linkinjeon@kernel.org, stable@vger.kernel.org
Subject: [PATCH v3] smb: client: fix heap overflow in cifs_do_set_acl()
Date: Wed, 26 Aug 2026 10:06:43 -0500 [thread overview]
Message-ID: <20260826150643.4106838-1-sorenson@redhat.com> (raw)
cifs_set_acl() validates ACL size using posix_acl_xattr_size():
4 + (count * 8) // 4-byte header + 8 bytes per ACE
cifs_do_set_acl() then calls posix_acl_to_cifs() to write the CIFS
wire format into the same buffer:
6 + (count * 10) // 6-byte header + 10 bytes per ACE
An ACL that passes the xattr-based check in cifs_set_acl() can
overflow the heap when posix_acl_to_cifs() writes the larger CIFS
format.
Validate the CIFS format size against the remaining buffer space and
USHRT_MAX before converting--data_count is __u16, so sizes above
USHRT_MAX truncate the on-wire packet length, causing the server to
apply a partial ACL. Replace MaxDataCount = 1000 with
min(CIFSMaxBufSize, USHRT_MAX).
Fixes: dc1af4c4b4721 ("cifs: implement set acl method")
Cc: stable@vger.kernel.org
Signed-off-by: Frank Sorenson <sorenson@redhat.com>
---
v3 changes:
- change header size to use MAX_HEADER_SIZE helper
v2 changes:
- Add USHRT_MAX bound to prevent u16 truncation of data_count for ACLs
with more than 6553 entries, which would cause a partial ACL to be
silently applied on the server
- limit MaxDataCount to min(CIFSMaxBufSize, USHRT_MAX)
fs/smb/client/cifssmb.c | 13 +++++++++++--
1 file changed, 11 insertions(+), 2 deletions(-)
diff --git a/fs/smb/client/cifssmb.c b/fs/smb/client/cifssmb.c
index f5aad5f61dce..230af243247c 100644
--- a/fs/smb/client/cifssmb.c
+++ b/fs/smb/client/cifssmb.c
@@ -3555,6 +3555,7 @@ int cifs_do_set_acl(const unsigned int xid, struct cifs_tcon *tcon,
int rc = 0;
int bytes_returned = 0;
__u16 params, byte_count, data_count, param_offset, offset;
+ size_t cifs_acl_size, bytes_available;
cifs_dbg(FYI, "In SetPosixACL (Unix) for path %s\n", fileName);
setAclRetry:
@@ -3574,8 +3575,7 @@ int cifs_do_set_acl(const unsigned int xid, struct cifs_tcon *tcon,
}
params = 6 + name_len;
pSMB->MaxParameterCount = cpu_to_le16(2);
- /* BB find max SMB size from sess */
- pSMB->MaxDataCount = cpu_to_le16(1000);
+ pSMB->MaxDataCount = cpu_to_le16(min_t(unsigned int, CIFSMaxBufSize, USHRT_MAX));
pSMB->MaxSetupCount = 0;
pSMB->Reserved = 0;
pSMB->Flags = 0;
@@ -3587,6 +3587,15 @@ int cifs_do_set_acl(const unsigned int xid, struct cifs_tcon *tcon,
parm_data = ((char *)pSMB) + offset;
pSMB->ParameterOffset = cpu_to_le16(param_offset);
+ /* make sure we can fit the larger cifs_posix_aces in the buffer */
+ cifs_acl_size = sizeof(struct cifs_posix_acl) +
+ (acl->a_count * sizeof(struct cifs_posix_ace));
+ bytes_available = (CIFSMaxBufSize + MAX_HEADER_SIZE(tcon->ses->server)) - offset;
+ if (cifs_acl_size > bytes_available || cifs_acl_size > USHRT_MAX) {
+ rc = -E2BIG;
+ goto setACLerrorExit;
+ }
+
/* convert to on the wire format for POSIX ACL */
data_count = posix_acl_to_cifs(parm_data, acl, acl_type);
--
2.55.0
reply other threads:[~2026-08-26 15:07 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260826150643.4106838-1-sorenson@redhat.com \
--to=sorenson@redhat.com \
--cc=linkinjeon@kernel.org \
--cc=linux-cifs@vger.kernel.org \
--cc=pc@manguebit.org \
--cc=stable@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.