From: Gao Xiang <xiang@kernel.org>
To: linux-erofs@lists.ozlabs.org
Cc: LKML <linux-kernel@vger.kernel.org>, Gao Xiang <xiang@kernel.org>
Subject: [PATCH] erofs: guard on-disk algorithm IDs against Z_EROFS_COMPRESSION_MAX
Date: Fri, 14 Aug 2026 16:14:37 +0800 [thread overview]
Message-ID: <20260814081437.86684-1-xiang@kernel.org> (raw)
All on-disk algorithm IDs should be validated against
supported Z_EROFS_COMPRESSION_MAX.
This includes a partial revert of a previous commit and also adds
validation for encoded extents.
Fixes: 131897c65e2b ("erofs: fix invalid algorithm for encoded extents")
Signed-off-by: Gao Xiang <xiang@kernel.org>
---
fs/erofs/internal.h | 2 +-
fs/erofs/zmap.c | 35 +++++++++++++++++++++--------------
2 files changed, 22 insertions(+), 15 deletions(-)
diff --git a/fs/erofs/internal.h b/fs/erofs/internal.h
index 6de6e5a58e6b..9b7370f0f3df 100644
--- a/fs/erofs/internal.h
+++ b/fs/erofs/internal.h
@@ -267,7 +267,7 @@ struct erofs_inode {
#ifdef CONFIG_EROFS_FS_ZIP
struct {
unsigned short z_advise;
- unsigned char z_algorithmtype[2];
+ unsigned char z_algofmt[2];
unsigned char z_lclusterbits;
union {
u64 z_tailextent_headlcn;
diff --git a/fs/erofs/zmap.c b/fs/erofs/zmap.c
index b5411b579fd9..b316a50efe38 100644
--- a/fs/erofs/zmap.c
+++ b/fs/erofs/zmap.c
@@ -488,10 +488,9 @@ static int z_erofs_map_blocks_fo(struct inode *inode,
map->m_algorithmformat = Z_EROFS_COMPRESSION_INTERLACED;
else
map->m_algorithmformat = Z_EROFS_COMPRESSION_SHIFTED;
- } else if (m.headtype == Z_EROFS_LCLUSTER_TYPE_HEAD2) {
- map->m_algorithmformat = vi->z_algorithmtype[1];
} else {
- map->m_algorithmformat = vi->z_algorithmtype[0];
+ map->m_algorithmformat =
+ vi->z_algofmt[m.headtype == Z_EROFS_LCLUSTER_TYPE_HEAD2];
}
if ((flags & EROFS_GET_BLOCKS_FIEMAP) ||
@@ -605,9 +604,14 @@ static int z_erofs_map_blocks_ext(struct inode *inode,
if (map->m_plen & Z_EROFS_EXTENT_PLEN_PARTIAL)
map->m_flags |= EROFS_MAP_PARTIAL_REF;
map->m_plen &= Z_EROFS_EXTENT_PLEN_MASK;
- if (fmt)
- map->m_algorithmformat = fmt - 1;
- else if (interlaced && !((map->m_pa | map->m_plen) & bmask))
+ if (fmt) {
+ map->m_algorithmformat = --fmt;
+ if (fmt >= Z_EROFS_COMPRESSION_MAX) {
+ erofs_err(sb, "unknown algorithm %d @ pos %llu for nid %llu, please upgrade kernel",
+ fmt, map->m_la, vi->nid);
+ return -EOPNOTSUPP;
+ }
+ } else if (interlaced && !((map->m_pa | map->m_plen) & bmask))
map->m_algorithmformat =
Z_EROFS_COMPRESSION_INTERLACED;
else
@@ -625,7 +629,7 @@ static int z_erofs_fill_inode(struct inode *inode, struct erofs_map_blocks *map)
struct super_block *const sb = inode->i_sb;
struct z_erofs_map_header *h;
erofs_off_t pos;
- int err = 0;
+ int err = 0, nr;
if (test_bit(EROFS_I_Z_INITED_BIT, &vi->flags)) {
/*
@@ -668,12 +672,19 @@ static int z_erofs_fill_inode(struct inode *inode, struct erofs_map_blocks *map)
goto done;
}
- vi->z_algorithmtype[0] = h->h_algorithmtype & 15;
- vi->z_algorithmtype[1] = h->h_algorithmtype >> 4;
if (vi->z_advise & Z_EROFS_ADVISE_FRAGMENT_PCLUSTER)
vi->z_fragmentoff = le32_to_cpu(h->h_fragmentoff);
else if (vi->z_advise & Z_EROFS_ADVISE_INLINE_PCLUSTER)
vi->z_idata_size = le16_to_cpu(h->h_idata_size);
+ for (nr = 0; nr < 2; ++nr) {
+ vi->z_algofmt[nr] = (h->h_algorithmtype >> (4 * nr)) & 15;
+ if (vi->z_algofmt[nr] >= Z_EROFS_COMPRESSION_MAX) {
+ erofs_err(sb, "unknown HEAD%u format %u for nid %llu, please upgrade kernel",
+ nr + 1, vi->z_algofmt[nr], vi->nid);
+ err = -EOPNOTSUPP;
+ goto out_unlock;
+ }
+ }
if (!erofs_sb_has_big_pcluster(EROFS_SB(sb)) &&
vi->z_advise & (Z_EROFS_ADVISE_BIG_PCLUSTER_1 |
@@ -721,12 +732,8 @@ static int z_erofs_map_sanity_check(struct inode *inode,
if (!(map->m_flags & EROFS_MAP_MAPPED))
return 0;
- if (unlikely(map->m_algorithmformat >= Z_EROFS_COMPRESSION_RUNTIME_MAX)) {
- erofs_err(inode->i_sb, "unknown algorithm %d @ pos %llu for nid %llu, please upgrade kernel",
- map->m_algorithmformat, map->m_la, EROFS_I(inode)->nid);
- return -EOPNOTSUPP;
- }
+ DBG_BUGON(map->m_algorithmformat >= Z_EROFS_COMPRESSION_RUNTIME_MAX);
if (map->m_algorithmformat < Z_EROFS_COMPRESSION_MAX) {
if (!(sbi->available_compr_algs & BIT(map->m_algorithmformat))) {
erofs_err(inode->i_sb, "inconsistent algorithmtype %u for nid %llu",
--
2.47.3
reply other threads:[~2026-08-14 8:15 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260814081437.86684-1-xiang@kernel.org \
--to=xiang@kernel.org \
--cc=linux-erofs@lists.ozlabs.org \
--cc=linux-kernel@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox