From nobody Thu Sep 18 08:29:06 2025 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 73247C63703 for ; Thu, 8 Dec 2022 02:53:23 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229867AbiLHCxW (ORCPT ); Wed, 7 Dec 2022 21:53:22 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:42542 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229835AbiLHCxT (ORCPT ); Wed, 7 Dec 2022 21:53:19 -0500 Received: from mail-pl1-x629.google.com (mail-pl1-x629.google.com [IPv6:2607:f8b0:4864:20::629]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 9DA6C5BD55; Wed, 7 Dec 2022 18:53:17 -0800 (PST) Received: by mail-pl1-x629.google.com with SMTP id d3so228231plr.10; Wed, 07 Dec 2022 18:53:17 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=content-disposition:mime-version:message-id:subject:cc:to:from:date :sender:from:to:cc:subject:date:message-id:reply-to; bh=Tg8aD+lDH6Tv1G5iqzFowxNp9DpUbCk5WdkpP14KUyw=; b=bwaVRySVfZUnRb2bEPwJ5xCOaAbW2JOL2VzvtwPsxsOLsgpqhXcMxtBMO4VtjWsH7V MDQdVhBlbBUjWAU33uNkOOvxe6VkCUIQpal1m6VcrraOtDor8fGL9ie8cC1x1k9jxDpj czQSokKN+AFxHVJpY8Th5uLXRaS/kzWqoEfgdtR/nJOjRFicdSnYdhZ4WHoINWQqfB/R k05tFcdSkGfjgd0dvF+scgm7a1+iUyuh/FVGqvRGA392bZFPehNVJTITg5BaWJBBlLvm tIEKV5suDt1M2Sc9G4ukFt5sH7wc7eq/2lUB3Z18JNCWI+My330fDciGZKoERtGwNA5C HQVw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-disposition:mime-version:message-id:subject:cc:to:from:date :sender:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=Tg8aD+lDH6Tv1G5iqzFowxNp9DpUbCk5WdkpP14KUyw=; b=6LKQ6WRHjit+VvlRmohFvuan4UmIN3DNtmQPDPWG/N9GzebLs8sYYKZYcCVCkbtZjC TkiayfHHdwEhYvHjoneo9S0LHak4vHy7zeFdh9Cyy5c6xqvwhPW7LjBk7paset4b3xgk V9bMlcmA0wxC6KzEBTrFCYn+X3xKtPxaX3xQbbiLZ7lIla+mYjGnCOtGQoiTqHJ3ZRUF 0hl43YWqzOz5EWkSIgR11M3EHj2tNMLMGueBdMQMNx9pXmmbTiDGFe6HxypAKscJZiwO vjZSYgmIe7o42GeEicXX/hFg6aBDSSPlegECOP6osicqVPV/yU685FU+5rFroBmgaPR5 mZqQ== X-Gm-Message-State: ANoB5plIAgCtF7pVUUx27G5A0kAUTfVdlHRaYEnJnacj/9Jyp+2GIBtS l3P48d9sLXsVV3xnBCB+EHA= X-Google-Smtp-Source: AA0mqf6MHLTy6w/tpnXtPpaIlwt8HeZbJL0xdkJqzAciMkw8dRBGOvKbVId36jXJqjg26Wh9+SLmYQ== X-Received: by 2002:a17:90a:1f8c:b0:219:fcad:75be with SMTP id x12-20020a17090a1f8c00b00219fcad75bemr10669236pja.165.1670467996865; Wed, 07 Dec 2022 18:53:16 -0800 (PST) Received: from localhost (2603-800c-1a02-1bae-a7fa-157f-969a-4cde.res6.spectrum.com. [2603:800c:1a02:1bae:a7fa:157f:969a:4cde]) by smtp.gmail.com with ESMTPSA id o25-20020aa79799000000b005769b244c2fsm8692079pfp.40.2022.12.07.18.53.16 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 07 Dec 2022 18:53:16 -0800 (PST) Sender: Tejun Heo Date: Wed, 7 Dec 2022 16:53:15 -1000 From: Tejun Heo To: Andrew Morton Cc: linux-mm@kvack.org, linux-kernel@vger.kernel.org, Jann Horn , Linus Torvalds , Johannes Weiner , Michal Hocko , Roman Gushchin , Shakeel Butt , Muchun Song , cgroups@vger.kernel.org Subject: [PATCH for-6.1-fixes] memcg: Fix possible use-after-free in memcg_write_event_control() Message-ID: MIME-Version: 1.0 Content-Disposition: inline Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" memcg_write_event_control() accesses the dentry->d_name of the specified control fd to route the write call. As a cgroup interface file can't be renamed, it's safe to access d_name as long as the specified file is a regular cgroup file. Also, as these cgroup interface files can't be removed before the directory, it's safe to access the parent too. Prior to 347c4a874710 ("memcg: remove cgroup_event->cft"), there was a call to __file_cft() which verified that the specified file is a regular cgroupfs file before further accesses. The cftype pointer returned from __file_cft() was no longer necessary and the commit inadvertently dropped the file type check with it allowing any file to slip through. With the invarients broken, the d_name and parent accesses can now race against renames and removals of arbitrary files and cause use-after-free's. Fix the bug by resurrecting the file type check in __file_cft(). Now that cgroupfs is implemented through kernfs, checking the file operations needs to go through a layer of indirection. Instead, let's check the superblock and dentry type. Signed-off-by: Tejun Heo Fixes: 347c4a874710 ("memcg: remove cgroup_event->cft") Cc: stable@vger.kernel.org # v3.14+ Reported-by: Jann Horn Cc: Linus Torvalds Acked-by: Johannes Weiner Acked-by: Roman Gushchin --- include/linux/cgroup.h | 1 + kernel/cgroup/cgroup-internal.h | 1 - mm/memcontrol.c | 15 +++++++++++++-- 3 files changed, 14 insertions(+), 3 deletions(-) diff --git a/include/linux/cgroup.h b/include/linux/cgroup.h index 528bd44b59e2..2b7d077de7ef 100644 --- a/include/linux/cgroup.h +++ b/include/linux/cgroup.h @@ -68,6 +68,7 @@ struct css_task_iter { struct list_head iters_node; /* css_set->task_iters */ }; =20 +extern struct file_system_type cgroup_fs_type; extern struct cgroup_root cgrp_dfl_root; extern struct css_set init_css_set; =20 diff --git a/kernel/cgroup/cgroup-internal.h b/kernel/cgroup/cgroup-interna= l.h index fd4020835ec6..367b0a42ada9 100644 --- a/kernel/cgroup/cgroup-internal.h +++ b/kernel/cgroup/cgroup-internal.h @@ -167,7 +167,6 @@ struct cgroup_mgctx { extern spinlock_t css_set_lock; extern struct cgroup_subsys *cgroup_subsys[]; extern struct list_head cgroup_roots; -extern struct file_system_type cgroup_fs_type; =20 /* iterate across the hierarchies */ #define for_each_root(root) \ diff --git a/mm/memcontrol.c b/mm/memcontrol.c index a1a35c12635e..266a1ab05434 100644 --- a/mm/memcontrol.c +++ b/mm/memcontrol.c @@ -4832,6 +4832,7 @@ static ssize_t memcg_write_event_control(struct kernf= s_open_file *of, unsigned int efd, cfd; struct fd efile; struct fd cfile; + struct dentry *cdentry; const char *name; char *endp; int ret; @@ -4885,6 +4886,16 @@ static ssize_t memcg_write_event_control(struct kern= fs_open_file *of, if (ret < 0) goto out_put_cfile; =20 + /* + * The control file must be a regular cgroup1 file. As a regular cgroup + * file can't be renamed, it's safe to access its name afterwards. + */ + cdentry =3D cfile.file->f_path.dentry; + if (cdentry->d_sb->s_type !=3D &cgroup_fs_type || !d_is_reg(cdentry)) { + ret =3D -EINVAL; + goto out_put_cfile; + } + /* * Determine the event callbacks and set them in @event. This used * to be done via struct cftype but cgroup core no longer knows @@ -4893,7 +4904,7 @@ static ssize_t memcg_write_event_control(struct kernf= s_open_file *of, * * DO NOT ADD NEW FILES. */ - name =3D cfile.file->f_path.dentry->d_name.name; + name =3D cdentry->d_name.name; =20 if (!strcmp(name, "memory.usage_in_bytes")) { event->register_event =3D mem_cgroup_usage_register_event; @@ -4917,7 +4928,7 @@ static ssize_t memcg_write_event_control(struct kernf= s_open_file *of, * automatically removed on cgroup destruction but the removal is * asynchronous, so take an extra ref on @css. */ - cfile_css =3D css_tryget_online_from_dir(cfile.file->f_path.dentry->d_par= ent, + cfile_css =3D css_tryget_online_from_dir(cdentry->d_parent, &memory_cgrp_subsys); ret =3D -EINVAL; if (IS_ERR(cfile_css))