Skip to content

Commit

Permalink
On Majave and later, allocate with MAP_JIT
Browse files Browse the repository at this point in the history
The VM requires writeable + executable memory which is blocked when
the "hardened runtime" is enabled at the codesigning stage.

If we pass the `MAP_JIT` flag then we can add the capability

  com.apple.security.cs.allow-jit [1]

to permit the allocation. The alternative is to globally enable
write+execute for all allocations in the process which seems worse [2]

[1] https://developer.apple.com/documentation/bundleresources/entitlements/com_apple_security_cs_allow-jit
[2] https://developer.apple.com/documentation/bundleresources/entitlements/com_apple_security_cs_allow-unsigned-executable-memory

Signed-off-by: David Scott <[email protected]>
  • Loading branch information
djs55 committed Aug 20, 2019
1 parent 04f7bc8 commit ccbb472
Showing 1 changed file with 42 additions and 1 deletion.
43 changes: 42 additions & 1 deletion src/lib/vmm/vmm_mem.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,55 @@

#include <stdint.h>
#include <stdlib.h>
#include <errno.h>
#include <Hypervisor/hv.h>
#include <Hypervisor/hv_vmx.h>
#include <xhyve/support/misc.h>
#include <xhyve/vmm/vmm_mem.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/sysctl.h>

/* According to the mono project
https://github.com/mono/mono/commit/a502768b3a24f4251de6a48ba78a27c898968e63
using MAP_JIT causes problems with older macOS versions so we should use it
on Mojave or later. */

static int mmap_flags = MAP_PRIVATE | MAP_ANONYMOUS;

#define OSRELEASE "kern.osrelease"
#define OSRELEASE_MOJAVE 18

static long
vmm_get_kern_osrelease()
{
char *s;
size_t len;
long v;
if (sysctlbyname(OSRELEASE, NULL, &len, NULL, 0)) {
xhyve_abort("vmm_get_kern_osrelease failed to query sysctl kern.osrelease\n");
}
s = malloc(len);
if (!s) {
xhyve_abort("vmm_get_kern_osrelease failed to allocate memory for kern.osrelease\n");
}
if (sysctlbyname(OSRELEASE, s, &len, NULL, 0)){
xhyve_abort("vmm_get_kern_osrelease failed to query sysctl kern.osrelease\n");
}
v = strtol(s, NULL, 10);
if ((v == 0) && (errno != 0)) {
xhyve_abort("vmm_get_kern_osrelease failed to parse sysctl kern.osrelease value\n");
}
return v;
}

int
vmm_mem_init(void)
{
if (vmm_get_kern_osrelease() >= OSRELEASE_MOJAVE) {
fprintf(stderr, "Detected Mojave or later, will use MAP_JIT\n");
mmap_flags |= MAP_JIT;
}
return (0);
}

Expand All @@ -46,7 +87,7 @@ vmm_mem_alloc(uint64_t gpa, size_t size)
{
void *object;

object = mmap(0, size, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
object = mmap(0, size, PROT_READ|PROT_WRITE|PROT_EXEC, mmap_flags, -1, 0);
if (object == MAP_FAILED) {
xhyve_abort("vmm_mem_alloc failed in mmap\n");
}
Expand Down

0 comments on commit ccbb472

Please sign in to comment.