--- a/sys/vfs/msdosfs/msdosfs_vfsops.c +++ b/sys/vfs/msdosfs/msdosfs_vfsops.c @@ -53,6 +53,7 @@ #include #include #include +#include #include #include #include @@ -300,6 +301,7 @@ struct byte_bpb710 *b710; uint8_t SecPerClust; u_long clusters; + int64_t devsize; int ronly, error; /* @@ -325,6 +327,12 @@ if (error) return (error); dev = devvp->v_rdev; + /* + * Size of the backing device (slice or whole disk) in DEV_BSIZE + * blocks, or 0 if the device cannot report it. (dev_dpsize() + * returns DEV_BSIZE-scale block counts, see vm_swap.c.) + */ + devsize = dev_dpsize(dev); bp = NULL; /* both used in error_exit */ pmp = NULL; @@ -430,8 +438,10 @@ } if ((off_t)pmp->pm_HugeSectors * pmp->pm_BytesPerSec < - pmp->pm_HugeSectors /* overflow */) { - /* XXX FreeBSD also checks media size in above */ + pmp->pm_HugeSectors /* overflow */ || + (devsize > 0 && + (off_t)pmp->pm_HugeSectors * pmp->pm_BlkPerSec > devsize) + /* past end of volume */) { error = EINVAL; goto error_exit; }