Skip to content

Commit eebff19

Browse files
namjaejeonsmfrench
authored andcommitted
ksmbd: fix slab out of bounds write in smb_inherit_dacl()
slab out-of-bounds write is caused by that offsets is bigger than pntsd allocation size. This patch add the check to validate 3 offsets using allocation size. Reported-by: [email protected] # ZDI-CAN-22271 Cc: [email protected] Signed-off-by: Namjae Jeon <[email protected]> Signed-off-by: Steve French <[email protected]>
1 parent 766e9cf commit eebff19

File tree

1 file changed

+26
-3
lines changed

1 file changed

+26
-3
lines changed

fs/smb/server/smbacl.c

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1107,6 +1107,7 @@ int smb_inherit_dacl(struct ksmbd_conn *conn,
11071107
struct smb_acl *pdacl;
11081108
struct smb_sid *powner_sid = NULL, *pgroup_sid = NULL;
11091109
int powner_sid_size = 0, pgroup_sid_size = 0, pntsd_size;
1110+
int pntsd_alloc_size;
11101111

11111112
if (parent_pntsd->osidoffset) {
11121113
powner_sid = (struct smb_sid *)((char *)parent_pntsd +
@@ -1119,9 +1120,10 @@ int smb_inherit_dacl(struct ksmbd_conn *conn,
11191120
pgroup_sid_size = 1 + 1 + 6 + (pgroup_sid->num_subauth * 4);
11201121
}
11211122

1122-
pntsd = kzalloc(sizeof(struct smb_ntsd) + powner_sid_size +
1123-
pgroup_sid_size + sizeof(struct smb_acl) +
1124-
nt_size, GFP_KERNEL);
1123+
pntsd_alloc_size = sizeof(struct smb_ntsd) + powner_sid_size +
1124+
pgroup_sid_size + sizeof(struct smb_acl) + nt_size;
1125+
1126+
pntsd = kzalloc(pntsd_alloc_size, GFP_KERNEL);
11251127
if (!pntsd) {
11261128
rc = -ENOMEM;
11271129
goto free_aces_base;
@@ -1136,6 +1138,27 @@ int smb_inherit_dacl(struct ksmbd_conn *conn,
11361138
pntsd->gsidoffset = parent_pntsd->gsidoffset;
11371139
pntsd->dacloffset = parent_pntsd->dacloffset;
11381140

1141+
if ((u64)le32_to_cpu(pntsd->osidoffset) + powner_sid_size >
1142+
pntsd_alloc_size) {
1143+
rc = -EINVAL;
1144+
kfree(pntsd);
1145+
goto free_aces_base;
1146+
}
1147+
1148+
if ((u64)le32_to_cpu(pntsd->gsidoffset) + pgroup_sid_size >
1149+
pntsd_alloc_size) {
1150+
rc = -EINVAL;
1151+
kfree(pntsd);
1152+
goto free_aces_base;
1153+
}
1154+
1155+
if ((u64)le32_to_cpu(pntsd->dacloffset) + sizeof(struct smb_acl) + nt_size >
1156+
pntsd_alloc_size) {
1157+
rc = -EINVAL;
1158+
kfree(pntsd);
1159+
goto free_aces_base;
1160+
}
1161+
11391162
if (pntsd->osidoffset) {
11401163
struct smb_sid *owner_sid = (struct smb_sid *)((char *)pntsd +
11411164
le32_to_cpu(pntsd->osidoffset));

0 commit comments

Comments
 (0)