ARM MTE如何防范单字节越界错误?同标签颗粒访问疑问
ARM MTE 越界检测常见疑问解答
关于
u8 arr[17]; arr[18] = 1;的越界检测:
没错,MTE确实无法检测到这个越界。因为MTE的标签是以16字节为粒度(称为一个granule)进行标记的,当你申请17字节内存时,操作系统会分配至少两个连续的16字节granule(共32字节),并且这两个granule会被打上同一个标签。arr[18]的地址落在第二个granule范围内,和原数组的标签一致,所以MTE不会触发标签不匹配的异常。是否只有访问arr[32:]才能被检测?
这个不一定,得看后续内存的状态:- 如果arr[32:]的内存已经被其他分配请求占用,且该内存的标签和arr的标签不同,此时访问arr[32:]就会触发MTE的标签不匹配异常;
- 如果arr[32:]属于未被分配的空闲内存,不同系统的处理逻辑有差异:有些系统会给空闲内存打上特殊的默认标签,此时访问会触发异常;有些系统可能不标记空闲内存,访问时可能不会触发MTE检测,但可能触发其他内存错误(比如页错误);
- 另外,如果你的内存分配请求本身就跨了多个granule(比如申请40字节,对应3个16字节granule),这些同属一个分配的granule标签都相同,越界到这些范围内也不会被MTE检测到。
操作系统页粒度的影响:
MTE的16字节granule粒度远小于通常的4KB页粒度,页粒度主要影响内存的整体映射和权限管理,但MTE的标签是在页内按granule独立管理的。需要注意两种情况:- 如果数组的分配刚好跨了两个页,只要这两个页内的内存属于同一个分配请求,操作系统依然会给对应的granule打上相同标签,越界到同标签的页内granule时,MTE还是检测不到;
- 如果越界到了权限不可访问的页(比如未映射的页、只读页),此时会先触发页错误异常,而不是MTE的标签不匹配异常,这种情况下MTE的检测逻辑不会被触发。
内容的提问来源于stack exchange,提问作者Semin Park
相关产品推荐
相关产品推荐

