aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Baldwin <jhb@FreeBSD.org>2023-08-04 23:40:19 +0000
committerJohn Baldwin <jhb@FreeBSD.org>2023-09-06 20:02:33 +0000
commit0db7f4b419dbaa2c23a737393d35564cd0b2f35a (patch)
tree62aa2722d22b8655d730483f9b48979247236b13
parentf9c32827759b2e1dda97d91f69d70673f5c9393b (diff)
downloadsrc-0db7f4b419dbaa2c23a737393d35564cd0b2f35a.tar.gz
src-0db7f4b419dbaa2c23a737393d35564cd0b2f35a.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.h4
-rw-r--r--sys/fs/udf/udf_vfsops.c5
2 files changed, 8 insertions, 1 deletions
diff --git a/sys/fs/udf/udf.h b/sys/fs/udf/udf.h
index 33bf4539c41b..507c75692433 100644
--- a/sys/fs/udf/udf.h
+++ b/sys/fs/udf/udf.h
@@ -97,8 +97,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 af249e91ed9d..0e450da83808 100644
--- a/sys/fs/udf/udf_vfsops.c
+++ b/sys/fs/udf/udf_vfsops.c
@@ -478,6 +478,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;