Технология NativeClient создает песочницу для x86 кода внутри процесса, при этом коду в песочнице доступен только небольшой фрагмент адресного пространства процесса. Сделано это так: перед запуском модуль дизасемблируется и валидатор проверяет что используется «безопасное» подмножество инструкций. Ограничение доступного адресного пространства реализовано с помощью сегментных регистров x86. Сбежать из песочницы не получится: инструкции, модифицирующие сегментные регистры, не пропустит валидатор.
Это сильно упрощенное описание. Еще надо добиться однозначной интерпретации x86 инструкций — из-за того, что инструкции имеют разный размер, возможна ситуация когда код прыгает в середину инструкции и байты из середины инструкции декодируются в другую валидную инструкцию (которую проглядел валидатор).
Решение есть в оригинальной статье.
Так вот не знаю как на Arm, а на x86_64 поддержка сегментных регистров отсутствует и другого аналогичного механизма просто нет. Как же оно работает на x86_64?
Единственное решение, которое мне приходит в голову — это каждое обращение к памяти по динамически вычисляемому адресу транслировать в особую последовательность инструкций, которая заканчивается применением маски к адресу (и енфорсить эту полиси в валидаторе). Если это на самом деле так, то NaCl должен вчистую сливать той же джаве с JIT компиляцией.