emscripten-core / emscripten-core/emscripten

Protection flag of mmap doesn't work as expected

Open
#21,707 2 comments 0 reactions 0 assignees View on GitHub
Dominant language
C++
Stars
27.6k
Forks
3.6k
Avg merge
1d 1h
Merged PRs (30d)
105

Description

Please include the following in your bug report:

**Version of emscripten/emsdk:**
emcc version: 3.1.54

**Failing command line in full:**
`emcc test_mmap_prot.cpp -o main.js; node main.js`

**Full link command and output with `-v` appended:**

Hi, I tried to use `mmap` in the program and tried to set the `prot` parameter as `PROT_READ`, expecting to set the memory as read-only. However, I found even though I set the parameter as `PROT_READ` only, the corresponding memory is still writable. Here is the code example:

```cpp
// test_mmap_prot.cpp
#include
#include
#include
#include
#include

int main() {
int len = 10 * sizeof(int);
int offset = 0;
int* ptr = (int*) mmap(nullptr, len, PROT_READ, MAP_ANONYMOUS, -1, offset);
ptr[0] = 10;
std::cout << "ptr[0] is: " << ptr[0] << std::endl;
return 0;
}
```
If I compile it natively with gcc using `g++ test_mmap_prot.cpp -o main; ./main`, when runing the code I got the `Segmentation fault (core dumped)`. It meets my expect because the program tries to write a read-only memory.

However, if I compile and run with `emcc test_mmap_prot.cpp -o main.js; node main.js`, I get the printed message `ptr[0] is: 10`, meaning that the read-only memory is written successfully. And this is not as expected.

The code above is just a simple example with anonymous mapping. In other specific usage cases, I tried to use `mmap` to map with a file descriptor and set the `prot` as `PROT_READ`, and the memory is also writable. It's like the following:
```cpp
// emcc test_mmap_prot_2.cpp -o main.js; node main.js
#include
#include
#include
#include
#include

int main() {
const char* name = "/shared_file";
int len = 10 * sizeof(int);
int offset = 0;
int fd = shm_open(name, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR);
if (fd == -1) {
exit(0);
}
ftruncate(fd, off_t(len));
int* ptr = (int*) mmap(nullptr, len, PROT_READ, MAP_SHARED, fd, offset);

ptr[0] = 10;

std::cout << "ptr[0] is: " << ptr[0] << std::endl;
shm_unlink(name);
return 0;
}
```
And by compiling and running it with `emcc test_mmap_prot_2.cpp -o main.js; node main.js`, I found the read-only memory can still be written successfully (of course if I compiled using gcc and run natively, it still got segmentation fault as expected). So I guess it is a general issue of `mmap`.

Thank you!

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.