| Index: components/nacl/loader/nonsfi/irt_memory.cc
|
| diff --git a/components/nacl/loader/nonsfi/irt_memory.cc b/components/nacl/loader/nonsfi/irt_memory.cc
|
| index cd7796515db0890b284c218fd4c89d6a0881ff50..06f76ea0326f491934b720b13720a2d84df47d3f 100644
|
| --- a/components/nacl/loader/nonsfi/irt_memory.cc
|
| +++ b/components/nacl/loader/nonsfi/irt_memory.cc
|
| @@ -5,6 +5,7 @@
|
| #include <errno.h>
|
| #include <sys/mman.h>
|
|
|
| +#include "base/logging.h"
|
| #include "components/nacl/loader/nonsfi/irt_interfaces.h"
|
| #include "components/nacl/loader/nonsfi/irt_util.h"
|
| #include "native_client/src/trusted/service_runtime/include/machine/_types.h"
|
| @@ -46,10 +47,20 @@ int NaClFlagsToFlags(int nacl_flags) {
|
|
|
| int IrtMMap(void** addr, size_t len, int prot, int flags,
|
| int fd, nacl_abi_off_t off) {
|
| - void* result =
|
| - mmap(*addr, len, NaClProtToProt(prot), NaClFlagsToFlags(flags), fd, off);
|
| + const int host_prot = NaClProtToProt(prot);
|
| + // On Chrome OS, mmap can fail if PROT_EXEC is set in |host_prot|,
|
| + // but mprotect will allow changing the permissions later.
|
| + // This is because Chrome OS mounts writable filesystems with "noexec".
|
| + void* result = mmap(
|
| + *addr, len, host_prot & ~PROT_EXEC, NaClFlagsToFlags(flags), fd, off);
|
| if (result == MAP_FAILED)
|
| return errno;
|
| + if (host_prot & PROT_EXEC) {
|
| + if (mprotect(result, len, host_prot) != 0) {
|
| + // This aborts here because it cannot easily undo the mmap() call.
|
| + LOG_ERRNO(FATAL) << "IrtMMap: mprotect to turn on PROT_EXEC failed.";
|
| + }
|
| + }
|
|
|
| *addr = result;
|
| return 0;
|
|
|