The logic in mmrw() to check whether an address is within direct
map was the wrong way around. The && prevented an EFAULT error and
could pass userland addresses as kernel source to copyout(9). The
kernel could crash with protection fault due to an invalid offset
when reading /dev/kmem.
Also make the range checks stricter. Not only the start address
must be valid, but also the end address must be within the region
to be copied.
Note that sysctl kern.allowkmem=0 makes the bug unreachable by
default.
OK deraadt@