diff options
Diffstat (limited to 'fs/erofs')
-rw-r--r-- | fs/erofs/decompressor.c | 16 | ||||
-rw-r--r-- | fs/erofs/internal.h | 2 | ||||
-rw-r--r-- | fs/erofs/zdata.c | 4 | ||||
-rw-r--r-- | fs/erofs/zmap.c | 10 |
4 files changed, 19 insertions, 13 deletions
diff --git a/fs/erofs/decompressor.c b/fs/erofs/decompressor.c index 23b74b8e8f96..38eeec5e3032 100644 --- a/fs/erofs/decompressor.c +++ b/fs/erofs/decompressor.c @@ -56,14 +56,18 @@ static int z_erofs_lz4_prepare_destpages(struct z_erofs_decompress_req *rq, if (page) { __clear_bit(j, bounced); - if (kaddr) { - if (kaddr + PAGE_SIZE == page_address(page)) + if (!PageHighMem(page)) { + if (!i) { + kaddr = page_address(page); + continue; + } + if (kaddr && + kaddr + PAGE_SIZE == page_address(page)) { kaddr += PAGE_SIZE; - else - kaddr = NULL; - } else if (!i) { - kaddr = page_address(page); + continue; + } } + kaddr = NULL; continue; } kaddr = NULL; diff --git a/fs/erofs/internal.h b/fs/erofs/internal.h index 544a453f3076..cc7a42682814 100644 --- a/fs/erofs/internal.h +++ b/fs/erofs/internal.h @@ -226,7 +226,7 @@ struct erofs_inode { unsigned char datalayout; unsigned char inode_isize; - unsigned short xattr_isize; + unsigned int xattr_isize; unsigned int xattr_shared_count; unsigned int *xattr_shared_xattrs; diff --git a/fs/erofs/zdata.c b/fs/erofs/zdata.c index fdd18c250811..fb718c3e3ebd 100644 --- a/fs/erofs/zdata.c +++ b/fs/erofs/zdata.c @@ -636,9 +636,11 @@ hitted: tight &= (clt->mode >= COLLECT_PRIMARY_HOOKED && clt->mode != COLLECT_PRIMARY_FOLLOWED_NOINPLACE); - cur = end - min_t(unsigned int, offset + end - map->m_la, end); + cur = end - min_t(erofs_off_t, offset + end - map->m_la, end); if (!(map->m_flags & EROFS_MAP_MAPPED)) { zero_user_segment(page, cur, end); + ++spiltted; + tight = false; goto next_part; } diff --git a/fs/erofs/zmap.c b/fs/erofs/zmap.c index fff574100721..6553f58fb289 100644 --- a/fs/erofs/zmap.c +++ b/fs/erofs/zmap.c @@ -179,6 +179,10 @@ static int vle_legacy_load_cluster_from_disk(struct z_erofs_maprecorder *m, case Z_EROFS_VLE_CLUSTER_TYPE_PLAIN: case Z_EROFS_VLE_CLUSTER_TYPE_HEAD: m->clusterofs = le16_to_cpu(di->di_clusterofs); + if (m->clusterofs >= 1 << vi->z_logical_clusterbits) { + DBG_BUGON(1); + return -EFSCORRUPTED; + } m->pblk = le32_to_cpu(di->di_u.blkaddr); break; default: @@ -211,7 +215,7 @@ static int unpack_compacted_index(struct z_erofs_maprecorder *m, int i; u8 *in, type; - if (1 << amortizedshift == 4) + if (1 << amortizedshift == 4 && lclusterbits <= 14) vcnt = 2; else if (1 << amortizedshift == 2 && lclusterbits == 12) vcnt = 16; @@ -269,7 +273,6 @@ static int compacted_load_cluster_from_disk(struct z_erofs_maprecorder *m, { struct inode *const inode = m->inode; struct erofs_inode *const vi = EROFS_I(inode); - const unsigned int lclusterbits = vi->z_logical_clusterbits; const erofs_off_t ebase = ALIGN(iloc(EROFS_I_SB(inode), vi->nid) + vi->inode_isize + vi->xattr_isize, 8) + sizeof(struct z_erofs_map_header); @@ -279,9 +282,6 @@ static int compacted_load_cluster_from_disk(struct z_erofs_maprecorder *m, erofs_off_t pos; int err; - if (lclusterbits != 12) - return -EOPNOTSUPP; - if (lcn >= totalidx) return -EINVAL; |