diff options
| author | John Baldwin <jhb@FreeBSD.org> | 2023-08-04 23:40:19 +0000 |
|---|---|---|
| committer | John Baldwin <jhb@FreeBSD.org> | 2023-09-06 21:56:09 +0000 |
| commit | 202c1d76218695ec094f289dbb23e96310eae2c1 (patch) | |
| tree | a5582cadc520aabf54033945c3c652d589ce0e01 | |
| parent | 21ccba43f511cc4089899619b5a85e6d83a200dc (diff) | |
| download | src-202c1d76218695ec094f289dbb23e96310eae2c1.tar.gz src-202c1d76218695ec094f289dbb23e96310eae2c1.zip | |
udf: Reject read requests with an invalid length
- If the size is negative or if rounding it up to a multiple of
the block size overflows, fail the read request with ERANGE.
- While here, add a sanity check that the ICB length for the root
directory is at least as long as a minimum-sized file entry.
PR: 257768
Reported by: Robert Morris <rtm@lcs.mit.edu>
MFC after: 1 week
Sponsored by: FreeBSD Foundation
Differential Revision: https://reviews.freebsd.org/D41220
(cherry picked from commit c70e615051b00671d54651d99af5cdec4b091d92)
| -rw-r--r-- | sys/fs/udf/udf.h | 4 | ||||
| -rw-r--r-- | sys/fs/udf/udf_vfsops.c | 5 |
2 files changed, 8 insertions, 1 deletions
diff --git a/sys/fs/udf/udf.h b/sys/fs/udf/udf.h index 31e63f1ffb05..c8f5191546c2 100644 --- a/sys/fs/udf/udf.h +++ b/sys/fs/udf/udf.h @@ -95,8 +95,10 @@ struct ifid { MALLOC_DECLARE(M_UDFFENTRY); static __inline int -udf_readdevblks(struct udf_mnt *udfmp, int sector, int size, struct buf **bp) +udf_readdevblks(struct udf_mnt *udfmp, daddr_t sector, int size, struct buf **bp) { + if (size < 0 || size + udfmp->bmask < size) + return (ERANGE); return (RDSECTOR(udfmp->im_devvp, sector, (size + udfmp->bmask) & ~udfmp->bmask, bp)); } diff --git a/sys/fs/udf/udf_vfsops.c b/sys/fs/udf/udf_vfsops.c index eb9e6f3fc370..efc216bc7635 100644 --- a/sys/fs/udf/udf_vfsops.c +++ b/sys/fs/udf/udf_vfsops.c @@ -480,6 +480,11 @@ udf_mountfs(struct vnode *devvp, struct mount *mp) */ sector = le32toh(udfmp->root_icb.loc.lb_num) + udfmp->part_start; size = le32toh(udfmp->root_icb.len); + if (size < UDF_FENTRY_SIZE) { + printf("Invalid root directory file entry length %u\n", + size); + goto bail; + } if ((error = udf_readdevblks(udfmp, sector, size, &bp)) != 0) { printf("Cannot read sector %d\n", sector); goto bail; |
