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: error out obviously illegal extents in advance

Detect some corrupted extent cases during metadata parsing rather
than letting them result in harmless decompression failures later:

- For full-reference compressed extents, the compressed size must
not exceed the decompressed size, which is a strict on-disk
layout constraint;

- For plain (shifted/interlaced) extents, the decoded size must
not exceed the encoded size, even accounting for partial decoding.

Both ways work but it should be better to report illegal extents as
metadata layout violations rather than deferring as decompression
failure.

Signed-off-by: Gao Xiang <hsiangkao@linux.alibaba.com>

+15 -10
-1
fs/erofs/decompressor.c
··· 145 145 oend = rq->pageofs_out + rq->outputsize; 146 146 omargin = PAGE_ALIGN(oend) - oend; 147 147 if (!rq->partial_decoding && may_inplace && 148 - rq->outpages >= rq->inpages && 149 148 omargin >= LZ4_DECOMPRESS_INPLACE_MARGIN(rq->inputsize)) { 150 149 for (i = 0; i < rq->inpages; ++i) 151 150 if (rq->out[rq->outpages - rq->inpages + i] !=
+15 -9
fs/erofs/zmap.c
··· 473 473 } 474 474 475 475 if (m.headtype == Z_EROFS_LCLUSTER_TYPE_PLAIN) { 476 - if (map->m_llen > map->m_plen) { 477 - DBG_BUGON(1); 478 - err = -EFSCORRUPTED; 479 - goto unmap_out; 480 - } 481 476 if (vi->z_advise & Z_EROFS_ADVISE_INTERLACED_PCLUSTER) 482 477 map->m_algorithmformat = Z_EROFS_COMPRESSION_INTERLACED; 483 478 else ··· 715 720 map->m_algorithmformat, map->m_la, EROFS_I(inode)->nid); 716 721 return -EOPNOTSUPP; 717 722 } 718 - if (unlikely(map->m_algorithmformat < Z_EROFS_COMPRESSION_MAX && 719 - !(sbi->available_compr_algs & (1 << map->m_algorithmformat)))) { 720 - erofs_err(inode->i_sb, "inconsistent algorithmtype %u for nid %llu", 721 - map->m_algorithmformat, EROFS_I(inode)->nid); 723 + 724 + if (map->m_algorithmformat < Z_EROFS_COMPRESSION_MAX) { 725 + if (sbi->available_compr_algs ^ BIT(map->m_algorithmformat)) { 726 + erofs_err(inode->i_sb, "inconsistent algorithmtype %u for nid %llu", 727 + map->m_algorithmformat, EROFS_I(inode)->nid); 728 + return -EFSCORRUPTED; 729 + } 730 + if (EROFS_MAP_FULL(map->m_flags) && map->m_llen < map->m_plen) { 731 + erofs_err(inode->i_sb, "too much compressed data @ la %llu of nid %llu", 732 + map->m_la, EROFS_I(inode)->nid); 733 + return -EFSCORRUPTED; 734 + } 735 + } else if (map->m_llen > map->m_plen) { 736 + erofs_err(inode->i_sb, "not enough plain data on disk @ la %llu of nid %llu", 737 + map->m_la, EROFS_I(inode)->nid); 722 738 return -EFSCORRUPTED; 723 739 } 724 740 if (unlikely(map->m_plen > Z_EROFS_PCLUSTER_MAX_SIZE ||