Принцип работы Google NativeClient (NaCl) на x86_64?

Технология NativeClient создает песочницу для x86 кода внутри процесса, при этом коду в песочнице доступен только небольшой фрагмент адресного пространства процесса. Сделано это так: перед запуском модуль дизасемблируется и валидатор проверяет что используется «безопасное» подмножество инструкций. Ограничение доступного адресного пространства реализовано с помощью сегментных регистров x86. Сбежать из песочницы не получится: инструкции, модифицирующие сегментные регистры, не пропустит валидатор.


Это сильно упрощенное описание. Еще надо добиться однозначной интерпретации x86 инструкций — из-за того, что инструкции имеют разный размер, возможна ситуация когда код прыгает в середину инструкции и байты из середины инструкции декодируются в другую валидную инструкцию (которую проглядел валидатор). Решение есть в оригинальной статье.


Так вот не знаю как на Arm, а на x86_64 поддержка сегментных регистров отсутствует и другого аналогичного механизма просто нет. Как же оно работает на x86_64?


Единственное решение, которое мне приходит в голову — это каждое обращение к памяти по динамически вычисляемому адресу транслировать в особую последовательность инструкций, которая заканчивается применением маски к адресу (и енфорсить эту полиси в валидаторе). Если это на самом деле так, то NaCl должен вчистую сливать той же джаве с JIT компиляцией.
  • Вопрос задан
  • 2959 просмотров
Решения вопроса 1
mejedi
@mejedi Автор вопроса
Как оказалось, достаточно было поискать потщательнее чтобы найти дополнительные материалы. Я так и подозревал, а вопрос создал скорее для того, чтобы сконнектиться с людьми со похожими интересами:)

В этой статье описывается решение для x86_64 и arm. Действительно, применяется специальная последовательность инструкций, если нужно модифицировать память. Утверждают, что замедление в пределах 10%. Читать можно бесконтрольно откуда угодно, говорят что это безопасно, т.к. куки и прочие интересные вещи менеджатся в другом процессе. ИМХО это не совсем верно — как минимум можно использовать для идентификации клиента (можно получить много данных о его системе).

Здесь описывается pnacl. Вместо того, чтобы отдельно распространять x86, x86_64 и arm код, предлагается промежуточный байткод (основан на LLVM).

На клиенте это транслируется в ассемблер нативной архитектуры и выполняется в песочнице NaCl. Это намного проще в реализации, чем JIT и имеет приемлимую эффективность.
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы