gfs2: fix use-after-free in trans_drain
This patch adds code to function trans_drain to remove drained bd elements from the ail lists, if queued, before freeing the bd. If we don't remove the bd from the ail, function ail_drain will try to reference the bd after it has been freed by trans_drain. Thanks to Andy Price for his analysis of the problem. Reported-by: Andy Price <anprice@redhat.com> Signed-off-by: Bob Peterson <rpeterso@redhat.com> Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
This commit is contained in:
parent
eb602521f4
commit
1a5a2cfd34
|
@ -998,12 +998,16 @@ static void trans_drain(struct gfs2_trans *tr)
|
|||
while (!list_empty(head)) {
|
||||
bd = list_first_entry(head, struct gfs2_bufdata, bd_list);
|
||||
list_del_init(&bd->bd_list);
|
||||
if (!list_empty(&bd->bd_ail_st_list))
|
||||
gfs2_remove_from_ail(bd);
|
||||
kmem_cache_free(gfs2_bufdata_cachep, bd);
|
||||
}
|
||||
head = &tr->tr_databuf;
|
||||
while (!list_empty(head)) {
|
||||
bd = list_first_entry(head, struct gfs2_bufdata, bd_list);
|
||||
list_del_init(&bd->bd_list);
|
||||
if (!list_empty(&bd->bd_ail_st_list))
|
||||
gfs2_remove_from_ail(bd);
|
||||
kmem_cache_free(gfs2_bufdata_cachep, bd);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -169,6 +169,8 @@ static struct gfs2_bufdata *gfs2_alloc_bufdata(struct gfs2_glock *gl,
|
|||
bd->bd_bh = bh;
|
||||
bd->bd_gl = gl;
|
||||
INIT_LIST_HEAD(&bd->bd_list);
|
||||
INIT_LIST_HEAD(&bd->bd_ail_st_list);
|
||||
INIT_LIST_HEAD(&bd->bd_ail_gl_list);
|
||||
bh->b_private = bd;
|
||||
return bd;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue