forked from Minki/linux
Changes since last update:
- Fix return codes in erofs_fscache_{meta_,}read_folio error paths; - Fix potential wrong pcluster sizes for later non-4K lclusters; - Fix in-memory pcluster use-after-free on UP platforms. -----BEGIN PGP SIGNATURE----- iIcEABYIAC8WIQThPAmQN9sSA0DVxtI5NzHcH7XmBAUCYxdnPREceGlhbmdAa2Vy bmVsLm9yZwAKCRA5NzHcH7XmBGzxAQCvIteTLkD2HWvvflFcrby6o1vWxoJSDFig J3QZUgH/TAEAvR6Jyl4oL4/kwtw+2ZuWeXnMI9FXBfz9pyDR/MiCQQw= =p6+J -----END PGP SIGNATURE----- Merge tag 'erofs-for-6.0-rc5-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/xiang/erofs Pull erofs fixes from Gao Xiang: - Fix return codes in erofs_fscache_{meta_,}read_folio error paths - Fix potential wrong pcluster sizes for later non-4K lclusters - Fix in-memory pcluster use-after-free on UP platforms * tag 'erofs-for-6.0-rc5-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/xiang/erofs: erofs: fix pcluster use-after-free on UP platforms erofs: avoid the potentially wrong m_plen for big pcluster erofs: fix error return code in erofs_fscache_{meta_,}read_folio
This commit is contained in:
commit
d2ec799d1c
@ -222,8 +222,10 @@ static int erofs_fscache_meta_read_folio(struct file *data, struct folio *folio)
|
||||
|
||||
rreq = erofs_fscache_alloc_request(folio_mapping(folio),
|
||||
folio_pos(folio), folio_size(folio));
|
||||
if (IS_ERR(rreq))
|
||||
if (IS_ERR(rreq)) {
|
||||
ret = PTR_ERR(rreq);
|
||||
goto out;
|
||||
}
|
||||
|
||||
return erofs_fscache_read_folios_async(mdev.m_fscache->cookie,
|
||||
rreq, mdev.m_pa);
|
||||
@ -301,8 +303,10 @@ static int erofs_fscache_read_folio(struct file *file, struct folio *folio)
|
||||
|
||||
rreq = erofs_fscache_alloc_request(folio_mapping(folio),
|
||||
folio_pos(folio), folio_size(folio));
|
||||
if (IS_ERR(rreq))
|
||||
if (IS_ERR(rreq)) {
|
||||
ret = PTR_ERR(rreq);
|
||||
goto out_unlock;
|
||||
}
|
||||
|
||||
pstart = mdev.m_pa + (pos - map.m_la);
|
||||
return erofs_fscache_read_folios_async(mdev.m_fscache->cookie,
|
||||
|
@ -195,7 +195,6 @@ struct erofs_workgroup {
|
||||
atomic_t refcount;
|
||||
};
|
||||
|
||||
#if defined(CONFIG_SMP)
|
||||
static inline bool erofs_workgroup_try_to_freeze(struct erofs_workgroup *grp,
|
||||
int val)
|
||||
{
|
||||
@ -224,34 +223,6 @@ static inline int erofs_wait_on_workgroup_freezed(struct erofs_workgroup *grp)
|
||||
return atomic_cond_read_relaxed(&grp->refcount,
|
||||
VAL != EROFS_LOCKED_MAGIC);
|
||||
}
|
||||
#else
|
||||
static inline bool erofs_workgroup_try_to_freeze(struct erofs_workgroup *grp,
|
||||
int val)
|
||||
{
|
||||
preempt_disable();
|
||||
/* no need to spin on UP platforms, let's just disable preemption. */
|
||||
if (val != atomic_read(&grp->refcount)) {
|
||||
preempt_enable();
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static inline void erofs_workgroup_unfreeze(struct erofs_workgroup *grp,
|
||||
int orig_val)
|
||||
{
|
||||
preempt_enable();
|
||||
}
|
||||
|
||||
static inline int erofs_wait_on_workgroup_freezed(struct erofs_workgroup *grp)
|
||||
{
|
||||
int v = atomic_read(&grp->refcount);
|
||||
|
||||
/* workgroup is never freezed on uniprocessor systems */
|
||||
DBG_BUGON(v == EROFS_LOCKED_MAGIC);
|
||||
return v;
|
||||
}
|
||||
#endif /* !CONFIG_SMP */
|
||||
#endif /* !CONFIG_EROFS_FS_ZIP */
|
||||
|
||||
/* we strictly follow PAGE_SIZE and no buffer head yet */
|
||||
|
@ -141,7 +141,7 @@ struct z_erofs_maprecorder {
|
||||
u8 type, headtype;
|
||||
u16 clusterofs;
|
||||
u16 delta[2];
|
||||
erofs_blk_t pblk, compressedlcs;
|
||||
erofs_blk_t pblk, compressedblks;
|
||||
erofs_off_t nextpackoff;
|
||||
};
|
||||
|
||||
@ -192,7 +192,7 @@ static int legacy_load_cluster_from_disk(struct z_erofs_maprecorder *m,
|
||||
DBG_BUGON(1);
|
||||
return -EFSCORRUPTED;
|
||||
}
|
||||
m->compressedlcs = m->delta[0] &
|
||||
m->compressedblks = m->delta[0] &
|
||||
~Z_EROFS_VLE_DI_D0_CBLKCNT;
|
||||
m->delta[0] = 1;
|
||||
}
|
||||
@ -293,7 +293,7 @@ static int unpack_compacted_index(struct z_erofs_maprecorder *m,
|
||||
DBG_BUGON(1);
|
||||
return -EFSCORRUPTED;
|
||||
}
|
||||
m->compressedlcs = lo & ~Z_EROFS_VLE_DI_D0_CBLKCNT;
|
||||
m->compressedblks = lo & ~Z_EROFS_VLE_DI_D0_CBLKCNT;
|
||||
m->delta[0] = 1;
|
||||
return 0;
|
||||
} else if (i + 1 != (int)vcnt) {
|
||||
@ -497,7 +497,7 @@ static int z_erofs_get_extent_compressedlen(struct z_erofs_maprecorder *m,
|
||||
return 0;
|
||||
}
|
||||
lcn = m->lcn + 1;
|
||||
if (m->compressedlcs)
|
||||
if (m->compressedblks)
|
||||
goto out;
|
||||
|
||||
err = z_erofs_load_cluster_from_disk(m, lcn, false);
|
||||
@ -506,7 +506,7 @@ static int z_erofs_get_extent_compressedlen(struct z_erofs_maprecorder *m,
|
||||
|
||||
/*
|
||||
* If the 1st NONHEAD lcluster has already been handled initially w/o
|
||||
* valid compressedlcs, which means at least it mustn't be CBLKCNT, or
|
||||
* valid compressedblks, which means at least it mustn't be CBLKCNT, or
|
||||
* an internal implemenatation error is detected.
|
||||
*
|
||||
* The following code can also handle it properly anyway, but let's
|
||||
@ -523,12 +523,12 @@ static int z_erofs_get_extent_compressedlen(struct z_erofs_maprecorder *m,
|
||||
* if the 1st NONHEAD lcluster is actually PLAIN or HEAD type
|
||||
* rather than CBLKCNT, it's a 1 lcluster-sized pcluster.
|
||||
*/
|
||||
m->compressedlcs = 1;
|
||||
m->compressedblks = 1 << (lclusterbits - LOG_BLOCK_SIZE);
|
||||
break;
|
||||
case Z_EROFS_VLE_CLUSTER_TYPE_NONHEAD:
|
||||
if (m->delta[0] != 1)
|
||||
goto err_bonus_cblkcnt;
|
||||
if (m->compressedlcs)
|
||||
if (m->compressedblks)
|
||||
break;
|
||||
fallthrough;
|
||||
default:
|
||||
@ -539,7 +539,7 @@ static int z_erofs_get_extent_compressedlen(struct z_erofs_maprecorder *m,
|
||||
return -EFSCORRUPTED;
|
||||
}
|
||||
out:
|
||||
map->m_plen = (u64)m->compressedlcs << lclusterbits;
|
||||
map->m_plen = (u64)m->compressedblks << LOG_BLOCK_SIZE;
|
||||
return 0;
|
||||
err_bonus_cblkcnt:
|
||||
erofs_err(m->inode->i_sb,
|
||||
|
Loading…
Reference in New Issue
Block a user