diff --git a/src/library_syscall.js b/src/library_syscall.js index 30a71794658c9..aa78173df7bcb 100644 --- a/src/library_syscall.js +++ b/src/library_syscall.js @@ -259,7 +259,7 @@ var SyscallsLibrary = { #if CAN_ADDRESS_2GB ptr >>>= 0; #endif - SYSCALLS.mappings[ptr] = { malloc: ptr, len: len, allocated: allocated, fd: fd, flags: flags, offset: off }; + SYSCALLS.mappings[ptr] = { malloc: ptr, len: len, allocated: allocated, fd: fd, prot: prot, flags: flags, offset: off }; return ptr; }, @@ -281,7 +281,9 @@ var SyscallsLibrary = { if (len === info.len) { #if FILESYSTEM && SYSCALLS_REQUIRE_FILESYSTEM var stream = FS.getStream(info.fd); - SYSCALLS.doMsync(addr, stream, len, info.flags, info.offset); + if (info.prot & {{{ cDefine('PROT_WRITE') }}}) { + SYSCALLS.doMsync(addr, stream, len, info.flags, info.offset); + } FS.munmap(stream); #else #if ASSERTIONS diff --git a/tests/fs/test_mmap.c b/tests/fs/test_mmap.c index 263ccca8e1930..9fa4e283cf833 100644 --- a/tests/fs/test_mmap.c +++ b/tests/fs/test_mmap.c @@ -89,6 +89,44 @@ int main() { fclose(fd); } + // Use mmap to read out.txt and modify the contents in memory, + // but make sure it's not overwritten on munmap + { + const char* readonlytext = "readonly mmap\0"; + const char* text = "write mmap\0"; + const char* path = "/yolo/outreadonly.txt"; + size_t readonlytextsize = strlen(readonlytext); + size_t textsize = strlen(text); + + int fd = open(path, O_RDWR | O_CREAT, (mode_t)0600); + // write contents to the file ( we don't want this to be overwritten on munmap ) + assert(write(fd, readonlytext, readonlytextsize) != -1); + close(fd); + + fd = open(path, O_RDWR); + char *map = (char*)mmap(0, textsize, PROT_READ, MAP_SHARED, fd, 0); + assert(map != MAP_FAILED); + + for (size_t i = 0; i < textsize; i++) { + map[i] = text[i]; + } + + assert(munmap(map, textsize) != -1); + close(fd); + } + + { + FILE* fd = fopen("/yolo/outreadonly.txt", "r"); + if (fd == NULL) { + printf("failed to open /yolo/outreadonly.txt\n"); + return 1; + } + char buffer[14]; + fread(buffer, 1, 15, fd); + printf("/yolo/outreadonly.txt content=%s\n", buffer); + fclose(fd); + } + // MAP_PRIVATE { const char* text = "written mmap"; diff --git a/tests/fs/test_mmap.out b/tests/fs/test_mmap.out index c97319ba9137e..30d93994299dd 100644 --- a/tests/fs/test_mmap.out +++ b/tests/fs/test_mmap.out @@ -1,4 +1,5 @@ /yolo/in.txt content=mmap ftw! /yolo/out.txt content=written mmap +/yolo/outreadonly.txt content=readonly mmap /yolo/private.txt content= /yolo/sharedoffset.txt content=written shared mmap with offset 32768