]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
erofs: fix illegal unmapped accesses in z_erofs_fill_inode_lazy()
authorYue Hu <huyue2@coolpad.com>
Wed, 5 Oct 2022 01:35:28 +0000 (09:35 +0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 3 Nov 2022 15:00:27 +0000 (00:00 +0900)
[ Upstream commit 664609e49f1c84fc97987b2bf64544e586b8849c ]

Note that we are still accessing 'h_idata_size' and 'h_fragmentoff'
after calling erofs_put_metabuf(), that is not correct. Fix it.

Fixes: ab92184ff8f1 ("erofs: add on-disk compressed tail-packing inline support")
Fixes: b15b2e307c3a ("erofs: support on-disk compressed fragments data")
Signed-off-by: Yue Hu <huyue2@coolpad.com>
Reviewed-by: Gao Xiang <hsiangkao@linux.alibaba.com>
Reviewed-by: Chao Yu <chao@kernel.org>
Link: https://lore.kernel.org/r/20221005013528.62977-1-zbestahu@163.com
Signed-off-by: Gao Xiang <hsiangkao@linux.alibaba.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
fs/erofs/zmap.c

index d58549ca1df9b8d326fbaffc0a2f6cdfe26f9362..63fd2f146026586bac6ccfb9e069fd6d6384bccb 100644 (file)
@@ -61,8 +61,7 @@ static int z_erofs_fill_inode_lazy(struct inode *inode)
 
        pos = ALIGN(iloc(EROFS_SB(sb), vi->nid) + vi->inode_isize +
                    vi->xattr_isize, 8);
-       kaddr = erofs_read_metabuf(&buf, sb, erofs_blknr(pos),
-                                  EROFS_KMAP_ATOMIC);
+       kaddr = erofs_read_metabuf(&buf, sb, erofs_blknr(pos), EROFS_KMAP);
        if (IS_ERR(kaddr)) {
                err = PTR_ERR(kaddr);
                goto out_unlock;
@@ -79,7 +78,7 @@ static int z_erofs_fill_inode_lazy(struct inode *inode)
                erofs_err(sb, "unknown HEAD%u format %u for nid %llu, please upgrade kernel",
                          headnr + 1, vi->z_algorithmtype[headnr], vi->nid);
                err = -EOPNOTSUPP;
-               goto unmap_done;
+               goto out_put_metabuf;
        }
 
        vi->z_logical_clusterbits = LOG_BLOCK_SIZE + (h->h_clusterbits & 7);
@@ -89,7 +88,7 @@ static int z_erofs_fill_inode_lazy(struct inode *inode)
                erofs_err(sb, "per-inode big pcluster without sb feature for nid %llu",
                          vi->nid);
                err = -EFSCORRUPTED;
-               goto unmap_done;
+               goto out_put_metabuf;
        }
        if (vi->datalayout == EROFS_INODE_FLAT_COMPRESSION &&
            !(vi->z_advise & Z_EROFS_ADVISE_BIG_PCLUSTER_1) ^
@@ -97,12 +96,8 @@ static int z_erofs_fill_inode_lazy(struct inode *inode)
                erofs_err(sb, "big pcluster head1/2 of compact indexes should be consistent for nid %llu",
                          vi->nid);
                err = -EFSCORRUPTED;
-               goto unmap_done;
+               goto out_put_metabuf;
        }
-unmap_done:
-       erofs_put_metabuf(&buf);
-       if (err)
-               goto out_unlock;
 
        if (vi->z_advise & Z_EROFS_ADVISE_INLINE_PCLUSTER) {
                struct erofs_map_blocks map = {
@@ -121,11 +116,13 @@ unmap_done:
                        err = -EFSCORRUPTED;
                }
                if (err < 0)
-                       goto out_unlock;
+                       goto out_put_metabuf;
        }
        /* paired with smp_mb() at the beginning of the function */
        smp_mb();
        set_bit(EROFS_I_Z_INITED_BIT, &vi->flags);
+out_put_metabuf:
+       erofs_put_metabuf(&buf);
 out_unlock:
        clear_and_wake_up_bit(EROFS_I_BL_Z_BIT, &vi->flags);
        return err;