Skip to content

Commit a5242d3

Browse files
committed
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>
1 parent 5c40d2e commit a5242d3

2 files changed

Lines changed: 15 additions & 10 deletions

File tree

fs/erofs/decompressor.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,6 @@ static void *z_erofs_lz4_handle_overlap(const struct z_erofs_decompress_req *rq,
145145
oend = rq->pageofs_out + rq->outputsize;
146146
omargin = PAGE_ALIGN(oend) - oend;
147147
if (!rq->partial_decoding && may_inplace &&
148-
rq->outpages >= rq->inpages &&
149148
omargin >= LZ4_DECOMPRESS_INPLACE_MARGIN(rq->inputsize)) {
150149
for (i = 0; i < rq->inpages; ++i)
151150
if (rq->out[rq->outpages - rq->inpages + i] !=

fs/erofs/zmap.c

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -473,11 +473,6 @@ static int z_erofs_map_blocks_fo(struct inode *inode,
473473
}
474474

475475
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-
}
481476
if (vi->z_advise & Z_EROFS_ADVISE_INTERLACED_PCLUSTER)
482477
map->m_algorithmformat = Z_EROFS_COMPRESSION_INTERLACED;
483478
else
@@ -720,10 +715,21 @@ static int z_erofs_map_sanity_check(struct inode *inode,
720715
map->m_algorithmformat, map->m_la, EROFS_I(inode)->nid);
721716
return -EOPNOTSUPP;
722717
}
723-
if (unlikely(map->m_algorithmformat < Z_EROFS_COMPRESSION_MAX &&
724-
!(sbi->available_compr_algs & (1 << map->m_algorithmformat)))) {
725-
erofs_err(inode->i_sb, "inconsistent algorithmtype %u for nid %llu",
726-
map->m_algorithmformat, EROFS_I(inode)->nid);
718+
719+
if (map->m_algorithmformat < Z_EROFS_COMPRESSION_MAX) {
720+
if (sbi->available_compr_algs ^ BIT(map->m_algorithmformat)) {
721+
erofs_err(inode->i_sb, "inconsistent algorithmtype %u for nid %llu",
722+
map->m_algorithmformat, EROFS_I(inode)->nid);
723+
return -EFSCORRUPTED;
724+
}
725+
if (EROFS_MAP_FULL(map->m_flags) && map->m_llen < map->m_plen) {
726+
erofs_err(inode->i_sb, "too much compressed data @ la %llu of nid %llu",
727+
map->m_la, EROFS_I(inode)->nid);
728+
return -EFSCORRUPTED;
729+
}
730+
} else if (map->m_llen > map->m_plen) {
731+
erofs_err(inode->i_sb, "not enough plain data on disk @ la %llu of nid %llu",
732+
map->m_la, EROFS_I(inode)->nid);
727733
return -EFSCORRUPTED;
728734
}
729735
if (unlikely(map->m_plen > Z_EROFS_PCLUSTER_MAX_SIZE ||

0 commit comments

Comments
 (0)