summaryrefslogtreecommitdiff
path: root/fs
diff options
context:
space:
mode:
authorStian Skjelstad <stian.skjelstad@gmail.com>2021-08-22 11:33:32 +0200
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2021-09-22 11:45:18 +0200
commit97ab90bcbe2a4743b3744c2ec46733acba600566 (patch)
tree217906dbf1621bd5606cc9b778deec9fd8310a62 /fs
parente57af4f1c921f18c4ea2e209c80f226ecddf5918 (diff)
udf_get_extendedattr() had no boundary checks.
[ Upstream commit 58bc6d1be2f3b0ceecb6027dfa17513ec6aa2abb ] When parsing the ExtendedAttr data, malicous or corrupt attribute length could cause kernel hangs and buffer overruns in some special cases. Link: https://lore.kernel.org/r/20210822093332.25234-1-stian.skjelstad@gmail.com Signed-off-by: Stian Skjelstad <stian.skjelstad@gmail.com> Signed-off-by: Jan Kara <jack@suse.cz> Signed-off-by: Sasha Levin <sashal@kernel.org>
Diffstat (limited to 'fs')
-rw-r--r--fs/udf/misc.c13
1 files changed, 11 insertions, 2 deletions
diff --git a/fs/udf/misc.c b/fs/udf/misc.c
index 3949c4bec3a3..e5f4dcde309f 100644
--- a/fs/udf/misc.c
+++ b/fs/udf/misc.c
@@ -173,13 +173,22 @@ struct genericFormat *udf_get_extendedattr(struct inode *inode, uint32_t type,
else
offset = le32_to_cpu(eahd->appAttrLocation);
- while (offset < iinfo->i_lenEAttr) {
+ while (offset + sizeof(*gaf) < iinfo->i_lenEAttr) {
+ uint32_t attrLength;
+
gaf = (struct genericFormat *)&ea[offset];
+ attrLength = le32_to_cpu(gaf->attrLength);
+
+ /* Detect undersized elements and buffer overflows */
+ if ((attrLength < sizeof(*gaf)) ||
+ (attrLength > (iinfo->i_lenEAttr - offset)))
+ break;
+
if (le32_to_cpu(gaf->attrType) == type &&
gaf->attrSubtype == subtype)
return gaf;
else
- offset += le32_to_cpu(gaf->attrLength);
+ offset += attrLength;
}
}