Received: by 2002:ac0:a594:0:0:0:0:0 with SMTP id m20-v6csp1438482imm; Wed, 23 May 2018 16:28:06 -0700 (PDT) X-Google-Smtp-Source: AB8JxZrvNHNSKWz46pU+jwHTklQHUPZ8obQhgl58pAzmJscj2OETsohP2sYOqvON45e48DlUwDm/ X-Received: by 2002:a62:e107:: with SMTP id q7-v6mr4725442pfh.226.1527118085962; Wed, 23 May 2018 16:28:05 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1527118085; cv=none; d=google.com; s=arc-20160816; b=pwBp3PTlgF86ng01HdMEu6rKrq1k24yVAm6tsSXp59ve9l+nMHtwTtmLoLuBqbHiAl q6vt1xKVZbV99QepjCeDZhWtFrTn4H4dCaF1iCE4gDCZLlQXYhXDGgAzEa1MxOCBWO2B Ub+TAYzCImEPyPtZMTl1QX95G8SgChDo/Nqy/4/GhXfBEywCBRVWGl7rW9B+XV+1biGP pbNo0sULH3BKDRPynHlQ97SA6a+YphnRWiQXGC/+MAf2OAYixoLiAqpmpduo7zdnWVvy EyafyYDo4a1cZbrwVl43RX66Fggww+GDnG+VGEf7zHxN54pfp/DuuDmD2UWSap0mm+wx sICg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:subject:references:in-reply-to:message-id :date:cc:to:from:arc-authentication-results; bh=XxmFnZNtO4NrVQ4gmTUrVviFoIfi6xII/7vHtTGkM/I=; b=ZHkrdkCmNRi6jPob7Xtjwi3gIoulHkgzBy4NqzoS/iB26mGloedJsJhw0MOfazQ2Fo NBQGAtn9civzymrqQy7mSXsGN9JlclWuf0zsgoVgX4ZlXshXoboquBUxzQY5+jQyoJAP cT3Zq49iaZ218O8k8yrC7Z0B/OBgT9kftuwriI+3wml1A+iThansNpC/FAfXGnkdHArI 4/NMdcpuvbOsHPNKaexvvxrhylmO3dvhrtdWZOuRMpzVJmnhp84ZGIpvaeHJqQNymfty PJq5s6hzHWtPEl6WNqPiWQz/byDKomxhj4o7E0j9c3OnYcdWb5wyW6eU6MwHYiG90cu0 gtZQ== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id w1-v6si15596206pgp.10.2018.05.23.16.27.50; Wed, 23 May 2018 16:28:05 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S935158AbeEWX0u (ORCPT + 99 others); Wed, 23 May 2018 19:26:50 -0400 Received: from out02.mta.xmission.com ([166.70.13.232]:40264 "EHLO out02.mta.xmission.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S934671AbeEWX0o (ORCPT ); Wed, 23 May 2018 19:26:44 -0400 Received: from in02.mta.xmission.com ([166.70.13.52]) by out02.mta.xmission.com with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.87) (envelope-from ) id 1fLd9Y-0006Kd-0d; Wed, 23 May 2018 17:26:44 -0600 Received: from [97.119.174.25] (helo=x220.int.ebiederm.org) by in02.mta.xmission.com with esmtpsa (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.87) (envelope-from ) id 1fLd9W-0004ID-VI; Wed, 23 May 2018 17:26:43 -0600 From: "Eric W. Biederman" To: Linux Containers Cc: linux-fsdevel@vger.kernel.org, Seth Forshee , "Serge E. Hallyn" , Christian Brauner , linux-kernel@vger.kernel.org, "Eric W. Biederman" Date: Wed, 23 May 2018 18:25:35 -0500 Message-Id: <20180523232538.4880-3-ebiederm@xmission.com> X-Mailer: git-send-email 2.14.1 In-Reply-To: <87o9h6554f.fsf@xmission.com> References: <87o9h6554f.fsf@xmission.com> X-XM-SPF: eid=1fLd9W-0004ID-VI;;;mid=<20180523232538.4880-3-ebiederm@xmission.com>;;;hst=in02.mta.xmission.com;;;ip=97.119.174.25;;;frm=ebiederm@xmission.com;;;spf=neutral X-XM-AID: U2FsdGVkX1+FRCWa5Jt02u8Bp5N774N27n63DhuhACc= X-SA-Exim-Connect-IP: 97.119.174.25 X-SA-Exim-Mail-From: ebiederm@xmission.com X-Spam-Checker-Version: SpamAssassin 3.4.1 (2015-04-28) on sa04.xmission.com X-Spam-Level: *** X-Spam-Status: No, score=3.6 required=8.0 tests=ALL_TRUSTED,BAYES_50, DCC_CHECK_NEGATIVE,TR_Symld_Words,XMNoVowels,XMSolicitRefs_0,XMSubLong autolearn=disabled version=3.4.1 X-Spam-Report: * -1.0 ALL_TRUSTED Passed through trusted hosts only via SMTP * 1.5 XMNoVowels Alpha-numberic number with no vowels * 0.7 XMSubLong Long Subject * 1.5 TR_Symld_Words too many words that have symbols inside * 0.8 BAYES_50 BODY: Bayes spam probability is 40 to 60% * [score: 0.5000] * -0.0 DCC_CHECK_NEGATIVE Not listed in DCC * [sa04 1397; Body=1 Fuz1=1 Fuz2=1] * 0.1 XMSolicitRefs_0 Weightloss drug X-Spam-DCC: XMission; sa04 1397; Body=1 Fuz1=1 Fuz2=1 X-Spam-Combo: ***;Linux Containers X-Spam-Relay-Country: X-Spam-Timing: total 438 ms - load_scoreonly_sql: 0.07 (0.0%), signal_user_changed: 3.8 (0.9%), b_tie_ro: 2.5 (0.6%), parse: 1.35 (0.3%), extract_message_metadata: 20 (4.6%), get_uri_detail_list: 3.7 (0.8%), tests_pri_-1000: 9 (2.0%), tests_pri_-950: 1.49 (0.3%), tests_pri_-900: 1.29 (0.3%), tests_pri_-400: 28 (6.5%), check_bayes: 27 (6.2%), b_tokenize: 11 (2.5%), b_tok_get_all: 8 (1.8%), b_comp_prob: 2.8 (0.6%), b_tok_touch_all: 3.2 (0.7%), b_finish: 0.74 (0.2%), tests_pri_0: 365 (83.3%), check_dkim_signature: 0.57 (0.1%), check_dkim_adsp: 4.0 (0.9%), tests_pri_500: 3.7 (0.8%), rewrite_mail: 0.00 (0.0%) Subject: [REVIEW][PATCH 3/6] fs: Allow superblock owner to replace invalid owners of inodes X-Spam-Flag: No X-SA-Exim-Version: 4.2.1 (built Thu, 05 May 2016 13:38:54 -0600) X-SA-Exim-Scanned: Yes (on in02.mta.xmission.com) Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Allow users with CAP_SYS_CHOWN over the superblock of a filesystem to chown files when inode owner is invalid. Ordinarily the capable_wrt_inode_uidgid check is sufficient to allow access to files but when the underlying filesystem has uids or gids that don't map to the current user namespace it is not enough, so the chown permission checks need to be extended to allow this case. Calling chown on filesystem nodes whose uid or gid don't map is necessary if those nodes are going to be modified as writing back inodes which contain uids or gids that don't map is likely to cause filesystem corruption of the uid or gid fields. Once chown has been called the existing capable_wrt_inode_uidgid checks are sufficient to allow the owner of a superblock to do anything the global root user can do with an appropriate set of capabilities. An ordinary filesystem mountable by a userns root will limit all uids and gids in s_user_ns or the INVALID_UID and INVALID_GID to flag all others. So having this added permission limited to just INVALID_UID and INVALID_GID is sufficient to handle every case on an ordinary filesystem. Of the virtual filesystems at least proc is known to set s_user_ns to something other than &init_user_ns, while at the same time presenting some files owned by GLOBAL_ROOT_UID. Those files the mounter of proc in a user namespace should not be able to chown to get access to. Limiting the relaxation in permission to just the minimum of allowing changing INVALID_UID and INVALID_GID prevents problems with cases like that. The original version of this patch was written by: Seth Forshee. I have rewritten and rethought this patch enough so it's really not the same thing (certainly it needs a different description), but he deserves credit for getting out there and getting the conversation started, and finding the potential gotcha's and putting up with my semi-paranoid feedback. Inspired-by: Seth Forshee Acked-by: Seth Forshee Signed-off-by: Eric W. Biederman --- fs/attr.c | 36 ++++++++++++++++++++++++++++-------- 1 file changed, 28 insertions(+), 8 deletions(-) diff --git a/fs/attr.c b/fs/attr.c index 12ffdb6fb63c..4220c98f41a5 100644 --- a/fs/attr.c +++ b/fs/attr.c @@ -18,6 +18,32 @@ #include #include +static bool chown_ok(const struct inode *inode, kuid_t uid) +{ + if (uid_eq(current_fsuid(), inode->i_uid) && + uid_eq(uid, inode->i_uid)) + return true; + if (capable_wrt_inode_uidgid(inode, CAP_CHOWN)) + return true; + if (uid_eq(inode->i_uid, INVALID_UID) && + ns_capable(inode->i_sb->s_user_ns, CAP_CHOWN)); + return true; + return false; +} + +static bool chgrp_ok(const struct inode *inode, kgid_t gid) +{ + if (uid_eq(current_fsuid(), inode->i_uid) && + (in_group_p(gid) || gid_eq(gid, inode->i_gid))) + return true; + if (capable_wrt_inode_uidgid(inode, CAP_CHOWN)) + return true; + if (gid_eq(inode->i_gid, INVALID_GID) && + ns_capable(inode->i_sb->s_user_ns, CAP_CHOWN)); + return true; + return false; +} + /** * setattr_prepare - check if attribute changes to a dentry are allowed * @dentry: dentry to check @@ -52,17 +78,11 @@ int setattr_prepare(struct dentry *dentry, struct iattr *attr) goto kill_priv; /* Make sure a caller can chown. */ - if ((ia_valid & ATTR_UID) && - (!uid_eq(current_fsuid(), inode->i_uid) || - !uid_eq(attr->ia_uid, inode->i_uid)) && - !capable_wrt_inode_uidgid(inode, CAP_CHOWN)) + if ((ia_valid & ATTR_UID) && !chown_ok(inode, attr->ia_uid)) return -EPERM; /* Make sure caller can chgrp. */ - if ((ia_valid & ATTR_GID) && - (!uid_eq(current_fsuid(), inode->i_uid) || - (!in_group_p(attr->ia_gid) && !gid_eq(attr->ia_gid, inode->i_gid))) && - !capable_wrt_inode_uidgid(inode, CAP_CHOWN)) + if ((ia_valid & ATTR_GID) && !chgrp_ok(inode, attr->ia_gid)) return -EPERM; /* Make sure a caller can chmod. */ -- 2.14.1