mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2026-09-22 09:34:56 +02:00
ksmbd: reject undersized DACLs before parsing ACEs
[ Upstream commit60908f7ebc] parse_dacl() limits the attacker-controlled ACE count by comparing it with the number of minimal ACEs that fit in the DACL size. The DACL size field is 16 bits, but the expression subtracts sizeof(struct smb_acl). Because sizeof() is unsigned, a DACL size smaller than the ACL header underflows to a large size_t. A malicious client can reach this with: SMB2_SET_INFO (InfoType=SMB2_O_INFO_SECURITY) -> smb2_set_info_sec() -> set_info_sec() -> parse_sec_desc() -> parse_dacl() -> init_acl_state(..., 0xffff) -> init_acl_state(..., 0xffff) -> kmalloc_objs(..., 0xffff) Thus a malformed security descriptor can make num_aces pass the guard and drive large temporary ACL state and pointer-array allocations. Reject DACLs smaller than struct smb_acl before doing the subtraction, so the ACE count check cannot be bypassed by the underflow. Fixes:e2f34481b2("cifsd: add server-side procedures for SMB3") Signed-off-by: Haofeng Li <lihaofeng@kylinos.cn> Reviewed-by: ChenXiaoSong <chenxiaosong@kylinos.cn> Acked-by: Namjae Jeon <linkinjeon@kernel.org> Signed-off-by: Steve French <stfrench@microsoft.com> Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:
committed by
Greg Kroah-Hartman
parent
17efa598ef
commit
16fb65ec15
@@ -374,6 +374,7 @@ static void parse_dacl(struct mnt_idmap *idmap,
|
||||
{
|
||||
int i, ret;
|
||||
u16 num_aces = 0;
|
||||
u16 dacl_size;
|
||||
unsigned int acl_size;
|
||||
char *acl_base;
|
||||
struct smb_ace **ppace;
|
||||
@@ -403,7 +404,11 @@ static void parse_dacl(struct mnt_idmap *idmap,
|
||||
if (num_aces <= 0)
|
||||
return;
|
||||
|
||||
if (num_aces > (le16_to_cpu(pdacl->size) - sizeof(struct smb_acl)) /
|
||||
dacl_size = le16_to_cpu(pdacl->size);
|
||||
if (dacl_size < sizeof(struct smb_acl))
|
||||
return;
|
||||
|
||||
if (num_aces > (dacl_size - sizeof(struct smb_acl)) /
|
||||
(offsetof(struct smb_ace, sid) +
|
||||
offsetof(struct smb_sid, sub_auth) + sizeof(__le16)))
|
||||
return;
|
||||
|
||||
Reference in New Issue
Block a user