public inbox for cgroups@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH -next 0/3] cgroup/dmem: bugfixes
@ 2026-01-31  9:11 Chen Ridong
  2026-01-31  9:12 ` [PATCH -next 1/3] cgroup/dmem: fix NULL pointer dereference when setting max Chen Ridong
                   ` (3 more replies)
  0 siblings, 4 replies; 7+ messages in thread
From: Chen Ridong @ 2026-01-31  9:11 UTC (permalink / raw)
  To: dev, mripard, natalie.vock, tj, hannes, mkoutny
  Cc: cgroups, dri-devel, linux-kernel, lujialin4, chenridong

From: Chen Ridong <chenridong@huawei.com>

This series fix three bugs.

Chen Ridong (3):
  cgroup/dmem: fix NULL pointer dereference when setting max
  cgroup/dmem: avoid rcu warning when unregister region
  cgroup/dmem: avoid pool UAF

 kernel/cgroup/dmem.c | 72 +++++++++++++++++++++++++++++++++++++++-----
 1 file changed, 65 insertions(+), 7 deletions(-)

-- 
2.34.1


^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH -next 1/3] cgroup/dmem: fix NULL pointer dereference when setting max
  2026-01-31  9:11 [PATCH -next 0/3] cgroup/dmem: bugfixes Chen Ridong
@ 2026-01-31  9:12 ` Chen Ridong
  2026-01-31 17:26   ` kernel test robot
  2026-01-31  9:12 ` [PATCH -next 2/3] cgroup/dmem: avoid rcu warning when unregister region Chen Ridong
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 7+ messages in thread
From: Chen Ridong @ 2026-01-31  9:12 UTC (permalink / raw)
  To: dev, mripard, natalie.vock, tj, hannes, mkoutny
  Cc: cgroups, dri-devel, linux-kernel, lujialin4, chenridong

From: Chen Ridong <chenridong@huawei.com>

An issue was triggered:

 BUG: kernel NULL pointer dereference, address: 0000000000000000
 #PF: supervisor read access in kernel mode
 #PF: error_code(0x0000) - not-present page
 PGD 0 P4D 0
 Oops: Oops: 0000 [#1] SMP NOPTI
 CPU: 15 UID: 0 PID: 658 Comm: bash Tainted: 6.19.0-rc6-next-2026012
 Tainted: [O]=OOT_MODULE
 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996),
 RIP: 0010:strcmp+0x10/0x30
 RSP: 0018:ffffc900017f7dc0 EFLAGS: 00000246
 RAX: 0000000000000000 RBX: 0000000000000000 RCX: ffff888107cd4358
 RDX: 0000000019f73907 RSI: ffffffff82cc381a RDI: 0000000000000000
 RBP: ffff8881016bef0d R08: 000000006c0e7145 R09: 0000000056c0e714
 R10: 0000000000000001 R11: ffff888107cd4358 R12: 0007ffffffffffff
 R13: ffff888101399200 R14: ffff888100fcb360 R15: 0007ffffffffffff
 CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
 CR2: 0000000000000000 CR3: 0000000105c79000 CR4: 00000000000006f0
 Call Trace:
  <TASK>
  dmemcg_limit_write.constprop.0+0x16d/0x390
  ? __pfx_set_resource_max+0x10/0x10
  kernfs_fop_write_iter+0x14e/0x200
  vfs_write+0x367/0x510
  ksys_write+0x66/0xe0
  do_syscall_64+0x6b/0x390
  entry_SYSCALL_64_after_hwframe+0x76/0x7e
 RIP: 0033:0x7f42697e1887

It was trriggered setting max without limitation, the command is like:
"echo test/region0 > dmem.max". To fix this issue, add check whether
options is valid after parsing the region_name.

Fixes: b168ed458dde ("kernel/cgroup: Add "dmem" memory accounting cgroup")
Signed-off-by: Chen Ridong <chenridong@huawei.com>
---
 kernel/cgroup/dmem.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/kernel/cgroup/dmem.c b/kernel/cgroup/dmem.c
index e12b946278b6..30f96627860c 100644
--- a/kernel/cgroup/dmem.c
+++ b/kernel/cgroup/dmem.c
@@ -700,6 +700,11 @@ static ssize_t dmemcg_limit_write(struct kernfs_open_file *of,
 		if (!region_name[0])
 			continue;
 
+		if (!options || !*options) {
+			err = -EINVAL;
+			goto out_put;
+		}
+
 		rcu_read_lock();
 		region = dmemcg_get_region_by_name(region_name);
 		rcu_read_unlock();
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH -next 2/3] cgroup/dmem: avoid rcu warning when unregister region
  2026-01-31  9:11 [PATCH -next 0/3] cgroup/dmem: bugfixes Chen Ridong
  2026-01-31  9:12 ` [PATCH -next 1/3] cgroup/dmem: fix NULL pointer dereference when setting max Chen Ridong
