Skip to content
This repository was archived by the owner on Jan 23, 2023. It is now read-only.

Commit 803c711

Browse files
committed
Fix loading of NI images on SELinux
This change fixes a problem that prevents us to load crossgen-ed managed assemblies on SELinux when running in confined mode. The problem was that when we load these images, we also apply relocations to their sections and so we temporarily switch section protection from RX to RW and then back. And the switching back (RW -> RX) is something that SELinux doesn't allow. The fix is to switch to RWX before applying to relocations for sections that are RX, since it is allowed then to switch them back to RX. One more change was needed to get the original protection of the section before relocation so that we can set it back later. The PE files are not mapped using VirtualXXXX functions in the PAL and so VirtualProtect doesn't return the proper original protection, but a fixed value instead. So for PAL, we derive the original protection from the section attributes.
1 parent cd48ee1 commit 803c711

File tree

1 file changed

+47
-1
lines changed

1 file changed

+47
-1
lines changed

src/vm/peimagelayout.cpp

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,40 @@ PEImageLayout* PEImageLayout::Map(HANDLE hFile, PEImage* pOwner)
9393
}
9494

9595
#ifdef FEATURE_PREJIT
96+
97+
#ifdef FEATURE_PAL
98+
DWORD SectionCharacteristicsToPageProtection(UINT characteristics)
99+
{
100+
_ASSERTE((characteristics & VAL32(IMAGE_SCN_MEM_READ)) != 0);
101+
DWORD pageProtection;
102+
103+
if ((characteristics & VAL32(IMAGE_SCN_MEM_WRITE)) != 0)
104+
{
105+
if ((characteristics & VAL32(IMAGE_SCN_MEM_EXECUTE)) != 0)
106+
{
107+
pageProtection = PAGE_EXECUTE_READWRITE;
108+
}
109+
else
110+
{
111+
pageProtection = PAGE_READWRITE;
112+
}
113+
}
114+
else
115+
{
116+
if ((characteristics & VAL32(IMAGE_SCN_MEM_EXECUTE)) != 0)
117+
{
118+
pageProtection = PAGE_EXECUTE_READ;
119+
}
120+
else
121+
{
122+
pageProtection = PAGE_READONLY;
123+
}
124+
}
125+
126+
return pageProtection;
127+
}
128+
#endif // FEATURE_PAL
129+
96130
//To force base relocation on Vista (which uses ASLR), unmask IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE
97131
//(0x40) for OptionalHeader.DllCharacteristics
98132
void PEImageLayout::ApplyBaseRelocations()
@@ -154,9 +188,21 @@ void PEImageLayout::ApplyBaseRelocations()
154188
// Unprotect the section if it is not writable
155189
if (((pSection->Characteristics & VAL32(IMAGE_SCN_MEM_WRITE)) == 0))
156190
{
191+
DWORD dwNewProtection = PAGE_READWRITE;
192+
#ifdef FEATURE_PAL
193+
if (((pSection->Characteristics & VAL32(IMAGE_SCN_MEM_EXECUTE)) != 0))
194+
{
195+
// On SELinux, we cannot change protection that doesn't have execute access rights
196+
// to one that has it, so we need to set the protection to RWX instead of RW
197+
dwNewProtection = PAGE_EXECUTE_READWRITE;
198+
}
199+
#endif // FEATURE_PAL
157200
if (!ClrVirtualProtect(pWriteableRegion, cbWriteableRegion,
158-
PAGE_READWRITE, &dwOldProtection))
201+
dwNewProtection, &dwOldProtection))
159202
ThrowLastError();
203+
#ifdef FEATURE_PAL
204+
dwOldProtection = SectionCharacteristicsToPageProtection(pSection->Characteristics);
205+
#endif // FEATURE_PAL
160206
}
161207
}
162208

0 commit comments

Comments
 (0)