mirror of
https://github.com/torvalds/linux.git
synced 2026-06-01 02:53:36 +02:00
Changes since last update:
- Hardening against fuzzed encoded extents - Fix infinite loops due to crafted subpage compact indexes - Improve z_erofs_extent_lookback() -----BEGIN PGP SIGNATURE----- iQJFBAABCgAvFiEEQ0A6bDUS9Y+83NPFUXZn5Zlu5qoFAmj45V0RHHhpYW5nQGtl cm5lbC5vcmcACgkQUXZn5Zlu5qpUzA//XfffZTdTfVtbb9hwgpjLA7sWVpATLUn6 iKA83ZkcGqoM36Y52LOwU9zvqH30JxktPA3+rWaM9T+2/zksfiTj+uG+I5ty00+Y Rp4bmbXNng6X+537AuOQYYMx2BUHAqFQHaFk8571Ounb75mUXZ1J9USa8cYfiy8A 60ekoO5UN8jGIvvTmSW/ZfsgXcG0Jkt5qIyOtlABk8gjzud+MHJ0N4VM1TgGotD5 dqTIlaLrKzSJPl1UEBVL6ijFe/PRp4O0wXWufdUbaNHnwOBxqFOKb6B7Wtho3tX0 2VSg58O4gylPVRla5ikfleCQqfyOXanOWioQ6+Dm3GIXsLHe8Jbudcoj6tnOrEU0 PVV+mi/EUputesTnMLH+adf5VyQFcBVI88UrqS+OzSbp9mBG93xYKAFrKhWjPTjf aOxzrqzMaVMXROz6iVEP3Q/FjkojjrQ5IW6enRFLNAXwa79jVNGG2NFWfDhSltdT t65ND4KYQocBEJWgy2iZWrwr4iOjPLNt6fonEdF3nnlQOGe1pgChSAfYRBwj1ID6 aESYMpdBG+nk1S73WQAdepOt9dN+uGtsQa4lWyDSwpvYzR7c2upvJIrMMNEkuN0d 2Ivxv7c/nBw8eT5qpd2CfC3IZydci6mrlSatJ9z2Pv6QDI69Vpq8KFyC+5Fz+FO+ +ieIbQIqzO4= =KvVj -----END PGP SIGNATURE----- Merge tag 'erofs-for-6.18-rc3-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/xiang/erofs Pull erofs fixes from Gao Xiang: "Just three small fixes to address fuzzed images in relatively new features, as reported by Robert. - Hardening against fuzzed encoded extents - Fix infinite loops due to crafted subpage compact indexes - Improve z_erofs_extent_lookback()" * tag 'erofs-for-6.18-rc3-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/xiang/erofs: erofs: consolidate z_erofs_extent_lookback() erofs: avoid infinite loops due to corrupted subpage compact indexes erofs: fix crafted invalid cases for encoded extents
This commit is contained in:
commit
250a17e8f9
|
|
@ -55,10 +55,6 @@ static int z_erofs_load_full_lcluster(struct z_erofs_maprecorder *m,
|
|||
} else {
|
||||
m->partialref = !!(advise & Z_EROFS_LI_PARTIAL_REF);
|
||||
m->clusterofs = le16_to_cpu(di->di_clusterofs);
|
||||
if (m->clusterofs >= 1 << vi->z_lclusterbits) {
|
||||
DBG_BUGON(1);
|
||||
return -EFSCORRUPTED;
|
||||
}
|
||||
m->pblk = le32_to_cpu(di->di_u.blkaddr);
|
||||
}
|
||||
return 0;
|
||||
|
|
@ -240,21 +236,29 @@ static int z_erofs_load_compact_lcluster(struct z_erofs_maprecorder *m,
|
|||
static int z_erofs_load_lcluster_from_disk(struct z_erofs_maprecorder *m,
|
||||
unsigned int lcn, bool lookahead)
|
||||
{
|
||||
struct erofs_inode *vi = EROFS_I(m->inode);
|
||||
int err;
|
||||
|
||||
if (vi->datalayout == EROFS_INODE_COMPRESSED_COMPACT) {
|
||||
err = z_erofs_load_compact_lcluster(m, lcn, lookahead);
|
||||
} else {
|
||||
DBG_BUGON(vi->datalayout != EROFS_INODE_COMPRESSED_FULL);
|
||||
err = z_erofs_load_full_lcluster(m, lcn);
|
||||
}
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
if (m->type >= Z_EROFS_LCLUSTER_TYPE_MAX) {
|
||||
erofs_err(m->inode->i_sb, "unknown type %u @ lcn %u of nid %llu",
|
||||
m->type, lcn, EROFS_I(m->inode)->nid);
|
||||
m->type, lcn, EROFS_I(m->inode)->nid);
|
||||
DBG_BUGON(1);
|
||||
return -EOPNOTSUPP;
|
||||
} else if (m->type != Z_EROFS_LCLUSTER_TYPE_NONHEAD &&
|
||||
m->clusterofs >= (1 << vi->z_lclusterbits)) {
|
||||
DBG_BUGON(1);
|
||||
return -EFSCORRUPTED;
|
||||
}
|
||||
|
||||
switch (EROFS_I(m->inode)->datalayout) {
|
||||
case EROFS_INODE_COMPRESSED_FULL:
|
||||
return z_erofs_load_full_lcluster(m, lcn);
|
||||
case EROFS_INODE_COMPRESSED_COMPACT:
|
||||
return z_erofs_load_compact_lcluster(m, lcn, lookahead);
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int z_erofs_extent_lookback(struct z_erofs_maprecorder *m,
|
||||
|
|
@ -268,20 +272,19 @@ static int z_erofs_extent_lookback(struct z_erofs_maprecorder *m,
|
|||
unsigned long lcn = m->lcn - lookback_distance;
|
||||
int err;
|
||||
|
||||
if (!lookback_distance)
|
||||
break;
|
||||
|
||||
err = z_erofs_load_lcluster_from_disk(m, lcn, false);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
if (m->type == Z_EROFS_LCLUSTER_TYPE_NONHEAD) {
|
||||
lookback_distance = m->delta[0];
|
||||
if (!lookback_distance)
|
||||
break;
|
||||
continue;
|
||||
} else {
|
||||
m->headtype = m->type;
|
||||
m->map->m_la = (lcn << lclusterbits) | m->clusterofs;
|
||||
return 0;
|
||||
}
|
||||
m->headtype = m->type;
|
||||
m->map->m_la = (lcn << lclusterbits) | m->clusterofs;
|
||||
return 0;
|
||||
}
|
||||
erofs_err(sb, "bogus lookback distance %u @ lcn %lu of nid %llu",
|
||||
lookback_distance, m->lcn, vi->nid);
|
||||
|
|
@ -431,13 +434,6 @@ static int z_erofs_map_blocks_fo(struct inode *inode,
|
|||
end = inode->i_size;
|
||||
} else {
|
||||
if (m.type != Z_EROFS_LCLUSTER_TYPE_NONHEAD) {
|
||||
/* m.lcn should be >= 1 if endoff < m.clusterofs */
|
||||
if (!m.lcn) {
|
||||
erofs_err(sb, "invalid logical cluster 0 at nid %llu",
|
||||
vi->nid);
|
||||
err = -EFSCORRUPTED;
|
||||
goto unmap_out;
|
||||
}
|
||||
end = (m.lcn << lclusterbits) | m.clusterofs;
|
||||
map->m_flags |= EROFS_MAP_FULL_MAPPED;
|
||||
m.delta[0] = 1;
|
||||
|
|
@ -596,7 +592,7 @@ static int z_erofs_map_blocks_ext(struct inode *inode,
|
|||
vi->z_fragmentoff = map->m_plen;
|
||||
if (recsz > offsetof(struct z_erofs_extent, pstart_lo))
|
||||
vi->z_fragmentoff |= map->m_pa << 32;
|
||||
} else if (map->m_plen) {
|
||||
} else if (map->m_plen & Z_EROFS_EXTENT_PLEN_MASK) {
|
||||
map->m_flags |= EROFS_MAP_MAPPED |
|
||||
EROFS_MAP_FULL_MAPPED | EROFS_MAP_ENCODED;
|
||||
fmt = map->m_plen >> Z_EROFS_EXTENT_PLEN_FMT_BIT;
|
||||
|
|
@ -715,6 +711,7 @@ static int z_erofs_map_sanity_check(struct inode *inode,
|
|||
struct erofs_map_blocks *map)
|
||||
{
|
||||
struct erofs_sb_info *sbi = EROFS_I_SB(inode);
|
||||
u64 pend;
|
||||
|
||||
if (!(map->m_flags & EROFS_MAP_ENCODED))
|
||||
return 0;
|
||||
|
|
@ -732,6 +729,10 @@ static int z_erofs_map_sanity_check(struct inode *inode,
|
|||
if (unlikely(map->m_plen > Z_EROFS_PCLUSTER_MAX_SIZE ||
|
||||
map->m_llen > Z_EROFS_PCLUSTER_MAX_DSIZE))
|
||||
return -EOPNOTSUPP;
|
||||
/* Filesystems beyond 48-bit physical block addresses are invalid */
|
||||
if (unlikely(check_add_overflow(map->m_pa, map->m_plen, &pend) ||
|
||||
(pend >> sbi->blkszbits) >= BIT_ULL(48)))
|
||||
return -EFSCORRUPTED;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user