From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail.openvz.org (mail.openvz.org [69.168.225.77]) by lore.virtuozzo.com (Postfix) with ESMTPS id 13B0081042 for ; Sun, 1 Nov 2026 23:53:39 +0000 (UTC) Received: from mail.openvz.org (localhost [127.0.0.1]) by mail.openvz.org (8.14.4/8.14.4) with ESMTP id 6A1NqSPW015290; Mon, 2 Nov 2026 02:52:28 +0300 DKIM-Filter: OpenDKIM Filter v2.11.0 mail.openvz.org 6A1NqSPW015290 Authentication-Results: mail.openvz.org; dkim=fail reason="signature verification failed" (2048-bit key) header.d=virtuozzo.com header.i=@virtuozzo.com header.b="W2FXrVX+" Received: from mail-wr1-f72.google.com (mail-wr1-f72.google.com [209.85.221.72]) by mail.openvz.org (8.14.4/8.14.4) with ESMTP id 6A1NqPMM015273 (version=TLSv1/SSLv3 cipher=AES128-GCM-SHA256 bits=128 verify=FAIL) for ; Mon, 2 Nov 2026 02:52:25 +0300 DKIM-Filter: OpenDKIM Filter v2.11.0 mail.openvz.org 6A1NqPMM015273 Received: by mail-wr1-f72.google.com with SMTP id ffacd0b85a97d-48e29c25101so1281807f8f.3 for ; Sun, 01 Nov 2026 15:52:25 -0800 (PST) X-Gm-Message-State: APuU4Z8ceVMWzjroOvxXcJK2fpk8u1B7JE+oaKfoej+QM2EETrKgmQRT Navn9JF1TfCaRdaGf8EzrzhJl6q0e5AiTA8L8hLM8WTSALzhhncAmLloJ1geviIPK1ohE1v2+Eb n2wk13ChpzxaGBqa+73ylq6Xq6fFTTglpHfRwkHPG2ZBErL2pr6rVRg== X-Gm-Gg: AYBFou0P/pGy8rJNChQJFOkgGNK/4ye7/Fk97zHh/EikGrj3G8P4ou1m1az7Z38DgoY 6MQBXjgnPQez/WZJug7HpW32LDkQrErjTz8T2dAw4qY8WpymnoX7NdcZ0coDZi2BAbYWaVlil6i kt37B0Y2Ufl/Q5EUdLtCsh/tew0/OVyAN352jX8lDKwuequ8AATOVrHL8UJoTB7jbCVIuHZsH1d BAlrk+v7nElj78OeQEl6OkqUeARKyewesRTepHqjmrP4P8KZfj1QNL8BXRq2zP4RQo+oTeJjxjD K5kT3ll7S4kT1VBGApXtrsFLJ1lbFBXdYtEg8rqWxyP+QL5wPXBknf6NY0qja8jf1kUXtENs7/U Lv1PVPJoLmbd/WugCbabr/VoMZkfE X-Received: by 2002:a05:6000:200b:b0:48e:5df2:fd24 with SMTP id ffacd0b85a97d-48e6e305bc0mr19683997f8f.32.1793577145340; Sun, 01 Nov 2026 15:52:25 -0800 (PST) X-Received: by 2002:a05:6000:200b:b0:48e:5df2:fd24 with SMTP id ffacd0b85a97d-48e6e305bc0mr19683977f8f.32.1793577144861; Sun, 01 Nov 2026 15:52:24 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1793577144; cv=none; d=google.com; s=arc-20260327; b=dTBakiG0TobQ4bWY0GX2JK8kG3nTci8dluosg9+58AlmN2IC4ak5OCdekskoE4MiZK e/rXu9HdDUv3XVOdc2+YOB47huiRTB2MTI02C8XMUS4O7Lbs3nF+b5X38wkVFotY1xu+ Xh9JW289DKcs0IU6arnvZ8zkLq/MeOaxG+5ra8pHE0kcaPIJk0G6dIP1+Q9pCCVFBGvA RpljViDmcfk6QLQQceNbgLhI0tugvP8TW3cDyAF9wI4wUgwQhs7LLGgAKk4yYRRq+s2Y 3Z5VGh20oFbiTSVJOKh5JkWxPCy7rZmAFTpLjWk6WsfnpMWdfUzU8Lhb15ekZg1YBU9h nFOA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20260327; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:dkim-signature; bh=A1vh26FaAozJkV7WH89zMQtOYabQ8639g0ue7kuA2yA=; fh=wpoNUURlquLpJK/14Kny0oMIYkY7mYwjJ/Ils9UT2kk=; b=qdw+Gp4ab9KtcttCHTtQDuXrL1583+Lf1X01oGXqWhvNoOEX5ZhUUiLmK83Xp3KUMz hGN+N4R2Sicbo5VRtARAilQ7j3RLJRsXyNWGjwj7GsZfC6mHmvv7kjDr0AoFhk/nOCc0 2YtdcDpbtB7+choRjjyRwGuv7uvwMOAAopVO8ZMDlhICB26CLAZAJWWiNFUk7jmDXZ21 Tr1wdf//GvNOYWUUev6Huum5AuPEGKhNQHNUb98mv+5yZneEcKsSOIIvSlFNIWJwFJVp 2rWzHGqyyK+LbduuJc3fNx9TCSse6C+w2YNkBhIT/a+wcezRL7QwPPvmfJ/hY7uZvf26 FI1g==; dara=google.com ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@virtuozzo.com header.s=relay header.b=W2FXrVX+; spf=pass (google.com: domain of mirian.shilakadze@virtuozzo.com designates 130.117.225.111 as permitted sender) smtp.mailfrom=mirian.shilakadze@virtuozzo.com; dmarc=pass (p=QUARANTINE sp=QUARANTINE dis=NONE) header.from=virtuozzo.com Received: from relay.virtuozzo.com (relay.virtuozzo.com. [130.117.225.111]) by mx.google.com with ESMTPS id ffacd0b85a97d-48e71bd1d3csi14640247f8f.422.2026.11.01.15.52.24 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 01 Nov 2026 15:52:24 -0800 (PST) Received-SPF: pass (google.com: domain of mirian.shilakadze@virtuozzo.com designates 130.117.225.111 as permitted sender) client-ip=130.117.225.111; Authentication-Results: mx.google.com; dkim=pass header.i=@virtuozzo.com header.s=relay header.b=W2FXrVX+; spf=pass (google.com: domain of mirian.shilakadze@virtuozzo.com designates 130.117.225.111 as permitted sender) smtp.mailfrom=mirian.shilakadze@virtuozzo.com; dmarc=pass (p=QUARANTINE sp=QUARANTINE dis=NONE) header.from=virtuozzo.com DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=virtuozzo.com; s=relay; h=MIME-Version:Message-ID:Date:Subject:From: Content-Type; bh=A1vh26FaAozJkV7WH89zMQtOYabQ8639g0ue7kuA2yA=; b=W2FXrVX+Ic9g 8BdE7sFQ3X9dpmqq/lYBgkOXZ0UuK3TVlnyadmw1HveyYfod3DXY8zEm9tLWJfqQjgc98BInkoCk4 UcCXSFGWSxzWIfVw1+nVtC/qVoeYFa/jJly/7HYjZtxF9Fi7G9go1nwElGH9yrXqG/Jwc42mlfi9w +UgvR0v4hsHLb5e+g1n1BXZupg/TAi210u5RuWqOPMUru2TjFy1l6yfwo+58HKsG8/g8YsO1eusI0 BqQpYcQ0kf9TtSBDAJfa2oW88Z9Bgi/EN7BDbcwJ9zWLeUTZTPt211WSNQ85Jj83NbCdVeqKpYK6j NCUIKX/XlTrB5NClf934eA==; Received: from ch-demo-asa.virtuozzo.com ([130.117.225.8] helo=localhost.localdomain) by relay.virtuozzo.com with esmtp (Exim 4.96) (envelope-from ) id 1xNfHj-004e5A-1m; Mon, 02 Nov 2026 00:52:17 +0100 From: Mirian Shilakadze To: khorenko@virtuozzo.com, ptikhomirov@virtuozzo.com Date: Mon, 2 Nov 2026 03:51:45 +0400 Message-ID: <20261101235155.124059-4-mirian.shilakadze@virtuozzo.com> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20261101235155.124059-1-mirian.shilakadze@virtuozzo.com> References: <20261101235155.124059-1-mirian.shilakadze@virtuozzo.com> MIME-Version: 1.0 X-OZ-Fwd: true Cc: devel@openvz.org Subject: [Devel] [PATCH hci-8.1 3/6] ms/cgroup/dmem: avoid pool UAF X-BeenThere: devel@openvz.org X-Mailman-Version: 2.1.12 Precedence: list List-Id: OpenVZ development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Sender: devel-bounces@openvz.org Errors-To: devel-bounces@openvz.org From: Chen Ridong 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: 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") Cc: stable@vger.kernel.org # v6.14+ Signed-off-by: Chen Ridong Signed-off-by: Tejun Heo (cherry picked from commit 99a2ef500906138ba58093b9893972a5c303c734) Rebase note: context only. This tree lacks upstream a214365140cc ("rculist: move list_for_each_rcu() to where it belongs"), so dmem.c does not include linux/rculist.h and the new linux/refcount.h include goes after linux/parser.h. The change is otherwise the same. https://virtuozzo.atlassian.net/browse/VSTOR-152813 Signed-off-by: Mirian Shilakadze --- 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 d71092d2b6ed..c8cfa5f3bd43 100644 --- a/kernel/cgroup/dmem.c +++ b/kernel/cgroup/dmem.c @@ -14,6 +14,7 @@ #include #include #include +#include #include struct dmem_cgroup_region { @@ -70,7 +71,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; }; @@ -87,6 +90,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) { @@ -103,10 +109,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 @@ -341,6 +375,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(®ion->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, ®ion->pools); @@ -388,6 +428,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; @@ -434,6 +478,8 @@ void dmem_cgroup_unregister_region(struct dmem_cgroup_region *region) list_for_each_entry_safe(pool, next, ®ion->pools, region_node) { list_del_rcu(&pool->css_node); + list_del(&pool->region_node); + dmemcg_pool_put(pool); } /* @@ -514,8 +560,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); @@ -529,6 +577,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) { @@ -537,6 +587,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)) { @@ -572,6 +624,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); @@ -623,7 +676,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; } @@ -718,6 +773,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(®ion->ref, dmemcg_free_region); -- 2.43.0 _______________________________________________ Devel mailing list Devel@openvz.org https://lists.openvz.org/mailman/listinfo/devel