Bug 30352 - System call recvfrom() returns "EFAULT" when the receive buffer end at 0x7fffffffefff
Summary: System call recvfrom() returns "EFAULT" when the receive buffer end at 0x7fff...
Status: CLOSED CODE_FIX
Alias: None
Product: Platform Specific/Hardware
Classification: Unclassified
Component: x86-64 (show other bugs)
Hardware: All Linux
: P1 normal
Assignee: platform_x86_64@kernel-bugs.osdl.org
URL: http://bugs.gentoo.org/show_bug.cgi?i...
Keywords:
Depends on:
Blocks:
 
Reported: 2011-03-02 00:29 UTC by Nan Wang
Modified: 2012-05-12 15:02 UTC (History)
2 users (show)

See Also:
Kernel Version: 2.6.36
Subsystem:
Regression: No
Bisected commit-id:


Attachments

Description Nan Wang 2011-03-02 00:29:51 UTC
The following program maps page 0x7fffffffe000 then use recv (translated into
recvfrom in glibc) to receive 4096 bytes. according to strace's result,
recvfrom returns -EFAULT. 

If change 0x7fffffffe000 to 0x7fffffffd000, recvfrom returns successfully.

My kernel version is 2.6.36-gentoo-r5.

#include <stdio.h>
#include <stdlib.h>
#include <memory.h>

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

#include <assert.h>

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

int main()
{
        void * ptr = mmap(LAST_PAGE, PAGE_SIZE, PROT_READ | PROT_WRITE,
                        MAP_ANONYMOUS | MAP_PRIVATE | MAP_FIXED, -1, 0);
        assert(ptr == LAST_PAGE);
        memset(ptr, '\0', PAGE_SIZE);

        void * data = malloc(PAGE_SIZE);
        assert(data != NULL);
        memset(data, '1', PAGE_SIZE);

        int fds[2];
        int err = socketpair(AF_LOCAL, SOCK_STREAM, 0, fds);
        assert(err == 0);

        err = send(fds[0], data, PAGE_SIZE, 0);
        assert(err == PAGE_SIZE);

        err = recv(fds[1], ptr, PAGE_SIZE, MSG_WAITALL);
        perror("recv returns");

        return 0;
}

// vim:ts=4:sw=4



Reproducible: Always

Steps to Reproduce:
1. compile the program;
2. run the generated executable;


Actual Results:  
recv returns: Bad address


Expected Results:  
recv returns: Success
Comment 1 Jiri Olsa 2011-05-22 11:40:39 UTC
fixed by following commit:

x86, 64-bit: Fix copy_[to/from]_user() checks for the userspace address limit
commit 26afb7c661080ae3f1f13ddf7f0c58c4f931c22b
Date:   Thu May 12 16:30:30 2011 +0200

Note You need to log in before you can comment on or make changes to this bug.