From nobody Fri Oct 3 21:56:42 2025 Received: from out30-118.freemail.mail.aliyun.com (out30-118.freemail.mail.aliyun.com [115.124.30.118]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 09A4D502BE for ; Sun, 24 Aug 2025 15:12:05 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=115.124.30.118 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1756048329; cv=none; b=oitiXZW3pRWe9j/WN9LU/sJD+UbcrpnNyEgZpS6GxWm1fmnEugNtT+r5kpF7L8KnqOMN81+RaRnfx/ad9Dphy4BoDVCGtW6H3aaAUWYCaFm+VNEfFYXIDU0ucvQbUbdpJNA0mYCMo4BH8GFY3qjUqvIiaOpy3zTqTed31Lx2Wlw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1756048329; c=relaxed/simple; bh=Xvag/undVxEeSQ3cfNf9wxJ5QQf6mF12e4Hb4JXuhVs=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=s+oBMXzcVRVLcLr35rpQamUJyYXsjgSfcuwMtC+w/56ISg8/Bxrd/viKTe9uPL3HCW9JDJcXO1Om3OK8k0BDvZqGfz3nsKOZq1fvDIsFK//n/KHEEfqc/nSOiwWtoI3A7aR0QA2XA4jv0+XYzjb3VN2s+7DFc00nKNy9nWYcoKk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.alibaba.com; spf=pass smtp.mailfrom=linux.alibaba.com; dkim=pass (1024-bit key) header.d=linux.alibaba.com header.i=@linux.alibaba.com header.b=orFWHP0y; arc=none smtp.client-ip=115.124.30.118 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.alibaba.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.alibaba.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.alibaba.com header.i=@linux.alibaba.com header.b="orFWHP0y" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.alibaba.com; s=default; t=1756048323; h=From:To:Subject:Date:Message-ID:MIME-Version; bh=hK5XLprToS2HpWr+A1tVE+AZ/QnOKtjAsUATr5kHsAw=; b=orFWHP0yI51DdvtXVFCeSRwyADlq3Br8DYX/jx44FtKajQlj4yv6SwWoSI8wRQmVC1YnDnKNtXvHQ7hkJt964cQY8ndksY39oH8gwXZfLYdwHhwN/0gXqCb/2a7D++JfS85FkD50c1uTGZOW2ljDu1amBOVmvqdFswUD9D4dhYc= Received: from x31i01179.sqa.na131.tbsite.net(mailfrom:hsiangkao@linux.alibaba.com fp:SMTPD_---0WmOoz.C_1756048318 cluster:ay36) by smtp.aliyun-inc.com; Sun, 24 Aug 2025 23:12:02 +0800 From: Gao Xiang To: linux-erofs@lists.ozlabs.org Cc: LKML , Gao Xiang , syzbot+5a398eb460ddaa6f242f@syzkaller.appspotmail.com Subject: [PATCH v3] erofs: fix invalid algorithm for encoded extents Date: Sun, 24 Aug 2025 23:11:57 +0800 Message-ID: <20250824151157.1138706-1-hsiangkao@linux.alibaba.com> X-Mailer: git-send-email 2.43.5 In-Reply-To: <20250823093018.3117864-1-hsiangkao@linux.alibaba.com> References: <20250823093018.3117864-1-hsiangkao@linux.alibaba.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" The current algorithm sanity checks do not properly apply to new encoded extents. Unify the algorithm format check with Z_EROFS_COMPRESSION_MAX and ensure consistency with sbi->available_compr_algs. Reported-and-tested-by: syzbot+5a398eb460ddaa6f242f@syzkaller.appspotmail.c= om Closes: https://lore.kernel.org/r/68a8bd20.050a0220.37038e.005a.GAE@google.= com Fixes: 1d191b4ca51d ("erofs: implement encoded extent metadata") Thanks-to: Edward Adam Davis Signed-off-by: Gao Xiang --- v3: - plain extents shouldn't be targeted for the consistency check. fs/erofs/zmap.c | 67 +++++++++++++++++++++++++++---------------------- 1 file changed, 37 insertions(+), 30 deletions(-) diff --git a/fs/erofs/zmap.c b/fs/erofs/zmap.c index a93efd95c555..798223e6da9c 100644 --- a/fs/erofs/zmap.c +++ b/fs/erofs/zmap.c @@ -394,10 +394,10 @@ static int z_erofs_map_blocks_fo(struct inode *inode, .map =3D map, .in_mbox =3D erofs_inode_in_metabox(inode), }; - int err =3D 0; - unsigned int endoff, afmt; + unsigned int endoff; unsigned long initial_lcn; unsigned long long ofs, end; + int err; =20 ofs =3D flags & EROFS_GET_BLOCKS_FINDTAIL ? inode->i_size - 1 : map->m_la; if (fragment && !(flags & EROFS_GET_BLOCKS_FINDTAIL) && @@ -482,20 +482,15 @@ static int z_erofs_map_blocks_fo(struct inode *inode, err =3D -EFSCORRUPTED; goto unmap_out; } - afmt =3D vi->z_advise & Z_EROFS_ADVISE_INTERLACED_PCLUSTER ? - Z_EROFS_COMPRESSION_INTERLACED : - Z_EROFS_COMPRESSION_SHIFTED; + if (vi->z_advise & Z_EROFS_ADVISE_INTERLACED_PCLUSTER) + map->m_algorithmformat =3D Z_EROFS_COMPRESSION_INTERLACED; + else + map->m_algorithmformat =3D Z_EROFS_COMPRESSION_SHIFTED; + } else if (m.headtype =3D=3D Z_EROFS_LCLUSTER_TYPE_HEAD2) { + map->m_algorithmformat =3D vi->z_algorithmtype[1]; } else { - afmt =3D m.headtype =3D=3D Z_EROFS_LCLUSTER_TYPE_HEAD2 ? - vi->z_algorithmtype[1] : vi->z_algorithmtype[0]; - if (!(EROFS_I_SB(inode)->available_compr_algs & (1 << afmt))) { - erofs_err(sb, "inconsistent algorithmtype %u for nid %llu", - afmt, vi->nid); - err =3D -EFSCORRUPTED; - goto unmap_out; - } + map->m_algorithmformat =3D vi->z_algorithmtype[0]; } - map->m_algorithmformat =3D afmt; =20 if ((flags & EROFS_GET_BLOCKS_FIEMAP) || ((flags & EROFS_GET_BLOCKS_READMORE) && @@ -626,9 +621,9 @@ static int z_erofs_fill_inode(struct inode *inode, stru= ct erofs_map_blocks *map) { struct erofs_inode *const vi =3D EROFS_I(inode); struct super_block *const sb =3D inode->i_sb; - int err, headnr; - erofs_off_t pos; struct z_erofs_map_header *h; + erofs_off_t pos; + int err =3D 0; =20 if (test_bit(EROFS_I_Z_INITED_BIT, &vi->flags)) { /* @@ -642,7 +637,6 @@ static int z_erofs_fill_inode(struct inode *inode, stru= ct erofs_map_blocks *map) if (wait_on_bit_lock(&vi->flags, EROFS_I_BL_Z_BIT, TASK_KILLABLE)) return -ERESTARTSYS; =20 - err =3D 0; if (test_bit(EROFS_I_Z_INITED_BIT, &vi->flags)) goto out_unlock; =20 @@ -679,15 +673,6 @@ static int z_erofs_fill_inode(struct inode *inode, str= uct erofs_map_blocks *map) else if (vi->z_advise & Z_EROFS_ADVISE_INLINE_PCLUSTER) vi->z_idata_size =3D le16_to_cpu(h->h_idata_size); =20 - headnr =3D 0; - if (vi->z_algorithmtype[0] >=3D Z_EROFS_COMPRESSION_MAX || - vi->z_algorithmtype[++headnr] >=3D Z_EROFS_COMPRESSION_MAX) { - erofs_err(sb, "unknown HEAD%u format %u for nid %llu, please upgrade ker= nel", - headnr + 1, vi->z_algorithmtype[headnr], vi->nid); - err =3D -EOPNOTSUPP; - goto out_unlock; - } - if (!erofs_sb_has_big_pcluster(EROFS_SB(sb)) && vi->z_advise & (Z_EROFS_ADVISE_BIG_PCLUSTER_1 | Z_EROFS_ADVISE_BIG_PCLUSTER_2)) { @@ -726,6 +711,30 @@ static int z_erofs_fill_inode(struct inode *inode, str= uct erofs_map_blocks *map) return err; } =20 +static int z_erofs_map_sanity_check(struct inode *inode, + struct erofs_map_blocks *map) +{ + struct erofs_sb_info *sbi =3D EROFS_I_SB(inode); + + if (!(map->m_flags & EROFS_MAP_ENCODED)) + return 0; + if (unlikely(map->m_algorithmformat >=3D Z_EROFS_COMPRESSION_RUNTIME_MAX)= ) { + erofs_err(inode->i_sb, "unknown algorithm %d @ pos %llu for nid %llu, pl= ease upgrade kernel", + map->m_algorithmformat, map->m_la, EROFS_I(inode)->nid); + return -EOPNOTSUPP; + } + if (unlikely(map->m_algorithmformat < Z_EROFS_COMPRESSION_MAX && + !(sbi->available_compr_algs & (1 << map->m_algorithmformat)))) { + erofs_err(inode->i_sb, "inconsistent algorithmtype %u for nid %llu", + map->m_algorithmformat, EROFS_I(inode)->nid); + return -EFSCORRUPTED; + } + if (unlikely(map->m_plen > Z_EROFS_PCLUSTER_MAX_SIZE || + map->m_llen > Z_EROFS_PCLUSTER_MAX_DSIZE)) + return -EOPNOTSUPP; + return 0; +} + int z_erofs_map_blocks_iter(struct inode *inode, struct erofs_map_blocks *= map, int flags) { @@ -746,10 +755,8 @@ int z_erofs_map_blocks_iter(struct inode *inode, struc= t erofs_map_blocks *map, else err =3D z_erofs_map_blocks_fo(inode, map, flags); } - if (!err && (map->m_flags & EROFS_MAP_ENCODED) && - unlikely(map->m_plen > Z_EROFS_PCLUSTER_MAX_SIZE || - map->m_llen > Z_EROFS_PCLUSTER_MAX_DSIZE)) - err =3D -EOPNOTSUPP; + if (!err) + err =3D z_erofs_map_sanity_check(inode, map); if (err) map->m_llen =3D 0; } --=20 2.43.5