@ 2026-01-31  9:12 ` Chen Ridong
  2026-01-31  9:12 ` [PATCH -next 3/3] cgroup/dmem: avoid pool UAF Chen Ridong
  2026-02-01 16:36 ` [PATCH -next 0/3] cgroup/dmem: bugfixes Tejun Heo
  3 siblings, 0 replies; 7+ messages in thread
From: Chen Ridong @ 2026-01-31  9:12 UTC (permalink / raw)
  To: dev, mripard, natalie.vock, tj, hannes, mkoutny
  Cc: cgroups, dri-devel, linux-kernel, lujialin4, chenridong

From: Chen Ridong <chenridong@huawei.com>

A warnning was detected:

 WARNING: suspicious RCU usage
 6.19.0-rc7-next-20260129+ #1101 Tainted: G           O
 kernel/cgroup/dmem.c:456 suspicious rcu_dereference_check() usage!

 other info that might help us debug this:

 rcu_scheduler_active = 2, debug_locks = 1
 1 lock held by insmod/532:
  #0: ffffffff85e78b38 (dmemcg_lock){+.+.}-dmem_cgroup_unregister_region+

 stack backtrace:
 CPU: 2 UID: 0 PID: 532 Comm: insmod Tainted: 6.19.0-rc7-next-
 Tainted: [O]=OOT_MODULE
 Call Trace:
  <TASK>
  dump_stack_lvl+0xb0/0xd0
  lockdep_rcu_suspicious+0x151/0x1c0
  dmem_cgroup_unregister_region+0x1e2/0x380
  ? __pfx_dmem_test_init+0x10/0x10 [dmem_uaf]
  dmem_test_init+0x65/0xff0 [dmem_uaf]
  do_one_initcall+0xbb/0x3a0

The macro list_for_each_rcu() must be used within an RCU read-side critical
section (between rcu_read_lock() and rcu_read_unlock()). Using it outside
that context, as seen in dmem_cgroup_unregister_region(), triggers the
lockdep warning because the RCU protection is not guaranteed.

Replace list_for_each_rcu() with list_for_each_entry_safe(), which is
appropriate for traversal under spinlock protection where nodes may be
deleted.

Fixes: b168ed458dde ("kernel/cgroup: Add "dmem" memory accounting cgroup")
Signed-off-by: Chen Ridong <chenridong@huawei.com>
---
 kernel/cgroup/dmem.c | 7 ++-----
 1 file changed, 2 insertions(+), 5 deletions(-)

diff --git a/kernel/cgroup/dmem.c b/kernel/cgroup/dmem.c
index 30f96627860c..b17f48bdef81 100644
--- a/kernel/cgroup/dmem.c
+++ b/kernel/cgroup/dmem.c
@@ -423,7 +423,7 @@ static void dmemcg_free_region(struct kref *ref)
  */
 void dmem_cgroup_unregister_region(struct dmem_cgroup_region *region)
 {
-	struct list_head *entry;
+	struct dmem_cgroup_pool_state *pool, *next;
 
 	if (!region)
 		return;
@@ -433,10 +433,7 @@ void dmem_cgroup_unregister_region(struct dmem_cgroup_region *region)
 	/* Remove from global region list */
 	list_del_rcu(&region->region_node);
 
-	list_for_each_rcu(entry, &region->pools) {
-		struct dmem_cgroup_pool_state *pool =
-			container_of(entry, typeof(*pool), region_node);
-
+	list_for_each_entry_safe(pool, next, &region->pools, region_node) {
 		list_del_rcu(&pool->css_node);
 	}
 
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH -next 3/3] cgroup/dmem: avoid pool UAF
  2026-01-31  9:11 [PATCH -next 0/3] cgroup/dmem: bugfixes Chen Ridong
  2026-01-31  9:12 ` [PATCH -next 1/3] cgroup/dmem: fix NULL pointer dereference when setting max Chen Ridong
  2026-01-31  9:12 ` [PATCH -next 2/3] cgroup/dmem: avoid rcu warning when unregister region Chen Ridong
@ 2026-01-31  9:12 ` Chen Ridong
  2026-02-01 16:36 ` [PATCH -next 0/3] cgroup/dmem: bugfixes Tejun Heo
  3 siblings, 0 replies; 7+ messages in thread
From: Chen Ridong @ 2026-01-31  9:12 UTC (permalink / raw)
  To: dev, mripard, natalie.vock, tj, hannes, mkoutny
  Cc: cgroups, dri-devel, linux-kernel, lujialin4, chenridong

From: Chen Ridong <chenridong@huawei.com>

An UAF issue was observed:

BUG: KASAN: slab-use-after-free in page_counter_uncharge+0x65/0x150
Write of size 8 at addr ffff888106715440 by task insmod/527

CPU: 4 UID: 0 PID: 527 Comm: insmod    6.19.0-rc7-next-20260129+ #11
Tainted: [O]=OOT_MODULE
Call Trace:
<TASK>
dump_stack_lvl+0x82/0xd0
kasan_report+0xca/0x100
kasan_check_range+0x39/0x1c0
page_counter_uncharge+0x65/0x150
dmem_cgroup_uncharge+0x1f/0x260

Allocated by task 527:

Freed by task 0:

The buggy address belongs to the object at ffff888106715400
which belongs to the cache kmalloc-512 of size 512
The buggy address is located 64 bytes inside of
freed 512-byte region [ffff888106715400, ffff888106715600)

The buggy address belongs to the physical page:

Memory state around the buggy address:
ffff888106715300: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
ffff888106715380: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
>ffff888106715400: fa fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
				     ^
ffff888106715480: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
ffff888106715500: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb

The issue occurs because a pool can still be held by a caller after its
associated memory region is unregistered. The current implementation frees
the pool even if users still hold references to it (e.g., before uncharge
operations complete).

This patch adds a reference counter to each pool, ensuring that a pool is
only freed when its reference count drops to zero.

Fixes: b168ed458dde ("kernel/cgroup: Add "dmem" memory accounting cgroup")
Signed-off-by: Chen Ridong <chenridong@huawei.com>
---
 kernel/cgroup/dmem.c | 60 ++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 58 insertions(+), 2 deletions(-)

diff --git a/kernel/cgroup/dmem.c b/kernel/cgroup/dmem.c
index b17f48bdef81..7fc13e4dce72 100644
--- a/kernel/cgroup/dmem.c
+++ b/kernel/cgroup/dmem.c
@@ -14,6 +14,7 @@
 #include <linux/mutex.h>
 #include <linux/page_counter.h>
 #include <linux/parser.h>
+#include <linux/refcount.h>
 #include <linux/rculist.h>
 #include <linux/slab.h>
 
@@ -71,7 +72,9 @@ struct dmem_cgroup_pool_state {
 	struct rcu_head rcu;
 
 	struct page_counter cnt;
+	struct dmem_cgroup_pool_state *parent;
 
+	refcount_t ref;
 	bool inited;
 };
 
@@ -88,6 +91,9 @@ struct dmem_cgroup_pool_state {
 static DEFINE_SPINLOCK(dmemcg_lock);
 static LIST_HEAD(dmem_cgroup_regions);
 
+static void dmemcg_free_region(struct kref *ref);
+static void dmemcg_pool_free_rcu(struct rcu_head *rcu);
+
 static inline struct dmemcg_state *
 css_to_dmemcs(struct cgroup_subsys_state *css)
 {
@@ -104,10 +110,38 @@ static struct dmemcg_state *parent_dmemcs(struct dmemcg_state *cg)
 	return cg->css.parent ? css_to_dmemcs(cg->css.parent) : NULL;
 }
 
+static void dmemcg_pool_get(struct dmem_cgroup_pool_state *pool)
+{
+	refcount_inc(&pool->ref);
+}
+
+static bool dmemcg_pool_tryget(struct dmem_cgroup_pool_state *pool)
+{
+	return refcount_inc_not_zero(&pool->ref);
+}
+
+static void dmemcg_pool_put(struct dmem_cgroup_pool_state *pool)
+{
+	if (!refcount_dec_and_test(&pool->ref))
+		return;
+
+	call_rcu(&pool->rcu, dmemcg_pool_free_rcu);
+}
+
+static void dmemcg_pool_free_rcu(struct rcu_head *rcu)
+{
+	struct dmem_cgroup_pool_state *pool = container_of(rcu, typeof(*pool), rcu);
+
+	if (pool->parent)
+		dmemcg_pool_put(pool->parent);
+	kref_put(&pool->region->ref, dmemcg_free_region);
+	kfree(pool);
+}
+
 static void free_cg_pool(struct dmem_cgroup_pool_state *pool)
 {
 	list_del(&pool->region_node);
-	kfree(pool);
+	dmemcg_pool_put(pool);
 }
 
 static void
@@ -342,6 +376,12 @@ alloc_pool_single(struct dmemcg_state *dmemcs, struct dmem_cgroup_region *region
 	page_counter_init(&pool->cnt,
 			  ppool ? &ppool->cnt : NULL, true);
 	reset_all_resource_limits(pool);
+	refcount_set(&pool->ref, 1);
+	kref_get(&region->ref);
+	if (ppool && !pool->parent) {
+		pool->parent = ppool;
+		dmemcg_pool_get(ppool);
+	}
 
 	list_add_tail_rcu(&pool->css_node, &dmemcs->pools);
 	list_add_tail(&pool->region_node, &region->pools);
@@ -389,6 +429,10 @@ get_cg_pool_locked(struct dmemcg_state *dmemcs, struct dmem_cgroup_region *regio
 
 		/* Fix up parent links, mark as inited. */
 		pool->cnt.parent = &ppool->cnt;
+		if (ppool && !pool->parent) {
+			pool->parent = ppool;
+			dmemcg_pool_get(ppool);
+		}
 		pool->inited = true;
 
 		pool = ppool;
@@ -435,6 +479,8 @@ void dmem_cgroup_unregister_region(struct dmem_cgroup_region *region)
 
 	list_for_each_entry_safe(pool, next, &region->pools, region_node) {
 		list_del_rcu(&pool->css_node);
+		list_del(&pool->region_node);
+		dmemcg_pool_put(pool);
 	}
 
 	/*
@@ -515,8 +561,10 @@ static struct dmem_cgroup_region *dmemcg_get_region_by_name(const char *name)
  */
 void dmem_cgroup_pool_state_put(struct dmem_cgroup_pool_state *pool)
 {
-	if (pool)
+	if (pool) {
 		css_put(&pool->cs->css);
+		dmemcg_pool_put(pool);
+	}
 }
 EXPORT_SYMBOL_GPL(dmem_cgroup_pool_state_put);
 
@@ -530,6 +578,8 @@ get_cg_pool_unlocked(struct dmemcg_state *cg, struct dmem_cgroup_region *region)
 	pool = find_cg_pool_locked(cg, region);
 	if (pool && !READ_ONCE(pool->inited))
 		pool = NULL;
+	if (pool && !dmemcg_pool_tryget(pool))
+		pool = NULL;
 	rcu_read_unlock();
 
 	while (!pool) {
@@ -538,6 +588,8 @@ get_cg_pool_unlocked(struct dmemcg_state *cg, struct dmem_cgroup_region *region)
 			pool = get_cg_pool_locked(cg, region, &allocpool);
 		else
 			pool = ERR_PTR(-ENODEV);
+		if (!IS_ERR(pool))
+			dmemcg_pool_get(pool);
 		spin_unlock(&dmemcg_lock);
 
 		if (pool == ERR_PTR(-ENOMEM)) {
@@ -573,6 +625,7 @@ void dmem_cgroup_uncharge(struct dmem_cgroup_pool_state *pool, u64 size)
 
 	page_counter_uncharge(&pool->cnt, size);
 	css_put(&pool->cs->css);
+	dmemcg_pool_put(pool);
 }
 EXPORT_SYMBOL_GPL(dmem_cgroup_uncharge);
 
@@ -624,7 +677,9 @@ int dmem_cgroup_try_charge(struct dmem_cgroup_region *region, u64 size,
 		if (ret_limit_pool) {
 			*ret_limit_pool = container_of(fail, struct dmem_cgroup_pool_state, cnt);
 			css_get(&(*ret_limit_pool)->cs->css);
+			dmemcg_pool_get(*ret_limit_pool);
 		}
+		dmemcg_pool_put(pool);
 		ret = -EAGAIN;
 		goto err;
 	}
@@ -721,6 +776,7 @@ static ssize_t dmemcg_limit_write(struct kernfs_open_file *of,
 
 		/* And commit */
 		apply(pool, new_limit);
+		dmemcg_pool_put(pool);
 
 out_put:
 		kref_put(&region->ref, dmemcg_free_region);
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* Re: [PATCH -next 1/3] cgroup/dmem: fix NULL pointer dereference when setting max
  2026-01-31  9:12 ` [PATCH -next 1/3] cgroup/dmem: fix NULL pointer dereference when setting max Chen Ridong
