svn commit: r366005 - head/sys/fs/udf
Mark Johnston
markj at FreeBSD.org
Tue Sep 22 17:05:01 UTC 2020
Author: markj
Date: Tue Sep 22 17:05:01 2020
New Revision: 366005
URL: https://svnweb.freebsd.org/changeset/base/366005
Log:
udf: Validate the full file entry length
Otherwise a corrupted file entry containing invalid extended attribute
lengths or allocation descriptor lengths can trigger an overflow when
the file entry is loaded.
admbug: 965
PR: 248613
Reported by: C Turt <ecturt at gmail.com>
MFC after: 3 days
Sponsored by: The FreeBSD Foundation
Modified:
head/sys/fs/udf/udf_vfsops.c
Modified: head/sys/fs/udf/udf_vfsops.c
==============================================================================
--- head/sys/fs/udf/udf_vfsops.c Tue Sep 22 16:18:31 2020 (r366004)
+++ head/sys/fs/udf/udf_vfsops.c Tue Sep 22 17:05:01 2020 (r366005)
@@ -589,6 +589,7 @@ udf_vget(struct mount *mp, ino_t ino, int flags, struc
struct vnode *vp;
struct udf_node *unode;
struct file_entry *fe;
+ uint32_t lea, lad;
int error, sector, size;
error = vfs_hash_get(mp, ino, flags, curthread, vpp, NULL, NULL);
@@ -644,31 +645,37 @@ udf_vget(struct mount *mp, ino_t ino, int flags, struc
devvp = udfmp->im_devvp;
if ((error = RDSECTOR(devvp, sector, udfmp->bsize, &bp)) != 0) {
printf("Cannot read sector %d\n", sector);
- vgone(vp);
- vput(vp);
- brelse(bp);
- *vpp = NULL;
- return (error);
+ goto error;
}
+ /*
+ * File entry length validation.
+ */
fe = (struct file_entry *)bp->b_data;
if (udf_checktag(&fe->tag, TAGID_FENTRY)) {
printf("Invalid file entry!\n");
- vgone(vp);
- vput(vp);
- brelse(bp);
- *vpp = NULL;
- return (ENOMEM);
+ error = ENOMEM;
+ goto error;
}
- size = UDF_FENTRY_SIZE + le32toh(fe->l_ea) + le32toh(fe->l_ad);
+ lea = le32toh(fe->l_ea);
+ lad = le32toh(fe->l_ad);
+ if (lea > udfmp->bsize || lad > udfmp->bsize) {
+ printf("Invalid EA and AD lengths %u, %u\n", lea, lad);
+ error = EIO;
+ goto error;
+ }
+ size = UDF_FENTRY_SIZE + lea + lad;
+ if (size > udfmp->bsize) {
+ printf("Invalid file entry size %u\n", size);
+ error = EIO;
+ goto error;
+ }
+
unode->fentry = malloc(size, M_UDFFENTRY, M_NOWAIT | M_ZERO);
if (unode->fentry == NULL) {
printf("Cannot allocate file entry block\n");
- vgone(vp);
- vput(vp);
- brelse(bp);
- *vpp = NULL;
- return (ENOMEM);
+ error = ENOMEM;
+ goto error;
}
bcopy(bp->b_data, unode->fentry, size);
@@ -713,6 +720,13 @@ udf_vget(struct mount *mp, ino_t ino, int flags, struc
*vpp = vp;
return (0);
+
+error:
+ vgone(vp);
+ vput(vp);
+ brelse(bp);
+ *vpp = NULL;
+ return (error);
}
static int
More information about the svn-src-all
mailing list