ntfs3: Add bounds checking to mi_enum_attr()

[ Upstream commit 556bdf27c2dd5c74a9caacbe524b943a6cd42d99 ]

Added bounds checking to make sure that every attr don't stray beyond
valid memory region.

Signed-off-by: lei lu <llfamsec@gmail.com>
Signed-off-by: Konstantin Komarov <almaz.alexandrovich@paragon-software.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:
lei lu 2024-08-23 21:39:44 +08:00 committed by Greg Kroah-Hartman
parent 3c73746c22
commit 22cdf3be7d

View file

@ -223,28 +223,19 @@ struct ATTRIB *mi_enum_attr(struct mft_inode *mi, struct ATTRIB *attr)
prev_type = 0; prev_type = 0;
attr = Add2Ptr(rec, off); attr = Add2Ptr(rec, off);
} else { } else {
/* Check if input attr inside record. */ /*
* We don't need to check previous attr here. There is
* a bounds checking in the previous round.
*/
off = PtrOffset(rec, attr); off = PtrOffset(rec, attr);
if (off >= used)
return NULL;
asize = le32_to_cpu(attr->size); asize = le32_to_cpu(attr->size);
if (asize < SIZEOF_RESIDENT) {
/* Impossible 'cause we should not return such attribute. */
return NULL;
}
/* Overflow check. */
if (off + asize < off)
return NULL;
prev_type = le32_to_cpu(attr->type); prev_type = le32_to_cpu(attr->type);
attr = Add2Ptr(attr, asize); attr = Add2Ptr(attr, asize);
off += asize; off += asize;
} }
asize = le32_to_cpu(attr->size);
/* Can we use the first field (attr->type). */ /* Can we use the first field (attr->type). */
if (off + 8 > used) { if (off + 8 > used) {
static_assert(ALIGN(sizeof(enum ATTR_TYPE), 8) == 8); static_assert(ALIGN(sizeof(enum ATTR_TYPE), 8) == 8);
@ -265,6 +256,12 @@ struct ATTRIB *mi_enum_attr(struct mft_inode *mi, struct ATTRIB *attr)
if (t32 < prev_type) if (t32 < prev_type)
return NULL; return NULL;
asize = le32_to_cpu(attr->size);
if (asize < SIZEOF_RESIDENT) {
/* Impossible 'cause we should not return such attribute. */
return NULL;
}
/* Check overflow and boundary. */ /* Check overflow and boundary. */
if (off + asize < off || off + asize > used) if (off + asize < off || off + asize > used)
return NULL; return NULL;