This is the mail archive of the glibc-bugs@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Bug libc/24699] New: mmap64 with very large offset broken on MIPS64 n32


https://sourceware.org/bugzilla/show_bug.cgi?id=24699

            Bug ID: 24699
           Summary: mmap64 with very large offset broken on MIPS64 n32
           Product: glibc
           Version: 2.26
            Status: UNCONFIRMED
          Severity: normal
          Priority: P2
         Component: libc
          Assignee: unassigned at sourceware dot org
          Reporter: patrickdepinguin at gmail dot com
                CC: drepper.fsp at gmail dot com
  Target Milestone: ---

Corresponding mail discussion:
https://www.sourceware.org/ml/libc-alpha/2019-06/msg00280.html

Bug opened as this is a user-visible problem, as discussed with Florian Weimer.

---

In glibc 2.26, a change was made to the behavior of mmap64, as a fix
for bug #21270 (mmap64 silently truncates large offset values), via
commit 158d5fa0e1906e7810bdc6ecb7bf598dcc3cd17d.
Practically, with the new behavior, doing mmap64 with an offset larger
than 1<<44 now fails with errno=EINVAL. The reasoning in this bug is
that offsets greater than 1<<44  are silently truncated, and so better
to fail early.

However, I have several cases in embedded applications where such
mmap64 with large offset values is performed, and it worked correctly
(< 2.26). In these applications, a physical memory region is mapped
into the virtual address space, by performing an mmap64 on /dev/mem.
The offset is very large because this is accessing devices high up in
the memory range.

This is on MIPS64 with the n32 ABI.

Example code is:

#define _GNU_SOURCE
#define _LARGEFILE_SOURCE
#define _LARGEFILE64_SOURCE
#define _FILE_OFFSET_BITS 64
#include <stdio.h>
#include <sys/mman.h>
#include <errno.h>
#include <stdint.h>
#include <fcntl.h>
#include <inttypes.h>

int main(void)
{
    off_t physical_base = 0x100001a000000ull;
    size_t length = 0x1000;
    volatile uint32_t* virtual_base;

    int fd = open("/dev/mem",O_RDWR);
    if (fd < 0) {
        perror("cannot open /dev/mem");
        return 1;
    }

    errno = 0;
    virtual_base = (volatile uint32_t*) mmap64(0, length,
PROT_READ|PROT_WRITE, MAP_SHARED, fd, physical_base);
    if (virtual_base == (volatile uint32_t *)-1) {
        printf("Mapping failed, errno=%d\n", errno);
        return 1;
    }
    printf("Virtual address: %p\n", virtual_base);
    return 0;
}



On a toolchain using gcc 4.7, glibc 2.16, the above gives a valid
virtual address.
On a toolchain using gcc 7.3, glibc 2.27, the mapping fails with
errno=22 (EINVAL) and virtual_base=-1 (0xffffffff).

-- 
You are receiving this mail because:
You are on the CC list for the bug.

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]