我已经了解了一段时间的jmp指令,但它从来没有让我觉得它甚至远程不安全。我最近有理由检查CIL规范和was very surprised to discover jmp is considered unverifiable。
答案 0 :(得分:4)
因为,与call
,callvirt
或calli
不同,调用者的堆栈帧将保留在堆栈中,以便将来触发(可能是间接的)代码访问安全堆栈通过被调用者,jmp
指令在转换到被调用者之前拆除调用者的堆栈帧,因此被调用者可能触发的任何CAS堆栈行走都不可见。
编辑:我认为naasking对于上面的错误答案是正确的。我现在认为(可验证的)tail.call序列和(无法验证的)jmp序列之间的区别可能是尾部调用需要将调用的参数推送到评估堆栈,在那里可以以正常方式验证它们,而jmp
要求评估堆栈为空,并使jump-ee继承跳转器的参数。可能没有理由使验证者复杂化以检查jmp
指令,但是可能在类似于tail.call
序列的条件下执行此操作(其中一个是调用者和被调用者必须在同一个程序集中,这排除了我上面的CAS猜测,至少是明确.Deny( )
次调用。)
如果是这样,这将是规范的相关部分:(第III部分,第3.37节)
转移当前参数 到目的地方法。
评估堆栈必须为空 执行该指令时该 调用约定,数量和类型 目的地地址的参数 必须与当前方法的匹配。