{"record":{"id":"59994501286a9f11","repo":"wasmerio/wasmer","slug":"unable-to-make-memory-readonly-and-executable","errorCode":null,"errorMessage":"unable to make memory readonly and executable","messagePattern":"unable to make memory readonly and executable","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"lib/compiler/src/engine/code_memory.rs","lineNumber":173,"sourceCode":"            executable_section_result,\n            data_section_result,\n        ))\n    }\n\n    /// Apply the page permissions.\n    pub fn publish(&mut self) {\n        if self.mmap.is_empty() || self.start_of_nonexecutable_pages == 0 {\n            return;\n        }\n        assert!(self.mmap.len() >= self.start_of_nonexecutable_pages);\n        unsafe {\n            region::protect(\n                self.mmap.as_mut_ptr(),\n                self.start_of_nonexecutable_pages,\n                region::Protection::READ_EXECUTE,\n            )\n        }\n        .expect(\"unable to make memory readonly and executable\");\n    }\n\n    /// Calculates the allocation size of the given compiled function.\n    fn function_allocation_size<'a>(func: &'a impl FunctionBodyLike<'a>) -> usize {\n        match &func.unwind_info().map(|o| o.get()) {\n            Some(CompiledFunctionUnwindInfoReference::WindowsX64(info)) => {\n                // Windows unwind information is required to be emitted into code memory\n                // This is because it must be a positive relative offset from the start of the memory\n                // Account for necessary unwind information alignment padding (32-bit alignment)\n                func.body().len().next_multiple_of(4) + info.len()\n            }\n            _ => func.body().len(),\n        }\n    }\n\n    /// Copies the data of the compiled function to the given buffer.\n    ///\n    /// This will also add the function to the current function table.","sourceCodeStart":155,"sourceCodeEnd":191,"githubUrl":"https://github.com/wasmerio/wasmer/blob/8c4b9ee9d33fb2068863fbb3d328683e7e6ff7f5/lib/compiler/src/engine/code_memory.rs#L155-L191","documentation":"After compiling code into code_memory, publish() makes previously-written pages non-writable by changing protection from RW to READ_EXECUTE via the `region` crate; it uses .expect() because making JIT memory executable is considered essential. A failure means the OS refused mprotect/VirtualProtect on the JIT region.","triggerScenarios":"Calling publish() (during module compilation/artifact finalization) when mprotect fails: page-alignment mismatch, mmap region already protected differently, SELinux/AppArmor restrictions, hardened kernels with W^X enforcement (e.g. PaX), or out-of-memory/address-space conditions.","commonSituations":"Environments with SELinux denying execmem, Docker/seccomp profiles blocking mprotect with PROT_EXEC, kernels with strict W^X policies, or running under hardened security modules while JIT-compiling.","solutions":["Relax the security policy: allow execmem in SELinux (`setsebool` or adjust policy) or seccomp profile for the container","Disable strict W^X enforcement (kernel.pax.softmode or hardened kernel option) if policy permits","Run in an environment that allows RWX/RT→RX transitions for JIT memory","Upgrade wasmer; if the failure is caused by an alignment/length bug, newer versions may fix it"],"exampleFix":null,"handlingStrategy":"retry","validationCode":"// Precheck: try an mprotect on a scratch RWX page before JIT compilation\nlet test = region::protect(test_page, 4096, region::Protection::READ_EXECUTE);\nif test.is_err() { return Err(anyhow!(\"environment blocks executable memory (execmem/W^X)\")); }","typeGuard":null,"tryCatchPattern":"std::panic::catch_unwind(|| code_memory.publish())\n    .map_err(|_| anyhow::anyhow!(\"JIT memory protection failed; environment forbids executable pages\"))?","preventionTips":["Verify the container/SELinux/seccomp policy allows PROT_EXEC allocations before deploying JIT workloads","Run with a profile that permits execmem (e.g. docker seccomp unconfined for the compiler service)","Test deployment hosts for hardened W^X kernels (PaX/grsecurity) early","Keep a sys-jit-free fallback (interpreter/dylib artifact loading) if policies are strict"],"tags":["memory-protection","jit","mprotect","panic","compiler"],"backgroundTag":"jit-memory-protect-failed","analyzedSha":"8c4b9ee9d33fb2068863fbb3d328683e7e6ff7f5","analyzedAt":"2026-09-01T23:06:31.009Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-09T06:17:21.866Z"}