Commit 664609e4 authored by Yue Hu's avatar Yue Hu Committed by Gao Xiang

erofs: fix illegal unmapped accesses in z_erofs_fill_inode_lazy()

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

Fixes: ab92184f ("erofs: add on-disk compressed tail-packing inline support")
Fixes: b15b2e30 ("erofs: support on-disk compressed fragments data")
Signed-off-by: default avatarYue Hu <huyue2@coolpad.com>
Reviewed-by: default avatarGao Xiang <hsiangkao@linux.alibaba.com>
Reviewed-by: default avatarChao Yu <chao@kernel.org>
Link: https://lore.kernel.org/r/20221005013528.62977-1-zbestahu@163.comSigned-off-by: default avatarGao Xiang <hsiangkao@linux.alibaba.com>
parent 9abf2313
...@@ -57,8 +57,7 @@ static int z_erofs_fill_inode_lazy(struct inode *inode) ...@@ -57,8 +57,7 @@ static int z_erofs_fill_inode_lazy(struct inode *inode)
pos = ALIGN(iloc(EROFS_SB(sb), vi->nid) + vi->inode_isize + pos = ALIGN(iloc(EROFS_SB(sb), vi->nid) + vi->inode_isize +
vi->xattr_isize, 8); vi->xattr_isize, 8);
kaddr = erofs_read_metabuf(&buf, sb, erofs_blknr(pos), kaddr = erofs_read_metabuf(&buf, sb, erofs_blknr(pos), EROFS_KMAP);
EROFS_KMAP_ATOMIC);
if (IS_ERR(kaddr)) { if (IS_ERR(kaddr)) {
err = PTR_ERR(kaddr); err = PTR_ERR(kaddr);
goto out_unlock; goto out_unlock;
...@@ -73,7 +72,7 @@ static int z_erofs_fill_inode_lazy(struct inode *inode) ...@@ -73,7 +72,7 @@ static int z_erofs_fill_inode_lazy(struct inode *inode)
vi->z_advise = Z_EROFS_ADVISE_FRAGMENT_PCLUSTER; vi->z_advise = Z_EROFS_ADVISE_FRAGMENT_PCLUSTER;
vi->z_fragmentoff = le64_to_cpu(*(__le64 *)h) ^ (1ULL << 63); vi->z_fragmentoff = le64_to_cpu(*(__le64 *)h) ^ (1ULL << 63);
vi->z_tailextent_headlcn = 0; vi->z_tailextent_headlcn = 0;
goto unmap_done; goto done;
} }
vi->z_advise = le16_to_cpu(h->h_advise); vi->z_advise = le16_to_cpu(h->h_advise);
vi->z_algorithmtype[0] = h->h_algorithmtype & 15; vi->z_algorithmtype[0] = h->h_algorithmtype & 15;
...@@ -85,7 +84,7 @@ static int z_erofs_fill_inode_lazy(struct inode *inode) ...@@ -85,7 +84,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", erofs_err(sb, "unknown HEAD%u format %u for nid %llu, please upgrade kernel",
headnr + 1, vi->z_algorithmtype[headnr], vi->nid); headnr + 1, vi->z_algorithmtype[headnr], vi->nid);
err = -EOPNOTSUPP; err = -EOPNOTSUPP;
goto unmap_done; goto out_put_metabuf;
} }
vi->z_logical_clusterbits = LOG_BLOCK_SIZE + (h->h_clusterbits & 7); vi->z_logical_clusterbits = LOG_BLOCK_SIZE + (h->h_clusterbits & 7);
...@@ -95,7 +94,7 @@ static int z_erofs_fill_inode_lazy(struct inode *inode) ...@@ -95,7 +94,7 @@ static int z_erofs_fill_inode_lazy(struct inode *inode)
erofs_err(sb, "per-inode big pcluster without sb feature for nid %llu", erofs_err(sb, "per-inode big pcluster without sb feature for nid %llu",
vi->nid); vi->nid);
err = -EFSCORRUPTED; err = -EFSCORRUPTED;
goto unmap_done; goto out_put_metabuf;
} }
if (vi->datalayout == EROFS_INODE_FLAT_COMPRESSION && if (vi->datalayout == EROFS_INODE_FLAT_COMPRESSION &&
!(vi->z_advise & Z_EROFS_ADVISE_BIG_PCLUSTER_1) ^ !(vi->z_advise & Z_EROFS_ADVISE_BIG_PCLUSTER_1) ^
...@@ -103,12 +102,8 @@ static int z_erofs_fill_inode_lazy(struct inode *inode) ...@@ -103,12 +102,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", erofs_err(sb, "big pcluster head1/2 of compact indexes should be consistent for nid %llu",
vi->nid); vi->nid);
err = -EFSCORRUPTED; 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) { if (vi->z_advise & Z_EROFS_ADVISE_INLINE_PCLUSTER) {
struct erofs_map_blocks map = { struct erofs_map_blocks map = {
...@@ -127,7 +122,7 @@ static int z_erofs_fill_inode_lazy(struct inode *inode) ...@@ -127,7 +122,7 @@ static int z_erofs_fill_inode_lazy(struct inode *inode)
err = -EFSCORRUPTED; err = -EFSCORRUPTED;
} }
if (err < 0) if (err < 0)
goto out_unlock; goto out_put_metabuf;
} }
if (vi->z_advise & Z_EROFS_ADVISE_FRAGMENT_PCLUSTER && if (vi->z_advise & Z_EROFS_ADVISE_FRAGMENT_PCLUSTER &&
...@@ -141,11 +136,14 @@ static int z_erofs_fill_inode_lazy(struct inode *inode) ...@@ -141,11 +136,14 @@ static int z_erofs_fill_inode_lazy(struct inode *inode)
EROFS_GET_BLOCKS_FINDTAIL); EROFS_GET_BLOCKS_FINDTAIL);
erofs_put_metabuf(&map.buf); erofs_put_metabuf(&map.buf);
if (err < 0) if (err < 0)
goto out_unlock; goto out_put_metabuf;
} }
done:
/* paired with smp_mb() at the beginning of the function */ /* paired with smp_mb() at the beginning of the function */
smp_mb(); smp_mb();
set_bit(EROFS_I_Z_INITED_BIT, &vi->flags); set_bit(EROFS_I_Z_INITED_BIT, &vi->flags);
out_put_metabuf:
erofs_put_metabuf(&buf);
out_unlock: out_unlock:
clear_and_wake_up_bit(EROFS_I_BL_Z_BIT, &vi->flags); clear_and_wake_up_bit(EROFS_I_BL_Z_BIT, &vi->flags);
return err; return err;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment