diff --git a/src/vm/peimagelayout.cpp b/src/vm/peimagelayout.cpp index 80d2b8747aac..b5d50b58c6d6 100644 --- a/src/vm/peimagelayout.cpp +++ b/src/vm/peimagelayout.cpp @@ -93,6 +93,40 @@ PEImageLayout* PEImageLayout::Map(HANDLE hFile, PEImage* pOwner) } #ifdef FEATURE_PREJIT + +#ifdef FEATURE_PAL +DWORD SectionCharacteristicsToPageProtection(UINT characteristics) +{ + _ASSERTE((characteristics & VAL32(IMAGE_SCN_MEM_READ)) != 0); + DWORD pageProtection; + + if ((characteristics & VAL32(IMAGE_SCN_MEM_WRITE)) != 0) + { + if ((characteristics & VAL32(IMAGE_SCN_MEM_EXECUTE)) != 0) + { + pageProtection = PAGE_EXECUTE_READWRITE; + } + else + { + pageProtection = PAGE_READWRITE; + } + } + else + { + if ((characteristics & VAL32(IMAGE_SCN_MEM_EXECUTE)) != 0) + { + pageProtection = PAGE_EXECUTE_READ; + } + else + { + pageProtection = PAGE_READONLY; + } + } + + return pageProtection; +} +#endif // FEATURE_PAL + //To force base relocation on Vista (which uses ASLR), unmask IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE //(0x40) for OptionalHeader.DllCharacteristics void PEImageLayout::ApplyBaseRelocations() @@ -154,9 +188,21 @@ void PEImageLayout::ApplyBaseRelocations() // Unprotect the section if it is not writable if (((pSection->Characteristics & VAL32(IMAGE_SCN_MEM_WRITE)) == 0)) { + DWORD dwNewProtection = PAGE_READWRITE; +#ifdef FEATURE_PAL + if (((pSection->Characteristics & VAL32(IMAGE_SCN_MEM_EXECUTE)) != 0)) + { + // On SELinux, we cannot change protection that doesn't have execute access rights + // to one that has it, so we need to set the protection to RWX instead of RW + dwNewProtection = PAGE_EXECUTE_READWRITE; + } +#endif // FEATURE_PAL if (!ClrVirtualProtect(pWriteableRegion, cbWriteableRegion, - PAGE_READWRITE, &dwOldProtection)) + dwNewProtection, &dwOldProtection)) ThrowLastError(); +#ifdef FEATURE_PAL + dwOldProtection = SectionCharacteristicsToPageProtection(pSection->Characteristics); +#endif // FEATURE_PAL } }