Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Disable W^X in Rosetta emulated x64 containers on macOS #102509

Merged
merged 4 commits into from
May 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/coreclr/minipal/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
include_directories(.)
include_directories(${CLR_SRC_NATIVE_DIR})
if (CLR_CMAKE_HOST_UNIX)
add_subdirectory(Unix)
else (CLR_CMAKE_HOST_UNIX)
Expand Down
33 changes: 10 additions & 23 deletions src/coreclr/minipal/Unix/doublemapping.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,24 +20,13 @@
#define memfd_create(...) syscall(__NR_memfd_create, __VA_ARGS__)
#endif // TARGET_LINUX && !MFD_CLOEXEC
#include "minipal.h"
#include "minipal/cpufeatures.h"

#if defined(TARGET_OSX) && defined(TARGET_AMD64)
#include <mach/mach.h>
#include <sys/sysctl.h>
#ifdef TARGET_OSX

bool IsProcessTranslated()
{
int ret = 0;
size_t size = sizeof(ret);
if (sysctlbyname("sysctl.proc_translated", &ret, &size, NULL, 0) == -1)
{
return false;
}
return ret == 1;
}
#endif // TARGET_OSX && TARGET_AMD64
#include <mach/mach.h>

#ifndef TARGET_OSX
#else // TARGET_OSX

#ifdef TARGET_64BIT
static const off_t MaxDoubleMappedSize = 2048ULL*1024*1024*1024;
Expand All @@ -49,6 +38,12 @@ static const off_t MaxDoubleMappedSize = UINT_MAX;

bool VMToOSInterface::CreateDoubleMemoryMapper(void** pHandle, size_t *pMaxExecutableCodeSize)
{
if (minipal_detect_rosetta())
{
// Rosetta doesn't support double mapping correctly
return false;
}

#ifndef TARGET_OSX

#ifdef TARGET_FREEBSD
Expand Down Expand Up @@ -78,14 +73,6 @@ bool VMToOSInterface::CreateDoubleMemoryMapper(void** pHandle, size_t *pMaxExecu
*pHandle = (void*)(size_t)fd;
#else // !TARGET_OSX

#ifdef TARGET_AMD64
if (IsProcessTranslated())
{
// Rosetta doesn't support double mapping correctly
return false;
}
#endif // TARGET_AMD64

*pMaxExecutableCodeSize = SIZE_MAX;
*pHandle = NULL;
#endif // !TARGET_OSX
Expand Down
7 changes: 7 additions & 0 deletions src/coreclr/minipal/Windows/doublemapping.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include <inttypes.h>
#include <assert.h>
#include "minipal.h"
#include "minipal/cpufeatures.h"

#define HIDWORD(_qw) ((ULONG)((_qw) >> 32))
#define LODWORD(_qw) ((ULONG)(_qw))
Expand Down Expand Up @@ -60,6 +61,12 @@ inline void *GetBotMemoryAddress(void)

bool VMToOSInterface::CreateDoubleMemoryMapper(void **pHandle, size_t *pMaxExecutableCodeSize)
{
if (minipal_detect_rosetta())
{
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe a comment here to explain that Rosetta on Windows would be on Wine/macOS?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added the comment

// Rosetta doesn't support double mapping correctly. WINE on macOS ARM64 can be running under Rosetta.
return false;
}

*pMaxExecutableCodeSize = (size_t)MaxDoubleMappedSize;
*pHandle = CreateFileMapping(
INVALID_HANDLE_VALUE, // use paging file
Expand Down
35 changes: 35 additions & 0 deletions src/native/minipal/cpufeatures.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
#include <stdint.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdio.h>
#include <string.h>

#include "cpufeatures.h"
#include "cpuid.h"
Expand Down Expand Up @@ -473,3 +475,36 @@ int minipal_getcpufeatures(void)

return result;
}

// Detect if the current process is running under the Apple Rosetta x64 emulator
bool minipal_detect_rosetta(void)
{
#if defined(HOST_AMD64) || defined(HOST_X86)
// Check for CPU brand indicating emulation
int regs[4];
char brand[49];

// Get the maximum value for extended function CPUID info
__cpuid(regs, (int)0x80000000);
if ((unsigned int)regs[0] < 0x80000004)
{
return false; // Extended CPUID not supported
}

// Retrieve the CPU brand string
for (unsigned int i = 0x80000002; i <= 0x80000004; ++i)
{
__cpuid(regs, (int)i);
memcpy(brand + (i - 0x80000002) * sizeof(regs), regs, sizeof(regs));
}
brand[sizeof(brand) - 1] = '\0';

// Check if CPU brand indicates emulation
if (strstr(brand, "VirtualApple") != NULL)
{
return true;
}
#endif // HOST_AMD64 || HOST_X86

return false;
}
1 change: 1 addition & 0 deletions src/native/minipal/cpufeatures.h
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ extern "C"
#endif // __cplusplus

int minipal_getcpufeatures(void);
bool minipal_detect_rosetta(void);

#ifdef __cplusplus
}
Expand Down
Loading