Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

erofs: fix interlaced plain identification for encoded extents

Only plain data whose start position and on-disk physical length are
both aligned to the block size should be classified as interlaced
plain extents. Otherwise, it must be treated as shifted plain extents.

This issue was found by syzbot using a crafted compressed image
containing plain extents with unaligned physical lengths, which can
cause OOB read in z_erofs_transform_plain().

Reported-and-tested-by: syzbot+d988dc155e740d76a331@syzkaller.appspotmail.com
Closes: https://lore.kernel.org/r/699d5714.050a0220.cdd3c.03e7.GAE@google.com
Fixes: 1d191b4ca51d ("erofs: implement encoded extent metadata")
Signed-off-by: Gao Xiang <hsiangkao@linux.alibaba.com>

Gao Xiang 4a2d046e bf4fde7d

+5 -4
+5 -4
fs/erofs/zmap.c
··· 513 513 unsigned int recsz = z_erofs_extent_recsize(vi->z_advise); 514 514 erofs_off_t pos = round_up(Z_EROFS_MAP_HEADER_END(erofs_iloc(inode) + 515 515 vi->inode_isize + vi->xattr_isize), recsz); 516 + unsigned int bmask = sb->s_blocksize - 1; 516 517 bool in_mbox = erofs_inode_in_metabox(inode); 517 518 erofs_off_t lend = inode->i_size; 518 519 erofs_off_t l, r, mid, pa, la, lstart; ··· 597 596 map->m_flags |= EROFS_MAP_MAPPED | 598 597 EROFS_MAP_FULL_MAPPED | EROFS_MAP_ENCODED; 599 598 fmt = map->m_plen >> Z_EROFS_EXTENT_PLEN_FMT_BIT; 599 + if (map->m_plen & Z_EROFS_EXTENT_PLEN_PARTIAL) 600 + map->m_flags |= EROFS_MAP_PARTIAL_REF; 601 + map->m_plen &= Z_EROFS_EXTENT_PLEN_MASK; 600 602 if (fmt) 601 603 map->m_algorithmformat = fmt - 1; 602 - else if (interlaced && !erofs_blkoff(sb, map->m_pa)) 604 + else if (interlaced && !((map->m_pa | map->m_plen) & bmask)) 603 605 map->m_algorithmformat = 604 606 Z_EROFS_COMPRESSION_INTERLACED; 605 607 else 606 608 map->m_algorithmformat = 607 609 Z_EROFS_COMPRESSION_SHIFTED; 608 - if (map->m_plen & Z_EROFS_EXTENT_PLEN_PARTIAL) 609 - map->m_flags |= EROFS_MAP_PARTIAL_REF; 610 - map->m_plen &= Z_EROFS_EXTENT_PLEN_MASK; 611 610 } 612 611 } 613 612 map->m_llen = lend - map->m_la;