Почему инструкция jmp CLR не поддается проверке? - PullRequest
14 голосов
/ 18 мая 2010

Некоторое время я знал об инструкции jmp, но она никогда не казалась мне даже отдаленно небезопасной. Недавно у меня была причина проверить спецификации CIL, и был очень удивлен, обнаружив, что jmp считается непроверяемым .

1 Ответ

4 голосов
/ 18 мая 2010

Потому что, в отличие от call, callvirt или calli, где кадр стека вызывающего абонента останется в стеке, чтобы его можно было увидеть в будущих обходах безопасности доступа к коду, инициированных (возможно, косвенно) вызываемым объектом, a jmp инструкция разрушает фрейм стека вызывающей стороны перед переходом к вызываемому и, таким образом, невидима для любых стековых прогулок CAS, которые может вызвать вызываемый.

Редактировать: Я думаю, что naasking прав, потому что ответ выше неправильный. Теперь я думаю, что разница между (проверяемыми) последовательностями tail.call и (не проверяемыми) последовательностями jmp может заключаться в том, что хвостовой вызов требует нажатия аргументы для вызова в стек оценки, где они могут быть проверены обычным способом, тогда как jmp требует, чтобы стек оценки был пуст и заставляет jump-ee наследовать аргументы jump-er. Вероятно, не было никакой причины усложнять верификатор для проверки jmp инструкций, но это могло бы быть возможно сделать в условиях, аналогичных тем, которые налагаются на последовательности tail.call (одна из которых заключается в том, что вызывающий и вызываемый должны быть в одном сборка, которая исключает мою догадку CAS выше, по крайней мере, до явных вызовов .Deny( ).

Если это так, это будет релевантная часть спецификации: (Раздел III, Раздел 3.37)

Текущие аргументы переданы к методу назначения.

Стек оценки должен быть пуст когда эта инструкция выполнена. соглашение о вызове, номер и тип аргументы по адресу назначения должен совпадать с текущим методом.

...