ksmbd: OOB read regression in smb_check_perm_dacl() ACE-walk loops
Commitmasterd07b26f392("ksmbd: require minimum ACE size in smb_check_perm_dacl()") introduced a transposed bounds check: if (offsetof(struct smb_ace, sid) + aces_size < CIFS_SID_BASE_SIZE) Since offsetof(..sid) is 8 and CIFS_SID_BASE_SIZE is 8, this evaluates to `aces_size < 0`. Because `aces_size` is always non-negative, this check becomes dead code and never breaks the loop. Worse, that commit removed the old 4-byte guard, meaning the loop now reads `ace->size` (offset 2) even when `aces_size` is 0-3 bytes. This re-opens a 2-byte heap out-of-bounds (OOB) read past the pntsd allocation during subsequent SMB2_CREATE operations. Fix this by properly transposing the comparison to require at least 16 bytes (8-byte offset + 8-byte SID base), matching the correct form used in smb_inherit_dacl(). Fixes:d07b26f392("ksmbd: require minimum ACE size in smb_check_perm_dacl()") Cc: stable@vger.kernel.org Signed-off-by: Ali Ganiyev <ali.qaniyev@gmail.com> Acked-by: Namjae Jeon <linkinjeon@kernel.org> Signed-off-by: Steve French <stfrench@microsoft.com>
parent
e7ae89a0c9
commit
0e60dafe97
|
|
@ -1446,8 +1446,8 @@ int smb_check_perm_dacl(struct ksmbd_conn *conn, const struct path *path,
|
|||
ace = (struct smb_ace *)((char *)pdacl + sizeof(struct smb_acl));
|
||||
aces_size = acl_size - sizeof(struct smb_acl);
|
||||
for (i = 0; i < le16_to_cpu(pdacl->num_aces); i++) {
|
||||
if (offsetof(struct smb_ace, sid) +
|
||||
aces_size < CIFS_SID_BASE_SIZE)
|
||||
if (aces_size < offsetof(struct smb_ace, sid) +
|
||||
CIFS_SID_BASE_SIZE)
|
||||
break;
|
||||
ace_size = le16_to_cpu(ace->size);
|
||||
if (ace_size > aces_size ||
|
||||
|
|
@ -1467,8 +1467,8 @@ int smb_check_perm_dacl(struct ksmbd_conn *conn, const struct path *path,
|
|||
ace = (struct smb_ace *)((char *)pdacl + sizeof(struct smb_acl));
|
||||
aces_size = acl_size - sizeof(struct smb_acl);
|
||||
for (i = 0; i < le16_to_cpu(pdacl->num_aces); i++) {
|
||||
if (offsetof(struct smb_ace, sid) +
|
||||
aces_size < CIFS_SID_BASE_SIZE)
|
||||
if (aces_size < offsetof(struct smb_ace, sid) +
|
||||
CIFS_SID_BASE_SIZE)
|
||||
break;
|
||||
ace_size = le16_to_cpu(ace->size);
|
||||
if (ace_size > aces_size ||
|
||||
|
|
|
|||
Loading…
Reference in New Issue