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.

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

+30 -29
+30 -29
fs/erofs/zmap.c
··· 55 55 } else { 56 56 m->partialref = !!(advise & Z_EROFS_LI_PARTIAL_REF); 57 57 m->clusterofs = le16_to_cpu(di->di_clusterofs); 58 - if (m->clusterofs >= 1 << vi->z_lclusterbits) { 59 - DBG_BUGON(1); 60 - return -EFSCORRUPTED; 61 - } 62 58 m->pblk = le32_to_cpu(di->di_u.blkaddr); 63 59 } 64 60 return 0; ··· 236 240 static int z_erofs_load_lcluster_from_disk(struct z_erofs_maprecorder *m, 237 241 unsigned int lcn, bool lookahead) 238 242 { 243 + struct erofs_inode *vi = EROFS_I(m->inode); 244 + int err; 245 + 246 + if (vi->datalayout == EROFS_INODE_COMPRESSED_COMPACT) { 247 + err = z_erofs_load_compact_lcluster(m, lcn, lookahead); 248 + } else { 249 + DBG_BUGON(vi->datalayout != EROFS_INODE_COMPRESSED_FULL); 250 + err = z_erofs_load_full_lcluster(m, lcn); 251 + } 252 + if (err) 253 + return err; 254 + 239 255 if (m->type >= Z_EROFS_LCLUSTER_TYPE_MAX) { 240 256 erofs_err(m->inode->i_sb, "unknown type %u @ lcn %u of nid %llu", 241 - m->type, lcn, EROFS_I(m->inode)->nid); 257 + m->type, lcn, EROFS_I(m->inode)->nid); 242 258 DBG_BUGON(1); 243 259 return -EOPNOTSUPP; 260 + } else if (m->type != Z_EROFS_LCLUSTER_TYPE_NONHEAD && 261 + m->clusterofs >= (1 << vi->z_lclusterbits)) { 262 + DBG_BUGON(1); 263 + return -EFSCORRUPTED; 244 264 } 245 - 246 - switch (EROFS_I(m->inode)->datalayout) { 247 - case EROFS_INODE_COMPRESSED_FULL: 248 - return z_erofs_load_full_lcluster(m, lcn); 249 - case EROFS_INODE_COMPRESSED_COMPACT: 250 - return z_erofs_load_compact_lcluster(m, lcn, lookahead); 251 - default: 252 - return -EINVAL; 253 - } 265 + return 0; 254 266 } 255 267 256 268 static int z_erofs_extent_lookback(struct z_erofs_maprecorder *m, ··· 272 268 unsigned long lcn = m->lcn - lookback_distance; 273 269 int err; 274 270 271 + if (!lookback_distance) 272 + break; 273 + 275 274 err = z_erofs_load_lcluster_from_disk(m, lcn, false); 276 275 if (err) 277 276 return err; 278 - 279 277 if (m->type == Z_EROFS_LCLUSTER_TYPE_NONHEAD) { 280 278 lookback_distance = m->delta[0]; 281 - if (!lookback_distance) 282 - break; 283 279 continue; 284 - } else { 285 - m->headtype = m->type; 286 - m->map->m_la = (lcn << lclusterbits) | m->clusterofs; 287 - return 0; 288 280 } 281 + m->headtype = m->type; 282 + m->map->m_la = (lcn << lclusterbits) | m->clusterofs; 283 + return 0; 289 284 } 290 285 erofs_err(sb, "bogus lookback distance %u @ lcn %lu of nid %llu", 291 286 lookback_distance, m->lcn, vi->nid); ··· 434 431 end = inode->i_size; 435 432 } else { 436 433 if (m.type != Z_EROFS_LCLUSTER_TYPE_NONHEAD) { 437 - /* m.lcn should be >= 1 if endoff < m.clusterofs */ 438 - if (!m.lcn) { 439 - erofs_err(sb, "invalid logical cluster 0 at nid %llu", 440 - vi->nid); 441 - err = -EFSCORRUPTED; 442 - goto unmap_out; 443 - } 444 434 end = (m.lcn << lclusterbits) | m.clusterofs; 445 435 map->m_flags |= EROFS_MAP_FULL_MAPPED; 446 436 m.delta[0] = 1; ··· 592 596 vi->z_fragmentoff = map->m_plen; 593 597 if (recsz > offsetof(struct z_erofs_extent, pstart_lo)) 594 598 vi->z_fragmentoff |= map->m_pa << 32; 595 - } else if (map->m_plen) { 599 + } else if (map->m_plen & Z_EROFS_EXTENT_PLEN_MASK) { 596 600 map->m_flags |= EROFS_MAP_MAPPED | 597 601 EROFS_MAP_FULL_MAPPED | EROFS_MAP_ENCODED; 598 602 fmt = map->m_plen >> Z_EROFS_EXTENT_PLEN_FMT_BIT; ··· 711 715 struct erofs_map_blocks *map) 712 716 { 713 717 struct erofs_sb_info *sbi = EROFS_I_SB(inode); 718 + u64 pend; 714 719 715 720 if (!(map->m_flags & EROFS_MAP_ENCODED)) 716 721 return 0; ··· 729 732 if (unlikely(map->m_plen > Z_EROFS_PCLUSTER_MAX_SIZE || 730 733 map->m_llen > Z_EROFS_PCLUSTER_MAX_DSIZE)) 731 734 return -EOPNOTSUPP; 735 + /* Filesystems beyond 48-bit physical block addresses are invalid */ 736 + if (unlikely(check_add_overflow(map->m_pa, map->m_plen, &pend) || 737 + (pend >> sbi->blkszbits) >= BIT_ULL(48))) 738 + return -EFSCORRUPTED; 732 739 return 0; 733 740 } 734 741