If packed_nid carries the metabox NID bit, loading the packed inode first redirects its inode metadata lookup through the metabox inode. Initializing that metabox inode can then read metadata that refers back through the packed inode, forming a recursive packed inode -> metabox inode -> packed inode path.
Reject such images while parsing the superblock, matching the format rule that the special packed inode itself is not stored inside the metabox. Reproducible image (base64-encoded gzipped blob): H4sIAAAAAAAAA2NgGAWjYBSMVPDo4dcHrY0KwsxANg8jAwMLFjVMSGzPx/7Lzj3zXb3jSFTh 5iN7v6CrbQSa8f8/gq8GoRpARHErYxYDEh8EVAm4jw2Il4AMFYDoB7IYmDGVNRhAzf8PBMh+ yEjNyclXKM8vyklRIILNRcA5o2AUjIJRMApGwSgYBaNgFAxpAGorv3VkYtBgQLSfQW3sF8wv kJvZDSqIXkCDKpANlWxQZ2Bk0NPTS8RlPkgXqP0Oa5/DxNDNB7XvR8EoGAWjYBSMglEwCkbB KBgFo2AUjIJRQBsAAEZO6n4AIAAA Assisted-by: Codex:GPT-5.5 Signed-off-by: Yifan Zhao <[email protected]> --- lib/super.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/super.c b/lib/super.c index 899d51a..655a6f4 100644 --- a/lib/super.c +++ b/lib/super.c @@ -131,6 +131,8 @@ int erofs_read_superblock(struct erofs_sb_info *sbi) sbi->root_nid = le16_to_cpu(dsb->rb.rootnid_2b); } sbi->packed_nid = le64_to_cpu(dsb->packed_nid); + if (sbi->packed_nid & BIT_ULL(EROFS_DIRENT_NID_METABOX_BIT)) + return -EFSCORRUPTED; if (erofs_sb_has_metabox(sbi)) { if (sbi->sb_size <= offsetof(struct erofs_super_block, metabox_nid)) -- 2.47.3
