mirror of
https://github.com/torvalds/linux.git
synced 2024-11-29 07:31:29 +00:00
cifsd: fix static checker warning from smb_check_perm_dacl()
Dan reported static checker warning: fs/cifsd/smbacl.c:1140 smb_check_perm_dacl() error: we previously assumed 'pntsd' could be null (see line 1137) This patch validate bounds of pntsd buffer. Reported-by: Dan Carpenter <dan.carpenter@oracle.com> Signed-off-by: Namjae Jeon <namjae.jeon@samsung.com> Signed-off-by: Steve French <stfrench@microsoft.com>
This commit is contained in:
parent
bc3fcc9462
commit
50355b0b20
@ -800,9 +800,13 @@ int parse_sec_desc(struct smb_ntsd *pntsd, int acl_len,
|
||||
le32_to_cpu(pntsd->gsidoffset),
|
||||
le32_to_cpu(pntsd->sacloffset), dacloffset);
|
||||
|
||||
if (dacloffset && dacl_ptr)
|
||||
if (dacloffset) {
|
||||
if (end_of_acl <= (char *)dacl_ptr ||
|
||||
end_of_acl < (char *)dacl_ptr + le16_to_cpu(dacl_ptr->size))
|
||||
return -EIO;
|
||||
total_ace_size =
|
||||
le16_to_cpu(dacl_ptr->size) - sizeof(struct smb_acl);
|
||||
}
|
||||
|
||||
pntsd_type = le16_to_cpu(pntsd->type);
|
||||
|
||||
@ -1131,13 +1135,28 @@ int smb_check_perm_dacl(struct ksmbd_conn *conn, struct dentry *dentry,
|
||||
struct smb_ace *others_ace = NULL;
|
||||
struct posix_acl_entry *pa_entry;
|
||||
unsigned int sid_type = SIDOWNER;
|
||||
char *end_of_acl;
|
||||
|
||||
ksmbd_debug(SMB, "check permission using windows acl\n");
|
||||
acl_size = ksmbd_vfs_get_sd_xattr(conn, dentry, &pntsd);
|
||||
if (acl_size <= 0 || (pntsd && !pntsd->dacloffset))
|
||||
if (acl_size <= 0 || !pntsd || !pntsd->dacloffset) {
|
||||
kfree(pntsd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
pdacl = (struct smb_acl *)((char *)pntsd + le32_to_cpu(pntsd->dacloffset));
|
||||
end_of_acl = ((char *)pntsd) + acl_size;
|
||||
if (end_of_acl <= (char *)pdacl) {
|
||||
kfree(pntsd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (end_of_acl < (char *)pdacl + le16_to_cpu(pdacl->size) ||
|
||||
le16_to_cpu(pdacl->size) < sizeof(struct smb_acl)) {
|
||||
kfree(pntsd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!pdacl->num_aces) {
|
||||
if (!(le16_to_cpu(pdacl->size) - sizeof(struct smb_acl)) &&
|
||||
*pdaccess & ~(FILE_READ_CONTROL_LE | FILE_WRITE_DAC_LE)) {
|
||||
@ -1156,6 +1175,8 @@ int smb_check_perm_dacl(struct ksmbd_conn *conn, struct dentry *dentry,
|
||||
for (i = 0; i < le32_to_cpu(pdacl->num_aces); i++) {
|
||||
granted |= le32_to_cpu(ace->access_req);
|
||||
ace = (struct smb_ace *) ((char *)ace + le16_to_cpu(ace->size));
|
||||
if (end_of_acl < (char *)ace)
|
||||
goto err_out;
|
||||
}
|
||||
|
||||
if (!pdacl->num_aces)
|
||||
@ -1177,6 +1198,8 @@ int smb_check_perm_dacl(struct ksmbd_conn *conn, struct dentry *dentry,
|
||||
others_ace = ace;
|
||||
|
||||
ace = (struct smb_ace *) ((char *)ace + le16_to_cpu(ace->size));
|
||||
if (end_of_acl < (char *)ace)
|
||||
goto err_out;
|
||||
}
|
||||
|
||||
if (*pdaccess & FILE_MAXIMAL_ACCESS_LE && found) {
|
||||
|
Loading…
Reference in New Issue
Block a user