tech-pkg archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: Can't build lang/openjdk{17,21} on NetBSD/aarch64 (Apple M3)



My previous mail about Apple Silicon's W^X enforcement turned out to be wrong. I wrote this code to see if W+X works on the very chip, and surprisingly, it worked:

#include <err.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <sys/mman.h>
#include <unistd.h>

const uint32_t insn_ret = 0xD65F03C0;
const uint32_t insn_nop = 0xD503201F;

int main() {
printf("Allocating a page with W+X. This would fail unless PaX MPROTECT is enabled.\n"); void* page = mmap(NULL, sysconf(_SC_PAGESIZE), PROT_EXEC|PROT_WRITE, MAP_ANON, -1, 0);
	if (page == MAP_FAILED)
		err(1, "mmap failed. Did you forget to paxctl +m the executable?");

printf("Successfully mapped a page. Now writing some instructions on it...\n");
	uint32_t* insn_p = page;
	*(insn_p++) = insn_ret;
	*(insn_p++) = insn_nop;
	__builtin___clear_cache(page, page + sysconf(_SC_PAGESIZE));

	printf("Done. Now calling it as a function.\n");
	typedef void(*thunk_t)();
	thunk_t thunk = page;
	thunk();

	printf("We survived and returned to main(). The call was successful.\n");
printf("What if we rewrite instructions and run it again? Does that work?\n");
	insn_p = page;
	*(insn_p++) = 0xD2800550; // mov x16, #42
	*(insn_p++) = insn_ret;
	*(insn_p++) = insn_nop;
	__builtin___clear_cache(page, page + sysconf(_SC_PAGESIZE));

	register uint64_t x16 __asm__("x16") = 0;
	thunk();
	// Tell the compiler that we just clobbered x16.
	__asm__ __volatile__ ("": "=r"(x16));

	if (x16 == 42)
		printf("It worked!\n");
	else
errx(1, "We tried to write 42 to x16 but x16 now contains something we didn't expect: %lu\n", x16);
	return 0;
}

So it's likely that the problem is about clearing instruction cache, which OpenJDK 17 does, but somehow isn't working on this chip. But omitting __builtin_clear_cache() from the code above did make it execute wrong instructions so the builtin itself is working.

Home | Main Index | Thread Index | Old Index