From 9b9d243bea9703f988528b95b6b5bf01b44fb75a Mon Sep 17 00:00:00 2001 From: whitequark Date: Tue, 26 May 2020 19:14:52 +0000 Subject: [PATCH] Make munmap() actually work. (#198) Before this commit, he header of a mapped area, `struct map`, was defined as follows: struct map { int prot; int flags; off_t offset; size_t length; char body[]; }; Because the size and alignment of an `off_t` is 8 bytes, the entire structure was padded to 24 bytes. However, the offset of `body` into `struct map` was only 20 bytes. Therefore the code in mmap() and munmap() did not agree on the offset from header to body. This commit changes mmap() to skip the entire header, which is what munmap() expects and what the size calculation uses. --- libc-bottom-half/mman/mman.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/libc-bottom-half/mman/mman.c b/libc-bottom-half/mman/mman.c index 1b806ff8d..be304bccc 100644 --- a/libc-bottom-half/mman/mman.c +++ b/libc-bottom-half/mman/mman.c @@ -17,7 +17,6 @@ struct map { int flags; off_t offset; size_t length; - char body[]; }; void *mmap(void *addr, size_t length, int prot, int flags, @@ -84,8 +83,9 @@ void *mmap(void *addr, size_t length, int prot, int flags, // Initialize the main memory buffer, either with the contents of a file, // or with zeros. + addr = map + 1; if ((flags & MAP_ANON) == 0) { - char *body = map->body; + char *body = (char *)addr; while (length > 0) { const ssize_t nread = pread(fd, body, length, offset); if (nread < 0) { @@ -100,10 +100,10 @@ void *mmap(void *addr, size_t length, int prot, int flags, body += (size_t)nread; } } else { - memset(map->body, 0, length); + memset(addr, 0, length); } - return map->body; + return addr; } int munmap(void *addr, size_t length) {