linux/arch/x86
Jiri Olsa 26afb7c661 x86, 64-bit: Fix copy_[to/from]_user() checks for the userspace address limit
As reported in BZ #30352:

  https://bugzilla.kernel.org/show_bug.cgi?id=30352

there's a kernel bug related to reading the last allowed page on x86_64.

The _copy_to_user() and _copy_from_user() functions use the following
check for address limit:

  if (buf + size >= limit)
	fail();

while it should be more permissive:

  if (buf + size > limit)
	fail();

That's because the size represents the number of bytes being
read/write from/to buf address AND including the buf address.
So the copy function will actually never touch the limit
address even if "buf + size == limit".

Following program fails to use the last page as buffer
due to the wrong limit check:

 #include <sys/mman.h>
 #include <sys/socket.h>
 #include <assert.h>

 #define PAGE_SIZE       (4096)
 #define LAST_PAGE       ((void*)(0x7fffffffe000))

 int main()
 {
        int fds[2], err;
        void * ptr = mmap(LAST_PAGE, PAGE_SIZE, PROT_READ | PROT_WRITE,
                          MAP_ANONYMOUS | MAP_PRIVATE | MAP_FIXED, -1, 0);
        assert(ptr == LAST_PAGE);
        err = socketpair(AF_LOCAL, SOCK_STREAM, 0, fds);
        assert(err == 0);
        err = send(fds[0], ptr, PAGE_SIZE, 0);
        perror("send");
        assert(err == PAGE_SIZE);
        err = recv(fds[1], ptr, PAGE_SIZE, MSG_WAITALL);
        perror("recv");
        assert(err == PAGE_SIZE);
        return 0;
 }

The other place checking the addr limit is the access_ok() function,
which is working properly. There's just a misleading comment
for the __range_not_ok() macro - which this patch fixes as well.

The last page of the user-space address range is a guard page and
Brian Gerst observed that the guard page itself due to an erratum on K8 cpus
(#121 Sequential Execution Across Non-Canonical Boundary Causes Processor
Hang).

However, the test code is using the last valid page before the guard page.
The bug is that the last byte before the guard page can't be read
because of the off-by-one error. The guard page is left in place.

This bug would normally not show up because the last page is
part of the process stack and never accessed via syscalls.

Signed-off-by: Jiri Olsa <jolsa@redhat.com>
Acked-by: Brian Gerst <brgerst@gmail.com>
Acked-by: Linus Torvalds <torvalds@linux-foundation.org>
Cc: <stable@kernel.org>
Link: http://lkml.kernel.org/r/1305210630-7136-1-git-send-email-jolsa@redhat.com
Signed-off-by: Ingo Molnar <mingo@elte.hu>
2011-05-18 12:49:00 +02:00
..
boot x86, setup: When probing memory with e801, use ax/bx as a pair 2011-04-25 14:52:37 -07:00
configs
crypto crypto: aesni-intel - fixed problem with packets that are not multiple of 64bytes 2011-03-27 10:29:39 +08:00
ia32 x86: mark associated mm when running a task in 32 bit compatibility mode 2011-03-23 16:36:53 -04:00
include/asm x86, 64-bit: Fix copy_[to/from]_user() checks for the userspace address limit 2011-05-18 12:49:00 +02:00
kernel x86, alternative, doc: Add comment for applying alternatives order 2011-05-17 15:40:25 -07:00
kvm KVM: move and fix substitue search for missing CPUID entries 2011-04-06 13:15:56 +03:00
lguest x86: Fix common misspellings 2011-03-18 10:39:30 +01:00
lib x86, 64-bit: Fix copy_[to/from]_user() checks for the userspace address limit 2011-05-18 12:49:00 +02:00
math-emu
mm x86, NUMA: Fix empty memblk detection in numa_cleanup_meminfo() 2011-05-01 19:15:11 +02:00
oprofile Merge branch 'core' of git://git.kernel.org/pub/scm/linux/kernel/git/rric/oprofile into perf/urgent 2011-03-29 09:32:28 +02:00
pci Merge branch 'linux-next' of git://git.kernel.org/pub/scm/linux/kernel/git/jbarnes/pci-2.6 2011-03-18 10:56:44 -07:00
platform x86: ce4100: Configure IOAPIC pins for USB and SATA to level type 2011-04-28 11:38:30 +02:00
power
tools
vdso mm: arch: rename in_gate_area_no_task to in_gate_area_no_mm 2011-03-23 16:36:55 -04:00
video
xen xen: mask_rw_pte mark RO all pagetable pages up to pgt_buf_top 2011-05-02 16:33:52 -04:00
.gitignore
Kbuild
Kconfig Merge branch 'syscore' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/suspend-2.6 2011-03-25 21:07:59 -07:00
Kconfig.cpu x86: Fix common misspellings 2011-03-18 10:39:30 +01:00
Kconfig.debug kconfig: rename CONFIG_EMBEDDED to CONFIG_EXPERT 2011-01-20 17:02:05 -08:00
Makefile
Makefile_32.cpu