This is the mail archive of the
glibc-bugs@sourceware.org
mailing list for the glibc project.
[Bug libc/24699] New: mmap64 with very large offset broken on MIPS64 n32
- From: "patrickdepinguin at gmail dot com" <sourceware-bugzilla at sourceware dot org>
- To: glibc-bugs at sourceware dot org
- Date: Tue, 18 Jun 2019 18:43:07 +0000
- Subject: [Bug libc/24699] New: mmap64 with very large offset broken on MIPS64 n32
- Auto-submitted: auto-generated
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.