From 9f38975317cf08b00f4fffabc07de87f3ef7b8e1 Mon Sep 17 00:00:00 2001 From: Wang Wensheng Date: Sat, 7 May 2022 08:24:40 +0000 Subject: [PATCH] share_pool: Fix ABBA deadlock hulk inclusion category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/I54I7W CVE: NA There is a ABBA deadlock in the process of sp_group_add_task and proc_stat_show(). PROCESS A: sp_group_add_task() acquire sp_group_sem write lock ->sp_init_proc_stat() acquire sp_spg_stat_sem write lock PROCESS B: proc_stat_show() acquire sp_spg_stat_sem read lock ->idr_proc_stat_cb() acquire sp_group_sem read lock Here we choose the simplest way that acquires sp_group_sem and sp_stat_sem read lock subsequently in proc_stat_show(), since it just has effect on the process of debug feature. Signed-off-by: Wang Wensheng Reviewed-by: Weilong Chen Signed-off-by: Yongqiang Liu --- mm/share_pool.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/mm/share_pool.c b/mm/share_pool.c index 40147ef85ba5..f33b4b308dcf 100644 --- a/mm/share_pool.c +++ b/mm/share_pool.c @@ -4118,7 +4118,6 @@ static int idr_proc_stat_cb(int id, void *p, void *data) long sp_res, sp_res_nsize, non_sp_res, non_sp_shm; /* to prevent ABBA deadlock, first hold sp_group_sem */ - down_read(&sp_group_sem); mutex_lock(&spg_stat->lock); hash_for_each(spg_stat->hash, i, spg_proc_stat, gnode) { proc_stat = spg_proc_stat->proc_stat; @@ -4147,7 +4146,6 @@ static int idr_proc_stat_cb(int id, void *p, void *data) seq_putc(seq, '\n'); } mutex_unlock(&spg_stat->lock); - up_read(&sp_group_sem); return 0; } @@ -4165,10 +4163,16 @@ static int proc_stat_show(struct seq_file *seq, void *offset) byte2kb(atomic64_read(&kthread_stat.alloc_size)), byte2kb(atomic64_read(&kthread_stat.k2u_size))); - /* pay attention to potential ABBA deadlock */ + /* + * This ugly code is just for fixing the ABBA deadlock against + * sp_group_add_task. + */ + down_read(&sp_group_sem); down_read(&sp_spg_stat_sem); idr_for_each(&sp_spg_stat_idr, idr_proc_stat_cb, seq); up_read(&sp_spg_stat_sem); + up_read(&sp_group_sem); + return 0; } -- GitLab