ARTICLE DETAIL

资讯详情

深耕商务建站与企业官网运营的一线实战洞察。

slub slab_pad_check

slub slab_pad_check slab_pad_check()是 SLUB 调试中用于校验整个 slab 页尾部填充区的函数。与上一问的check_pad_bytes()校验单个对象内部的 padding不同它检查的是最后一个对象之后、到 slab 页结束那段空间。一、函数签名static pad_check_attributes void slab_pad_check(struct kmem_cache *s, struct slab *slab)项含义pad_check_attributes编译器属性避免 sanitizer 误报同check_bytes_and_reports缓存slab要检查的 slab 页无返回值。二、典型实现static pad_check_attributes void slab_pad_check(struct kmem_cache *s, struct slab *slab) { u8 *end; if (!(s-flags SLAB_POISON)) return; end slab_address(slab) (PAGE_SIZE oo_order(s-oo)); end - sizeof(void *); // 末尾可能残留 freepointer 空间 ... }核心思路门控未开SLAB_POISON直接返回。算出 slab 页末尾地址slab_address(slab)slab 页起始。PAGE_SIZE oo_order(s-oo)slab 总字节数2^order个页。相加得到 slab 页结束地址。计算最后一个对象的结束位置slab_address objects * s-size。检查两者之间的空隙这段是 slab 页尾部 padding正常应填POISON_FREE。发现异常则报告 恢复用slab_err()/restore_bytes()。三、与check_pad_bytes()的区别函数检查范围期望值触发条件check_pad_bytes()单个对象内部元数据后到对象槽位结束POISON_INUSESLAB_POISONslab_pad_check()整个 slab 页尾部最后一个对象后到页结束POISON_FREESLAB_POISONslab 页布局 -------------------------------- ... -------------------------------- | 对象 0 | 对象 1 | | 对象 N-1 | 页尾 padding | -------------------------------- ... -------------------------------- ^ ^ ^ slab_address objects*size 页结束 └── slab_pad_check 检查 ──┘check_pad_bytes()检查每个对象槽位内部的填充用户数据后到s-size。slab_pad_check()检查整个 slab 页最后一个对象之后到页结束的填充。四、为什么需要检查 slab 页尾slab 页大小是2^order个页所有对象按s-size排列后剩余空间就是页尾 padding。这段空间正常填POISON_FREE。如果被越界写破坏如某对象写超出自身槽位、freelist 操作越界这里会留下痕迹。检查它能发现跨对象、跨槽位的越界写是对象内部 padding 检查的补充。五、典型实现细节更完整的实现可能static pad_check_attributes void slab_pad_check(struct kmem_cache *s, struct slab *slab) { u8 *start; u8 *end; u8 *p; unsigned int length; if (!(s-flags SLAB_POISON)) return; start slab_address(slab); end start (PAGE_SIZE oo_order(s-oo)); // 最后一个对象的结束位置 p start slab-objects * s-size; length end - p; if (!length) return; check_bytes_and_report(s, slab, p, Slab tail padding, p, POISON_FREE, length, false); }start/endslab 页范围。p start objects * s-size所有对象结束位置。length end - p页尾 padding 长度。交给check_bytes_and_report()检查POISON_FREE发现破坏则报告 restore_bytes()恢复。slab_obj_print false页尾 padding 出错时只需 slab 级信息不用打印整个对象现场。六、调用时机slab_pad_check()通常在slab 页级一致性校验里调用static int validate_slab(struct kmem_cache *s, struct slab *slab, ...) { ... slab_pad_check(s, slab); ... }或check_slab()里static int check_slab(struct kmem_cache *s, struct slab *slab) { ... slab_pad_check(s, slab); ... }它在对象级校验check_object→check_pad_bytes之外提供页级的填充完整性检查。七、与前面知识的呼应前面讲过这里体现check_bytes_and_report()slab_pad_check底层调用的校验函数check_pad_bytes()对象内部 padding 检查与本函数互补restore_bytes()发现破坏后恢复SLAB_POISON门控条件oo_order(s-oo)算 slab 页大小slab_address()取 slab 页起始地址slab-objects/s-size算对象区结束位置POISON_FREE页尾 padding 期望值pad_check_attributes避免 sanitizer 误报八、一句话总结slab_pad_check(s, slab)在开启SLAB_POISON时检查 slab 页中最后一个对象之后到页结束的尾部填充区是否仍为POISON_FREE发现破坏则报告并恢复。它与check_pad_bytes()对象内部 padding互补共同覆盖 slab 页内所有“无用空间”用于检测越界写。
返回列表
PREV
查看更多资讯
NEXT
返回资讯列表