Received: by 2002:a25:1506:0:0:0:0:0 with SMTP id 6csp2062090ybv; Fri, 14 Feb 2020 10:42:30 -0800 (PST) X-Google-Smtp-Source: APXvYqxei8r6gJ/Z6o3kIK5kEP5QZhFQmYAhnyiNQ4IZQSGaK6N7GSA3Xb3I+6voRSm7anzMqSEe X-Received: by 2002:aca:ab51:: with SMTP id u78mr2830366oie.21.1581705750300; Fri, 14 Feb 2020 10:42:30 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1581705750; cv=none; d=google.com; s=arc-20160816; b=ANfDE05rCboA8BxIKspqkTKoLFJQf4TF4A/6HmT4qnAevSzmRXtUgpHfXSePtWxenl MbA2u7nX898Yi6DEK5W6r/ngsFlw9eJJNtJxZZdeqFZ+7s0PTPDg9Qb0uDydjJPvbg6J OBCLBfdkhGH9Ik7WRRlLZ2jc7iE8zZ47RZ6rj6Dcyeb//Q/9tAVTnksH+CZ9Wbq88M90 Smtr0aalQkWud1k+dQM3vIs6fH1Kqzkdl/Y6A/A6ZSUAlB11bmlgIUY2HRdEvDuZVUC9 jFM1meT0mCsEc9uDMkA88+qBS0CU35bMRiJPP182sScL7PZttLicDjX3it1Xb16Q583P phZw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from; bh=hreQTnVwCkwdADajiOlJbEsmzNsJVa4J8WePNVm9guM=; b=P2yZv6ut5SxpiJGDygxUMJhPtmW+kJUmgdec3hCR6CdQxrYs/muWWv3yyjtMc9Zmkk ODeIfgrZI+jo8R5ujb0Y5OClq5HF2ugrMLBZajkkzMbTMvO20Z8q7glCoR4PPSfliExu PZIHZZJGnSBhxSmV2nVeR6CtcXaJabUYBqciyvdJRUqXCtGO7CV/gMo8cwPpo8UJkpdM QON75Lz3/8HiSDtBfkcuZJMF/SW1sDeBhfX6vwOqhVUCrgonEOTpfuRNtsxy/PSsq5Ee Spu302eexyfFrSvgW327m5jpxkA5ITRXiprrnbDlsyLGR4m1lEuU8l2SOvmYUImejskd SsJw== 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 x6si3212133ota.322.2020.02.14.10.42.18; Fri, 14 Feb 2020 10:42:30 -0800 (PST) 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 S2390070AbgBNSmO (ORCPT + 99 others); Fri, 14 Feb 2020 13:42:14 -0500 Received: from youngberry.canonical.com ([91.189.89.112]:33920 "EHLO youngberry.canonical.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2388592AbgBNSmO (ORCPT ); Fri, 14 Feb 2020 13:42:14 -0500 Received: from ip5f5bf7ec.dynamic.kabel-deutschland.de ([95.91.247.236] helo=wittgenstein.fritz.box) by youngberry.canonical.com with esmtpsa (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.86_2) (envelope-from ) id 1j2fqn-0000uO-SV; Fri, 14 Feb 2020 18:38:05 +0000 From: Christian Brauner To: =?UTF-8?q?St=C3=A9phane=20Graber?= , "Eric W. Biederman" , Aleksa Sarai , Jann Horn Cc: smbarber@chromium.org, Seth Forshee , Alexander Viro , Alexey Dobriyan , Serge Hallyn , James Morris , Kees Cook , Jonathan Corbet , Phil Estes , linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, containers@lists.linux-foundation.org, linux-security-module@vger.kernel.org, linux-api@vger.kernel.org, Christian Brauner Subject: [PATCH v2 26/28] exec: bprm_fill_uid(): handle fsid mappings Date: Fri, 14 Feb 2020 19:35:52 +0100 Message-Id: <20200214183554.1133805-27-christian.brauner@ubuntu.com> X-Mailer: git-send-email 2.25.0 In-Reply-To: <20200214183554.1133805-1-christian.brauner@ubuntu.com> References: <20200214183554.1133805-1-christian.brauner@ubuntu.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Make sure that during suid/sgid binary execution we lookup the fsids in the fsid mappings. If the kernel is compiled without fsid mappings or now fsid mappings are setup the behavior is unchanged. Assuming we have a binary in a given user namespace that is owned by 0:0 in the given user namespace which appears as 300000:300000 on-disk in the initial user namespace. Now assume we write an id mapping of 0 100000 100000 and an fsid mapping for 0 300000 300000 in the user namespace. When we hit bprm_fill_uid() during setid execution we will retrieve inode kuid=100000 and kgid=1000000. We first check whether there's an fsid mapping for these kids. In our scenario we find that they map to fsuid=0 and fsgid=0 in the user namespace. Now we translate them into kids in the id mapping. In our example they translate to kuid=100000 and kgid=100000 which means the file will ultimately run as uid=0 and gid=0 in the user namespace and as uid=100000, gid=100000 in the initial user namespace. Let's alter the example and assume that there is an fsid mapping of 0 300000 300000 set up but no id mapping has been setup for the user namespace. In this the last step of translating into a valid kid pair in the id mappings will fail and we will behave as before and ignore the sid bits. Cc: Jann Horn Signed-off-by: Christian Brauner --- /* v2 */ patch added - Christian Brauner : - Make sure that bprm_fill_uid() handles fsid mappings. --- fs/exec.c | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/fs/exec.c b/fs/exec.c index db17be51b112..9e4a7e757cef 100644 --- a/fs/exec.c +++ b/fs/exec.c @@ -62,6 +62,7 @@ #include #include #include +#include #include #include @@ -1518,8 +1519,8 @@ static void bprm_fill_uid(struct linux_binprm *bprm) { struct inode *inode; unsigned int mode; - kuid_t uid; - kgid_t gid; + kuid_t uid, euid; + kgid_t gid, egid; /* * Since this can be called multiple times (via prepare_binprm), @@ -1551,18 +1552,30 @@ static void bprm_fill_uid(struct linux_binprm *bprm) inode_unlock(inode); /* We ignore suid/sgid if there are no mappings for them in the ns */ - if (!kuid_has_mapping(bprm->cred->user_ns, uid) || - !kgid_has_mapping(bprm->cred->user_ns, gid)) + if (!kfsuid_has_mapping(bprm->cred->user_ns, uid) || + !kfsgid_has_mapping(bprm->cred->user_ns, gid)) return; + if (mode & S_ISUID) { + euid = kfsuid_to_kuid(bprm->cred->user_ns, uid); + if (!uid_valid(euid)) + return; + } + + if ((mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP)) { + egid = kfsgid_to_kgid(bprm->cred->user_ns, gid); + if (!gid_valid(egid)) + return; + } + if (mode & S_ISUID) { bprm->per_clear |= PER_CLEAR_ON_SETID; - bprm->cred->euid = uid; + bprm->cred->euid = euid; } if ((mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP)) { bprm->per_clear |= PER_CLEAR_ON_SETID; - bprm->cred->egid = gid; + bprm->cred->egid = egid; } } -- 2.25.0