Received: by 2002:a05:6a10:6d10:0:0:0:0 with SMTP id gq16csp3366513pxb; Tue, 19 Apr 2022 00:23:03 -0700 (PDT) X-Google-Smtp-Source: ABdhPJzt7rxIXbu46ovyE6GLkscuxEVn9Kd9nyfjf/tA0tYkCtdyyZZKHBURL2jOreHCwQRgUVik X-Received: by 2002:a17:906:6a16:b0:6e8:a89c:6bb8 with SMTP id qw22-20020a1709066a1600b006e8a89c6bb8mr12198342ejc.476.1650352982921; Tue, 19 Apr 2022 00:23:02 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1650352982; cv=none; d=google.com; s=arc-20160816; b=hcMVJrMkZR8yHeX5qx3DOjbNgUKUKXNI4Tes8LlhuuAE4KGVTB9MBTPqrbjuSBwkRE K7ooV1l+dEJhmMbvb3mCyEnrBeV/FCN13wtPcorcvSnx82dFDSoTYg0g6JI9QSyedOWP zzzZK6R2YInyJX398UtNA8MlOEtq6SHTCs4PebwGcgDgPkUaCLHTU+MEYn6lkJyWqOW/ fw2Ur7OhooAoXOZ1HAeBga2kfERApu7FK13Ns7WIeCJgFKev+tju6AxenVZLB7hUXy7n AJMqFx1ilRSoNVn1ywwCcux1HVhy1s/SXlJ4FLiMiAIDaIcVmFzitZJN/t/8BG39IwU2 JS8Q== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=rmC0WaKC618bkp+nF8UzzCvQKr4PaMdW0TGCuwwc4EI=; b=NAu6m1fi0m+cV4uYD5qojk72YNZa/6bj15DYzjraw6v7NKpnHCZs0FZwGAXnaZGuFW I9dMrCT+EV1KKRWrx+9RKH33cTc4INBeYu1tKCG5a/tOHI+Kioa2XPE3wmcL0RGOZjJz GvRa0tVCQ23VaXxg6Rxr4I2UxU0Ed7MjPOjobZtlcIrFhemTlGu4/s5rTtxUesefGl0s cGsLH6DYw7Q92uV2t71fp8d5FpyamIt/ich0IC5fFhb1cWtfLiC/LM/2EKyqjwdmqrX7 eiYhoRxwsI8OdXryFES4XlaLltEZSfkz6iS/Mic3QCDbrL9Vy709pWckpVRaoaaJM0kx XV8Q== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=iKATwCC5; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Return-Path: Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id e11-20020a056402190b00b0041d850844f5si9984588edz.262.2022.04.19.00.22.39; Tue, 19 Apr 2022 00:23:02 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=iKATwCC5; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S245416AbiDROHU (ORCPT + 99 others); Mon, 18 Apr 2022 10:07:20 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:57504 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S244656AbiDRNuu (ORCPT ); Mon, 18 Apr 2022 09:50:50 -0400 Received: from ams.source.kernel.org (ams.source.kernel.org [145.40.68.75]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id F1257443F7; Mon, 18 Apr 2022 06:02:02 -0700 (PDT) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ams.source.kernel.org (Postfix) with ESMTPS id 7BD00B80EDC; Mon, 18 Apr 2022 13:02:01 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id D1577C385A1; Mon, 18 Apr 2022 13:01:59 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1650286920; bh=0c1wzjzdCckmhAYOoRg1y/jRpjgntM2jVZjWBC9E3BY=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=iKATwCC5x/Jp/gyIUKdMAG0nmwTp8CmWUGWCMqWMweg44z0dgldjP8ocpeaVRbhNI 6PTi2ttj66oDe7p/iaDl+aRRhtqgFooy1Ey4Ol7ltMaoQKBm5fOdPFRF6poHUwRDtz zxyKU3EMU6OO+kfB5yDbkO4w+ZGTG8NVoOw8rnf0= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org, stable@vger.kernel.org Cc: Greg Kroah-Hartman , "Eric W. Biederman" , Linus Torvalds , =?UTF-8?q?Michal=20Koutn=C3=BD?= , Oleg Nesterov , syzbot+50f5cf33a284ce738b62@syzkaller.appspotmail.com, Tejun Heo , Ovidiu Panait Subject: [PATCH 4.14 259/284] cgroup: Use open-time cgroup namespace for process migration perm checks Date: Mon, 18 Apr 2022 14:14:00 +0200 Message-Id: <20220418121219.855654899@linuxfoundation.org> X-Mailer: git-send-email 2.35.3 In-Reply-To: <20220418121210.689577360@linuxfoundation.org> References: <20220418121210.689577360@linuxfoundation.org> User-Agent: quilt/0.66 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-7.7 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_HI, SPF_HELO_NONE,SPF_PASS,T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Tejun Heo commit e57457641613fef0d147ede8bd6a3047df588b95 upstream. cgroup process migration permission checks are performed at write time as whether a given operation is allowed or not is dependent on the content of the write - the PID. This currently uses current's cgroup namespace which is a potential security weakness as it may allow scenarios where a less privileged process tricks a more privileged one into writing into a fd that it created. This patch makes cgroup remember the cgroup namespace at the time of open and uses it for migration permission checks instad of current's. Note that this only applies to cgroup2 as cgroup1 doesn't have namespace support. This also fixes a use-after-free bug on cgroupns reported in https://lore.kernel.org/r/00000000000048c15c05d0083397@google.com Note that backporting this fix also requires the preceding patch. Reported-by: "Eric W. Biederman" Suggested-by: Linus Torvalds Cc: Michal Koutný Cc: Oleg Nesterov Reviewed-by: Michal Koutný Reported-by: syzbot+50f5cf33a284ce738b62@syzkaller.appspotmail.com Link: https://lore.kernel.org/r/00000000000048c15c05d0083397@google.com Fixes: 5136f6365ce3 ("cgroup: implement "nsdelegate" mount option") Signed-off-by: Tejun Heo [mkoutny: v5.10: duplicate ns check in procs/threads write handler, adjust context] Signed-off-by: Michal Koutný Signed-off-by: Greg Kroah-Hartman [OP: backport to v4.14: drop changes to cgroup_attach_permissions() and cgroup_css_set_fork(), adjust cgroup_procs_write_permission() calls] Signed-off-by: Ovidiu Panait Signed-off-by: Greg Kroah-Hartman --- kernel/cgroup/cgroup-internal.h | 2 ++ kernel/cgroup/cgroup.c | 24 +++++++++++++++++------- 2 files changed, 19 insertions(+), 7 deletions(-) --- a/kernel/cgroup/cgroup-internal.h +++ b/kernel/cgroup/cgroup-internal.h @@ -11,6 +11,8 @@ struct cgroup_pidlist; struct cgroup_file_ctx { + struct cgroup_namespace *ns; + struct { void *trigger; } psi; --- a/kernel/cgroup/cgroup.c +++ b/kernel/cgroup/cgroup.c @@ -3370,14 +3370,19 @@ static int cgroup_file_open(struct kernf ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); if (!ctx) return -ENOMEM; + + ctx->ns = current->nsproxy->cgroup_ns; + get_cgroup_ns(ctx->ns); of->priv = ctx; if (!cft->open) return 0; ret = cft->open(of); - if (ret) + if (ret) { + put_cgroup_ns(ctx->ns); kfree(ctx); + } return ret; } @@ -3388,13 +3393,14 @@ static void cgroup_file_release(struct k if (cft->release) cft->release(of); + put_cgroup_ns(ctx->ns); kfree(ctx); } static ssize_t cgroup_file_write(struct kernfs_open_file *of, char *buf, size_t nbytes, loff_t off) { - struct cgroup_namespace *ns = current->nsproxy->cgroup_ns; + struct cgroup_file_ctx *ctx = of->priv; struct cgroup *cgrp = of->kn->parent->priv; struct cftype *cft = of->kn->priv; struct cgroup_subsys_state *css; @@ -3408,7 +3414,7 @@ static ssize_t cgroup_file_write(struct */ if ((cgrp->root->flags & CGRP_ROOT_NS_DELEGATE) && !(cft->flags & CFTYPE_NS_DELEGATABLE) && - ns != &init_cgroup_ns && ns->root_cset->dfl_cgrp == cgrp) + ctx->ns != &init_cgroup_ns && ctx->ns->root_cset->dfl_cgrp == cgrp) return -EPERM; if (cft->write) @@ -4351,9 +4357,9 @@ static int cgroup_procs_show(struct seq_ static int cgroup_procs_write_permission(struct cgroup *src_cgrp, struct cgroup *dst_cgrp, - struct super_block *sb) + struct super_block *sb, + struct cgroup_namespace *ns) { - struct cgroup_namespace *ns = current->nsproxy->cgroup_ns; struct cgroup *com_cgrp = src_cgrp; struct inode *inode; int ret; @@ -4389,6 +4395,7 @@ static int cgroup_procs_write_permission static ssize_t cgroup_procs_write(struct kernfs_open_file *of, char *buf, size_t nbytes, loff_t off) { + struct cgroup_file_ctx *ctx = of->priv; struct cgroup *src_cgrp, *dst_cgrp; struct task_struct *task; const struct cred *saved_cred; @@ -4415,7 +4422,8 @@ static ssize_t cgroup_procs_write(struct */ saved_cred = override_creds(of->file->f_cred); ret = cgroup_procs_write_permission(src_cgrp, dst_cgrp, - of->file->f_path.dentry->d_sb); + of->file->f_path.dentry->d_sb, + ctx->ns); revert_creds(saved_cred); if (ret) goto out_finish; @@ -4438,6 +4446,7 @@ static void *cgroup_threads_start(struct static ssize_t cgroup_threads_write(struct kernfs_open_file *of, char *buf, size_t nbytes, loff_t off) { + struct cgroup_file_ctx *ctx = of->priv; struct cgroup *src_cgrp, *dst_cgrp; struct task_struct *task; const struct cred *saved_cred; @@ -4466,7 +4475,8 @@ static ssize_t cgroup_threads_write(stru */ saved_cred = override_creds(of->file->f_cred); ret = cgroup_procs_write_permission(src_cgrp, dst_cgrp, - of->file->f_path.dentry->d_sb); + of->file->f_path.dentry->d_sb, + ctx->ns); revert_creds(saved_cred); if (ret) goto out_finish;