From nobody Fri Nov 22 17:08:06 2024 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 F14401D61A1 for ; Fri, 15 Nov 2024 17:37:20 +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=1731692244; cv=none; b=AKkQwkn6vwZOaLOg7yjMsWYJEI/EXxiVt71rkTpCTnlI1WWRUBYdWsgJVo6bV0nmg8/BkNaVFx2viHt4X1gECxy7+axFk5ann71u09GKWCeTVDg8BksoSdHwGOWsDsYmmlA111G+cSphzRnH+AmB14uGwURn509AKdNOsiy4CSU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1731692244; c=relaxed/simple; bh=lxdMuJDoPhT7Q7+0NfYML3iNAiw1cd6bSRP5MItqQYQ=; h=From:To:Cc:Subject:Date:Message-ID:MIME-Version; b=uF4MV2nHsX5uMyQuy6gV5+54tGq7UeRg23EHE4Z3PILDmng/rJFqdc8E9qvKuCQN7lgFT/ABxG5zCiIh7r+b1FPDsSsjGn4ObqStHogoac4z54zi9bPX/k0aGtsrhVCWk24q6GU9DGf3294HxmOT9y+/AVyaGRzIssRq8Et6YKo= 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=PTOBeByM; 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="PTOBeByM" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.alibaba.com; s=default; t=1731692230; h=From:To:Subject:Date:Message-ID:MIME-Version; bh=0C4zvkjgOBhm5nZYv4qVK0pKEHqWTMIfQl4q5rV5u+o=; b=PTOBeByMqHlkITpHZdU3704jchnTI0hyTL7JQCuRnoPD23L7LOCnsvQZZ8M0H4JVIvYE4mhwnsCS72AYvAGc+TFxcjx3M264eg1hunloubc5rwgW/AIEJraMXNUEO+uMkHWcUTkERsZ7gxjuse5/B5Pk5e9Jn2C5yIy5rF0+6U4= Received: from x31i01179.sqa.na131.tbsite.net(mailfrom:hsiangkao@linux.alibaba.com fp:SMTPD_---0WJUJogH_1731692222 cluster:ay36) by smtp.aliyun-inc.com; Sat, 16 Nov 2024 01:37:10 +0800 From: Gao Xiang To: linux-erofs@lists.ozlabs.org Cc: LKML , Gao Xiang , syzbot+6c0b301317aa0156f9eb@syzkaller.appspotmail.com Subject: [PATCH] erofs: handle NONHEAD !delta[1] lclusters gracefully Date: Sat, 16 Nov 2024 01:36:51 +0800 Message-ID: <20241115173651.3339514-1-hsiangkao@linux.alibaba.com> X-Mailer: git-send-email 2.43.5 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" syzbot reported a WARNING in iomap_iter_done: iomap_fiemap+0x73b/0x9b0 fs/iomap/fiemap.c:80 ioctl_fiemap fs/ioctl.c:220 [inline] Generally, NONHEAD lclusters won't have delta[1]=3D=3D0, except for crafted images and filesystems created by pre-1.0 mkfs versions. Previously, it would immediately bail out if delta[1]=3D=3D0, which led to inadequate decompressed lengths (thus FIEMAP is impacted). Treat it as delta[1]=3D1 to work around these legacy mkfs versions. `lclusterbits > 14` is illegal for compact indexes, error out too. Reported-by: syzbot+6c0b301317aa0156f9eb@syzkaller.appspotmail.com Closes: https://lore.kernel.org/r/67373c0c.050a0220.2a2fcc.0079.GAE@google.= com Fixes: d95ae5e25326 ("erofs: add support for the full decompressed length") Fixes: 001b8ccd0650 ("erofs: fix compact 4B support for 16k block size") Signed-off-by: Gao Xiang --- fs/erofs/zmap.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/fs/erofs/zmap.c b/fs/erofs/zmap.c index a076cca1f547..4535f2f0a014 100644 --- a/fs/erofs/zmap.c +++ b/fs/erofs/zmap.c @@ -219,7 +219,7 @@ static int z_erofs_load_compact_lcluster(struct z_erofs= _maprecorder *m, unsigned int amortizedshift; erofs_off_t pos; =20 - if (lcn >=3D totalidx) + if (lcn >=3D totalidx || vi->z_logical_clusterbits > 14) return -EINVAL; =20 m->lcn =3D lcn; @@ -390,7 +390,7 @@ static int z_erofs_get_extent_decompressedlen(struct z_= erofs_maprecorder *m) u64 lcn =3D m->lcn, headlcn =3D map->m_la >> lclusterbits; int err; =20 - do { + while (1) { /* handle the last EOF pcluster (no next HEAD lcluster) */ if ((lcn << lclusterbits) >=3D inode->i_size) { map->m_llen =3D inode->i_size - map->m_la; @@ -402,14 +402,16 @@ static int z_erofs_get_extent_decompressedlen(struct = z_erofs_maprecorder *m) return err; =20 if (m->type =3D=3D Z_EROFS_LCLUSTER_TYPE_NONHEAD) { - DBG_BUGON(!m->delta[1] && - m->clusterofs !=3D 1 << lclusterbits); + /* work around invalid d1 generated by pre-1.0 mkfs */ + if (unlikely(!m->delta[1])) { + m->delta[1] =3D 1; + DBG_BUGON(1); + } } else if (m->type =3D=3D Z_EROFS_LCLUSTER_TYPE_PLAIN || m->type =3D=3D Z_EROFS_LCLUSTER_TYPE_HEAD1 || m->type =3D=3D Z_EROFS_LCLUSTER_TYPE_HEAD2) { - /* go on until the next HEAD lcluster */ if (lcn !=3D headlcn) - break; + break; /* ends at the next HEAD lcluster */ m->delta[1] =3D 1; } else { erofs_err(inode->i_sb, "unknown type %u @ lcn %llu of nid %llu", @@ -418,8 +420,7 @@ static int z_erofs_get_extent_decompressedlen(struct z_= erofs_maprecorder *m) return -EOPNOTSUPP; } lcn +=3D m->delta[1]; - } while (m->delta[1]); - + } map->m_llen =3D (lcn << lclusterbits) + m->clusterofs - map->m_la; return 0; } --=20 2.43.5