mirror of https://gitee.com/openkylin/linux.git
staging: erofs: avoid loop in submit chains
As reported by erofs-utils fuzzer, 2 conditions can happen in corrupted images, which can cause unexpected behaviors. - access the same pcluster one more time; - access the tail end pcluster again, e.g. _ access again (will trigger tail merging) | 1 2 3 1 2 -> 1 2 3 1 |_ tail end of the chain \___/ (unexpected behavior) Let's detect and avoid them now. Reviewed-by: Chao Yu <yuchao0@huawei.com> Signed-off-by: Gao Xiang <gaoxiang25@huawei.com> Link: https://lore.kernel.org/r/20190821030908.40282-1-gaoxiang25@huawei.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
2cb05d8788
commit
bfc4ccb158
|
@ -132,7 +132,7 @@ enum z_erofs_collectmode {
|
|||
struct z_erofs_collector {
|
||||
struct z_erofs_pagevec_ctor vector;
|
||||
|
||||
struct z_erofs_pcluster *pcl;
|
||||
struct z_erofs_pcluster *pcl, *tailpcl;
|
||||
struct z_erofs_collection *cl;
|
||||
struct page **compressedpages;
|
||||
z_erofs_next_pcluster_t owned_head;
|
||||
|
@ -353,6 +353,11 @@ static struct z_erofs_collection *cllookup(struct z_erofs_collector *clt,
|
|||
return NULL;
|
||||
|
||||
pcl = container_of(grp, struct z_erofs_pcluster, obj);
|
||||
if (clt->owned_head == &pcl->next || pcl == clt->tailpcl) {
|
||||
DBG_BUGON(1);
|
||||
erofs_workgroup_put(grp);
|
||||
return ERR_PTR(-EFSCORRUPTED);
|
||||
}
|
||||
|
||||
cl = z_erofs_primarycollection(pcl);
|
||||
if (unlikely(cl->pageofs != (map->m_la & ~PAGE_MASK))) {
|
||||
|
@ -381,7 +386,13 @@ static struct z_erofs_collection *cllookup(struct z_erofs_collector *clt,
|
|||
}
|
||||
}
|
||||
mutex_lock(&cl->lock);
|
||||
/* used to check tail merging loop due to corrupted images */
|
||||
if (clt->owned_head == Z_EROFS_PCLUSTER_TAIL)
|
||||
clt->tailpcl = pcl;
|
||||
clt->mode = try_to_claim_pcluster(pcl, &clt->owned_head);
|
||||
/* clean tailpcl if the current owned_head is Z_EROFS_PCLUSTER_TAIL */
|
||||
if (clt->owned_head == Z_EROFS_PCLUSTER_TAIL)
|
||||
clt->tailpcl = NULL;
|
||||
clt->pcl = pcl;
|
||||
clt->cl = cl;
|
||||
return cl;
|
||||
|
@ -434,6 +445,9 @@ static struct z_erofs_collection *clregister(struct z_erofs_collector *clt,
|
|||
kmem_cache_free(pcluster_cachep, pcl);
|
||||
return ERR_PTR(-EAGAIN);
|
||||
}
|
||||
/* used to check tail merging loop due to corrupted images */
|
||||
if (clt->owned_head == Z_EROFS_PCLUSTER_TAIL)
|
||||
clt->tailpcl = pcl;
|
||||
clt->owned_head = &pcl->next;
|
||||
clt->pcl = pcl;
|
||||
clt->cl = cl;
|
||||
|
|
Loading…
Reference in New Issue