@ 2026-01-31 17:26   ` kernel test robot
  2026-02-02  0:50     ` Chen Ridong
  0 siblings, 1 reply; 7+ messages in thread
From: kernel test robot @ 2026-01-31 17:26 UTC (permalink / raw)
  To: Chen Ridong, dev, mripard, natalie.vock, tj, hannes, mkoutny
  Cc: oe-kbuild-all, cgroups, dri-devel, linux-kernel, lujialin4,
	chenridong

Hi Chen,

kernel test robot noticed the following build warnings:

[auto build test WARNING on next-20260130]

url:    https://github.com/intel-lab-lkp/linux/commits/Chen-Ridong/cgroup-dmem-fix-NULL-pointer-dereference-when-setting-max/20260131-173002
base:   next-20260130
patch link:    https://lore.kernel.org/r/20260131091202.344788-2-chenridong%40huaweicloud.com
patch subject: [PATCH -next 1/3] cgroup/dmem: fix NULL pointer dereference when setting max
config: x86_64-randconfig-161-20260131 (https://download.01.org/0day-ci/archive/20260201/202602010100.5CjcoPFh-lkp@intel.com/config)
compiler: clang version 20.1.8 (https://github.com/llvm/llvm-project 87f0227cb60147a26a1eeb4fb06e3b505e9c7261)
smatch version: v0.5.0-8994-gd50c5a4c
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20260201/202602010100.5CjcoPFh-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202602010100.5CjcoPFh-lkp@intel.com/

All warnings (new ones prefixed by >>):

>> kernel/cgroup/dmem.c:703:7: warning: variable 'region' is used uninitialized whenever 'if' condition is true [-Wsometimes-uninitialized]
     703 |                 if (!options || !*options) {
         |                     ^~~~~~~~~~~~~~~~~~~~~
   kernel/cgroup/dmem.c:729:13: note: uninitialized use occurs here
     729 |                 kref_put(&region->ref, dmemcg_free_region);
         |                           ^~~~~~
   kernel/cgroup/dmem.c:703:3: note: remove the 'if' if its condition is always false
     703 |                 if (!options || !*options) {
         |                 ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
     704 |                         err = -EINVAL;
         |                         ~~~~~~~~~~~~~~
     705 |                         goto out_put;
         |                         ~~~~~~~~~~~~~
     706 |                 }
         |                 ~
>> kernel/cgroup/dmem.c:703:7: warning: variable 'region' is used uninitialized whenever '||' condition is true [-Wsometimes-uninitialized]
     703 |                 if (!options || !*options) {
         |                     ^~~~~~~~
   kernel/cgroup/dmem.c:729:13: note: uninitialized use occurs here
     729 |                 kref_put(&region->ref, dmemcg_free_region);
         |                           ^~~~~~
   kernel/cgroup/dmem.c:703:7: note: remove the '||' if its condition is always false
     703 |                 if (!options || !*options) {
         |                     ^~~~~~~~~~~
   kernel/cgroup/dmem.c:685:36: note: initialize the variable 'region' to silence this warning
     685 |                 struct dmem_cgroup_region *region;
         |                                                  ^
         |                                                   = NULL
   2 warnings generated.


vim +703 kernel/cgroup/dmem.c

   674	
   675	static ssize_t dmemcg_limit_write(struct kernfs_open_file *of,
   676					 char *buf, size_t nbytes, loff_t off,
   677					 void (*apply)(struct dmem_cgroup_pool_state *, u64))
   678	{
   679		struct dmemcg_state *dmemcs = css_to_dmemcs(of_css(of));
   680		int err = 0;
   681	
   682		while (buf && !err) {
   683			struct dmem_cgroup_pool_state *pool = NULL;
   684			char *options, *region_name;
   685			struct dmem_cgroup_region *region;
   686			u64 new_limit;
   687	
   688			options = buf;
   689			buf = strchr(buf, '\n');
   690			if (buf)
   691				*buf++ = '\0';
   692	
   693			options = strstrip(options);
   694	
   695			/* eat empty lines */
   696			if (!options[0])
   697				continue;
   698	
   699			region_name = strsep(&options, " \t");
   700			if (!region_name[0])
   701				continue;
   702	
 > 703			if (!options || !*options) {
   704				err = -EINVAL;
   705				goto out_put;
   706			}
   707	
   708			rcu_read_lock();
   709			region = dmemcg_get_region_by_name(region_name);
   710			rcu_read_unlock();
   711	
   712			if (!region)
   713				return -EINVAL;
   714	
   715			err = dmemcg_parse_limit(options, region, &new_limit);
   716			if (err < 0)
   717				goto out_put;
   718	
   719			pool = get_cg_pool_unlocked(dmemcs, region);
   720			if (IS_ERR(pool)) {
   721				err = PTR_ERR(pool);
   722				goto out_put;
   723			}
   724	
   725			/* And commit */
   726			apply(pool, new_limit);
   727	
   728	out_put:
   729			kref_put(&region->ref, dmemcg_free_region);
   730		}
   731	
   732	
   733		return err ?: nbytes;
   734	}
   735	

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH -next 0/3] cgroup/dmem: bugfixes
  2026-01-31  9:11 [PATCH -next 0/3] cgroup/dmem: bugfixes Chen Ridong
                   ` (2 preceding siblings ...)
  2026-01-31  9:12 ` [PATCH -next 3/3] cgroup/dmem: avoid pool UAF Chen Ridong
@ 2026-02-01 16:36 ` Tejun Heo
  3 siblings, 0 replies; 7+ messages in thread
From: Tejun Heo @ 2026-02-01 16:36 UTC (permalink / raw)
  To: Chen Ridong
  Cc: dev, mripard, natalie.vock, hannes, mkoutny, cgroups, dri-devel,
	linux-kernel, lujialin4

On Sat, Jan 31, 2026 at 09:11:59AM +0000, Chen Ridong wrote:
> From: Chen Ridong <chenridong@huawei.com>
> 
> This series fix three bugs.
> 
> Chen Ridong (3):
>   cgroup/dmem: fix NULL pointer dereference when setting max
>   cgroup/dmem: avoid rcu warning when unregister region
>   cgroup/dmem: avoid pool UAF

Other than the exit path problem flagged by the kernel test bot in the first
patch, the series look correct to me. Maarten, any inputs?

Thanks.

-- 
tejun

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH -next 1/3] cgroup/dmem: fix NULL pointer dereference when setting max
  2026-01-31 17:26   ` kernel test robot
@ 2026-02-02  0:50     ` Chen Ridong
  0 siblings, 0 replies; 7+ messages in thread
From: Chen Ridong @ 2026-02-02  0:50 UTC (permalink / raw)
  To: kernel test robot, dev, mripard, natalie.vock, tj, hannes,
	mkoutny
  Cc: oe-kbuild-all, cgroups, dri-devel, linux-kernel, lujialin4



On 2026/2/1 1:26, kernel test robot wrote:
> Hi Chen,
> 
> kernel test robot noticed the following build warnings:
> 
> [auto build test WARNING on next-20260130]
> 
> url:    https://github.com/intel-lab-lkp/linux/commits/Chen-Ridong/cgroup-dmem-fix-NULL-pointer-dereference-when-setting-max/20260131-173002
> base:   next-20260130
> patch link:    https://lore.kernel.org/r/20260131091202.344788-2-chenridong%40huaweicloud.com
> patch subject: [PATCH -next 1/3] cgroup/dmem: fix NULL pointer dereference when setting max
> config: x86_64-randconfig-161-20260131 (https://download.01.org/0day-ci/archive/20260201/202602010100.5CjcoPFh-lkp@intel.com/config)
> compiler: clang version 20.1.8 (https://github.com/llvm/llvm-project 87f0227cb60147a26a1eeb4fb06e3b505e9c7261)
> smatch version: v0.5.0-8994-gd50c5a4c
> reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20260201/202602010100.5CjcoPFh-lkp@intel.com/reproduce)
> 
> If you fix the issue in a separate patch/commit (i.e. not just a new version of
> the same patch/commit), kindly add following tags
> | Reported-by: kernel test robot <lkp@intel.com>
> | Closes: https://lore.kernel.org/oe-kbuild-all/202602010100.5CjcoPFh-lkp@intel.com/
> 
> All warnings (new ones prefixed by >>):
> 
>>> kernel/cgroup/dmem.c:703:7: warning: variable 'region' is used uninitialized whenever 'if' condition is true [-Wsometimes-uninitialized]
>      703 |                 if (!options || !*options) {
>          |                     ^~~~~~~~~~~~~~~~~~~~~
>    kernel/cgroup/dmem.c:729:13: note: uninitialized use occurs here
>      729 |                 kref_put(&region->ref, dmemcg_free_region);
>          |                           ^~~~~~
>    kernel/cgroup/dmem.c:703:3: note: remove the 'if' if its condition is always false
>      703 |                 if (!options || !*options) {
>          |                 ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
>      704 |                         err = -EINVAL;
>          |                         ~~~~~~~~~~~~~~
>      705 |                         goto out_put;
>          |                         ~~~~~~~~~~~~~
>      706 |                 }
>          |                 ~
>>> kernel/cgroup/dmem.c:703:7: warning: variable 'region' is used uninitialized whenever '||' condition is true [-Wsometimes-uninitialized]
>      703 |                 if (!options || !*options) {
>          |                     ^~~~~~~~
>    kernel/cgroup/dmem.c:729:13: note: uninitialized use occurs here
>      729 |                 kref_put(&region->ref, dmemcg_free_region);
>          |                           ^~~~~~
>    kernel/cgroup/dmem.c:703:7: note: remove the '||' if its condition is always false
>      703 |                 if (!options || !*options) {
>          |                     ^~~~~~~~~~~
>    kernel/cgroup/dmem.c:685:36: note: initialize the variable 'region' to silence this warning
>      685 |                 struct dmem_cgroup_region *region;
>          |                                                  ^
>          |                                                   = NULL
>    2 warnings generated.
> 
> 
> vim +703 kernel/cgroup/dmem.c
> 
>    674	
>    675	static ssize_t dmemcg_limit_write(struct kernfs_open_file *of,
>    676					 char *buf, size_t nbytes, loff_t off,
>    677					 void (*apply)(struct dmem_cgroup_pool_state *, u64))
>    678	{
>    679		struct dmemcg_state *dmemcs = css_to_dmemcs(of_css(of));
>    680		int err = 0;
>    681	
>    682		while (buf && !err) {
>    683			struct dmem_cgroup_pool_state *pool = NULL;
>    684			char *options, *region_name;
>    685			struct dmem_cgroup_region *region;
>    686			u64 new_limit;
>    687	
>    688			options = buf;
>    689			buf = strchr(buf, '\n');
>    690			if (buf)
>    691				*buf++ = '\0';
>    692	
>    693			options = strstrip(options);
>    694	
>    695			/* eat empty lines */
>    696			if (!options[0])
>    697				continue;
>    698	
>    699			region_name = strsep(&options, " \t");
>    700			if (!region_name[0])
>    701				continue;
>    702	
>  > 703			if (!options || !*options) {
>    704				err = -EINVAL;
>    705				goto out_put;
>    706			}
>    707	

Thanks.

I missed that region is uninitialized. It could just return -EINVAL.
I'll fix it in the next version. If anyone has other opinions, I would like to
update together.

>    708			rcu_read_lock();
>    709			region = dmemcg_get_region_by_name(region_name);
>    710			rcu_read_unlock();
>    711	
>    712			if (!region)
>    713				return -EINVAL;
>    714	
>    715			err = dmemcg_parse_limit(options, region, &new_limit);
>    716			if (err < 0)
>    717				goto out_put;
>    718	
>    719			pool = get_cg_pool_unlocked(dmemcs, region);
>    720			if (IS_ERR(pool)) {
>    721				err = PTR_ERR(pool);
>    722				goto out_put;
>    723			}
>    724	
>    725			/* And commit */
>    726			apply(pool, new_limit);
>    727	
>    728	out_put:
>    729			kref_put(&region->ref, dmemcg_free_region);
>    730		}
>    731	
>    732	
>    733		return err ?: nbytes;
>    734	}
>    735	
> 

-- 
Best regards,
Ridong


^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2026-02-02  0:50 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-01-31  9:11 [PATCH -next 0/3] cgroup/dmem: bugfixes Chen Ridong
2026-01-31  9:12 ` [PATCH -next 1/3] cgroup/dmem: fix NULL pointer dereference when setting max Chen Ridong
2026-01-31 17:26   ` kernel test robot
2026-02-02  0:50     ` Chen Ridong
2026-01-31  9:12 ` [PATCH -next 2/3] cgroup/dmem: avoid rcu warning when unregister region Chen Ridong
2026-01-31  9:12 ` [PATCH -next 3/3] cgroup/dmem: avoid pool UAF Chen Ridong
2026-02-01 16:36 ` [PATCH -next 0/3] cgroup/dmem: bugfixes Tejun Heo

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox