hulk inclusion category: bugfix bugzilla: 46904, https://gitee.com/openeuler/kernel/issues/IA5JXN
--------------------------------
In freeing process, set memcg->hpool or dpool_global_hpool to NULL and then freeing it. To avoid UAF problem of hpool, we have to make sure the users that already hold pointer to hpool don't use the pointer after freeing hpool. The freeing of hpool should block until make sure all such users don't use hpool. Since anyone who want to use hpool have to increase its refcount at first. Use rcu_read_lock() and synchronize_rcu() to guarantee all such users failed to get hpool before freeing hpool.
Fixes: 0bc0d0d57eda ("dhugetlb: backport dynamic hugetlb feature") Signed-off-by: Liu Shixin liushixin2@huawei.com --- mm/hugetlb.c | 6 ++++++ mm/memcontrol.c | 11 ++++++++--- 2 files changed, 14 insertions(+), 3 deletions(-)
diff --git a/mm/hugetlb.c b/mm/hugetlb.c index 4be708677ce6..18dd5bcd13a3 100644 --- a/mm/hugetlb.c +++ b/mm/hugetlb.c @@ -3360,6 +3360,7 @@ void dhugetlb_pool_put(struct dhugetlb_pool *hpool)
if (atomic_dec_and_test(&hpool->refcnt)) { css_put(&hpool->attach_memcg->css); + synchronize_rcu(); kfree(hpool); } } @@ -3500,9 +3501,14 @@ struct dhugetlb_pool *get_dhugetlb_pool_from_task(struct task_struct *tsk)
rcu_read_lock(); memcg = mem_cgroup_from_task(tsk); + if (!memcg || !css_tryget(&memcg->css)) { + rcu_read_unlock(); + return NULL; + } rcu_read_unlock();
hpool = get_dhugetlb_pool_from_memcg(memcg); + css_put(&memcg->css);
return hpool; } diff --git a/mm/memcontrol.c b/mm/memcontrol.c index 7dc68b1792ef..4ecb6f09b68b 100644 --- a/mm/memcontrol.c +++ b/mm/memcontrol.c @@ -4701,14 +4701,19 @@ static ssize_t memcg_write_event_control(struct kernfs_open_file *of, struct dhugetlb_pool *get_dhugetlb_pool_from_memcg(struct mem_cgroup *memcg) { struct mem_cgroup_extension *memcg_ext; + struct dhugetlb_pool *hpool;
if (!memcg) return NULL;
+ rcu_read_lock(); memcg_ext = container_of(memcg, struct mem_cgroup_extension, memcg); - if (dhugetlb_pool_get(memcg_ext->hpool)) - return memcg_ext->hpool; - return NULL; + hpool = memcg_ext->hpool; + if (!dhugetlb_pool_get(hpool)) + hpool = NULL; + rcu_read_unlock(); + + return hpool; }
static void set_dhugetlb_pool_to_memcg(struct mem_cgroup *memcg,
反馈: 您发送到kernel@openeuler.org的补丁/补丁集,已成功转换为PR! PR链接地址: https://gitee.com/openeuler/kernel/pulls/9086 邮件列表地址:https://mailweb.openeuler.org/hyperkitty/list/kernel@openeuler.org/message/H...
FeedBack: The patch(es) which you have sent to kernel@openeuler.org mailing list has been converted to a pull request successfully! Pull request link: https://gitee.com/openeuler/kernel/pulls/9086 Mailing list address: https://mailweb.openeuler.org/hyperkitty/list/kernel@openeuler.org/message/H...