diff options
author | jhb <jhb@FreeBSD.org> | 2016-12-02 19:02:12 +0000 |
---|---|---|
committer | jhb <jhb@FreeBSD.org> | 2016-12-02 19:02:12 +0000 |
commit | f264e4e233ec1083a30cb6b50d0d0ac53cc6fb86 (patch) | |
tree | 640c3f7b80a315fde7c31532ac9cf3676da35285 /sys/i386 | |
parent | 5c325f007b252a394e014fef7ff608a260222247 (diff) | |
download | FreeBSD-src-f264e4e233ec1083a30cb6b50d0d0ac53cc6fb86.zip FreeBSD-src-f264e4e233ec1083a30cb6b50d0d0ac53cc6fb86.tar.gz |
MFC 303753,308004: Add bounds checking on addresses used with /dev/mem.
303753:
Don't permit mappings of invalid physical addresses on amd64 via /dev/mem.
308004:
MFamd64: Add bounds checks on addresses used with /dev/mem.
Reject attempts to read from or memory map offsets in /dev/mem that are
beyond the maximum-supported physical address of the current CPU.
Diffstat (limited to 'sys/i386')
-rw-r--r-- | sys/i386/i386/mem.c | 13 |
1 files changed, 9 insertions, 4 deletions
diff --git a/sys/i386/i386/mem.c b/sys/i386/i386/mem.c index b036bd3..003f207f 100644 --- a/sys/i386/i386/mem.c +++ b/sys/i386/i386/mem.c @@ -108,8 +108,11 @@ memrw(struct cdev *dev, struct uio *uio, int flags) continue; } if (dev2unit(dev) == CDEV_MINOR_MEM) { - pa = uio->uio_offset; - pa &= ~PAGE_MASK; + if (uio->uio_offset > cpu_getmaxphyaddr()) { + error = EFAULT; + break; + } + pa = trunc_page(uio->uio_offset); } else { /* * Extract the physical page since the mapping may @@ -161,9 +164,11 @@ int memmmap(struct cdev *dev, vm_ooffset_t offset, vm_paddr_t *paddr, int prot __unused, vm_memattr_t *memattr __unused) { - if (dev2unit(dev) == CDEV_MINOR_MEM) + if (dev2unit(dev) == CDEV_MINOR_MEM) { + if (offset > cpu_getmaxphyaddr()) + return (-1); *paddr = offset; - else if (dev2unit(dev) == CDEV_MINOR_KMEM) + } else if (dev2unit(dev) == CDEV_MINOR_KMEM) *paddr = vtophys(offset); /* else panic! */ return (0); |