Commit c97d622a authored by Liu Shixin's avatar Liu Shixin
Browse files

mm/dynamic_pool: prevent task attach to another dpool

hulk inclusion
category: feature
bugzilla: https://gitee.com/openeuler/kernel/issues/I8S9BY


CVE: NA

--------------------------------

The process in a memcg with dpool is not allowed to migrate to other memcg
with different dpool. Otherwise, the pages can not be guaranteed to be
freed.

Signed-off-by: default avatarLiu Shixin <liushixin2@huawei.com>
parent 78612d58
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -57,6 +57,8 @@ struct dynamic_pool {
	KABI_RESERVE(1)
};

int dynamic_pool_can_attach(struct task_struct *tsk, struct mem_cgroup *memcg);

void dynamic_pool_inherit(struct mem_cgroup *memcg);
int dynamic_pool_destroy(struct cgroup *cgrp, bool *clear_css_online);

@@ -70,6 +72,12 @@ int dynamic_pool_reserve_hugepage(struct mem_cgroup *memcg,
#else
struct dynamic_pool {};

static inline int dynamic_pool_can_attach(struct task_struct *tsk,
					  struct mem_cgroup *memcg)
{
	return 0;
}

static inline void dynamic_pool_inherit(struct mem_cgroup *memcg)
{
}
+46 −0
Original line number Diff line number Diff line
@@ -73,6 +73,28 @@ static struct dynamic_pool *dpool_get_from_memcg(struct mem_cgroup *memcg)
	return dpool;
}

static struct dynamic_pool *dpool_get_from_task(struct task_struct *tsk)
{
	struct dynamic_pool *dpool = NULL;
	struct mem_cgroup *memcg;

	if (!dpool_enabled)
		return NULL;

	rcu_read_lock();
	do {
		memcg = mem_cgroup_from_task(tsk);
	} while (memcg && !css_tryget(&memcg->css));
	rcu_read_unlock();
	if (!memcg)
		return NULL;

	dpool = dpool_get_from_memcg(memcg);
	css_put(&memcg->css);

	return dpool;
}

/* === demote and promote function ==================================== */

/*
@@ -346,6 +368,30 @@ static int dpool_promote_pool(struct dynamic_pool *dpool, int type)
	return ret;
}

/* === allocation interface =========================================== */

int dynamic_pool_can_attach(struct task_struct *tsk, struct mem_cgroup *memcg)
{
	struct dynamic_pool *src_dpool, *dst_dpool;
	int ret = 0;

	if (!dpool_enabled)
		return 0;

	src_dpool = dpool_get_from_task(tsk);
	if (!src_dpool)
		return 0;

	dst_dpool = dpool_get_from_memcg(memcg);
	if (dst_dpool != src_dpool)
		ret = -EPERM;

	dpool_put(src_dpool);
	dpool_put(dst_dpool);

	return ret;
}

/* === dynamic pool function ========================================== */

static void dpool_dump_child_memcg(struct mem_cgroup *memcg, void *message)
+4 −0
Original line number Diff line number Diff line
@@ -7239,6 +7239,10 @@ static int mem_cgroup_can_attach(struct cgroup_taskset *tset)
	if (!p)
		return 0;

	ret = dynamic_pool_can_attach(p, memcg);
	if (ret)
		return ret;

	/*
	 * We are now committed to this value whatever it is. Changes in this
	 * tunable will only affect upcoming migrations, not the current one.