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:ab92184ff8
("erofs: add on-disk compressed tail-packing inline support") Fixes:b15b2e307c
("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>
This commit is contained in:
parent
9abf2313ad
commit
664609e49f
@ -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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
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 @@ unmap_done:
|
|||||||
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 @@ unmap_done:
|
|||||||
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;
|
||||||
|
Loading…
Reference in New Issue
Block a user