From patchwork Tue Aug 1 19:16:26 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kees Cook X-Patchwork-Id: 9875345 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 0567C604DA for ; Tue, 1 Aug 2017 19:20:51 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id EAF052872B for ; Tue, 1 Aug 2017 19:20:50 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id DFC1E28731; Tue, 1 Aug 2017 19:20:50 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.8 required=2.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_HI,T_DKIM_INVALID autolearn=unavailable version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 470D92872B for ; Tue, 1 Aug 2017 19:20:50 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752422AbdHATUi (ORCPT ); Tue, 1 Aug 2017 15:20:38 -0400 Received: from mail-pf0-f182.google.com ([209.85.192.182]:32979 "EHLO mail-pf0-f182.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752130AbdHATQp (ORCPT ); Tue, 1 Aug 2017 15:16:45 -0400 Received: by mail-pf0-f182.google.com with SMTP id d67so11537287pfc.0 for ; Tue, 01 Aug 2017 12:16:44 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=vfGwHSdqS/NUZNDGDlsTUNfjSZUQ3WLQqX+y4nVe4CY=; b=SLswe0R7diZCEE8C/PFaojiosqtQ1pL0YkuY0iijZlnFdZmlOyD66y+Szg1x5dVWJA AVrAXPw9aSGKgWckEXx61N7vftrtdtnzUgHzF1tp16SnSwVnkko1agSvQeZ36+w05qkV 7bqhWGu449xKiklV+ej5qsmbKQsxE5CwWc/sk= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=vfGwHSdqS/NUZNDGDlsTUNfjSZUQ3WLQqX+y4nVe4CY=; b=C5ORVhb+g/XTY+ZIvoJamnOGHLNnIOLVFf8r7mh1d9lLeodImE6XN9ShsCeqC0eZag rimd51JUY451DRhOG+yhEeZggLeyYJqFlWlTl80pO07bopaLg/zHkulTQtVuKO0TlVut sci3KrZzSkpLD1GWOYhXvwk+L/Lk/NCd8CS5faKYJ/P5hyma4rAdt8L6lmshZ9NZqDTw z4mLGRgUTGNvMs5RGNXVrhscv6aUkh+Jq8ryMQsdsgz2ydGHwvPTQgfh1Y01bhiEbO1z G4mT25Fl0YkMeZdlRVwV9ODxglWjPX8eIHMt5RragIpt0FnHbFluth1/lH5130ntAZmf hUHw== X-Gm-Message-State: AIVw110QhjZg9AI34Pm4mkZDBRUlagxZdvs8nhS/ySYdFDjdrn50Aubg YqqPZlnryKQqvyyh X-Received: by 10.84.167.2 with SMTP id c2mr21835345plb.366.1501615004375; Tue, 01 Aug 2017 12:16:44 -0700 (PDT) Received: from www.outflux.net (173-164-112-133-Oregon.hfc.comcastbusiness.net. [173.164.112.133]) by smtp.gmail.com with ESMTPSA id j65sm1663052pgc.36.2017.08.01.12.16.41 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 01 Aug 2017 12:16:41 -0700 (PDT) From: Kees Cook To: linux-kernel@vger.kernel.org Cc: Kees Cook , David Howells , Linus Torvalds , Andrew Morton , James Morris , "Serge E. Hallyn" , Andy Lutomirski , "Eric W. Biederman" , John Johansen , Paul Moore , Casey Schaufler , Stephen Smalley , Tetsuo Handa , linux-fsdevel@vger.kernel.org, linux-security-module@vger.kernel.org Subject: [PATCH v5 03/15] binfmt: Introduce secureexec flag Date: Tue, 1 Aug 2017 12:16:26 -0700 Message-Id: <1501614998-62619-4-git-send-email-keescook@chromium.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1501614998-62619-1-git-send-email-keescook@chromium.org> References: <1501614998-62619-1-git-send-email-keescook@chromium.org> Sender: owner-linux-security-module@vger.kernel.org Precedence: bulk List-ID: X-Virus-Scanned: ClamAV using ClamSMTP The bprm_secureexec hook can be moved earlier. Right now, it is called during create_elf_tables(), via load_binary(), via search_binary_handler(), via exec_binprm(). Nearly all (see exception below) state used by bprm_secureexec is created during the bprm_set_creds hook, called from prepare_binprm(). For all LSMs (except commoncaps described next), only the first execution of bprm_set_creds takes any effect (they all check bprm->called_set_creds which prepare_binprm() sets after the first call to the bprm_set_creds hook). However, all these LSMs also only do anything with bprm_secureexec when they detected a secure state during their first run of bprm_set_creds. Therefore, it is functionally identical to move the detection into bprm_set_creds, since the results from secureexec here only need to be based on the first call to the LSM's bprm_set_creds hook. The single exception is that the commoncaps secureexec hook also examines euid/uid and egid/gid differences which are controlled by bprm_fill_uid(), via prepare_binprm(), which can be called multiple times (e.g. binfmt_script, binfmt_misc), and may clear the euid/egid for the final load (i.e. the script interpreter). However, while commoncaps specifically ignores bprm->cred_prepared, and runs its bprm_set_creds hook each time prepare_binprm() may get called, it needs to base the secureexec decision on the final call to bprm_set_creds. As a result, it will need special handling. To begin this refactoring, this adds the secureexec flag to the bprm struct, and calls the secureexec hook during setup_new_exec(). This is safe since all the cred work is finished (and past the point of no return). This explicit call will be removed in later patches once the hook has been removed. Cc: David Howells Signed-off-by: Kees Cook Reviewed-by: John Johansen Acked-by: Serge Hallyn Reviewed-by: James Morris --- fs/binfmt_elf.c | 2 +- fs/binfmt_elf_fdpic.c | 2 +- fs/exec.c | 2 ++ include/linux/binfmts.h | 8 +++++++- 4 files changed, 11 insertions(+), 3 deletions(-) diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c index 879ff9c7ffd0..3b7dda91b07b 100644 --- a/fs/binfmt_elf.c +++ b/fs/binfmt_elf.c @@ -252,7 +252,7 @@ create_elf_tables(struct linux_binprm *bprm, struct elfhdr *exec, NEW_AUX_ENT(AT_EUID, from_kuid_munged(cred->user_ns, cred->euid)); NEW_AUX_ENT(AT_GID, from_kgid_munged(cred->user_ns, cred->gid)); NEW_AUX_ENT(AT_EGID, from_kgid_munged(cred->user_ns, cred->egid)); - NEW_AUX_ENT(AT_SECURE, security_bprm_secureexec(bprm)); + NEW_AUX_ENT(AT_SECURE, bprm->secureexec); NEW_AUX_ENT(AT_RANDOM, (elf_addr_t)(unsigned long)u_rand_bytes); #ifdef ELF_HWCAP2 NEW_AUX_ENT(AT_HWCAP2, ELF_HWCAP2); diff --git a/fs/binfmt_elf_fdpic.c b/fs/binfmt_elf_fdpic.c index cf93a4fad012..5aa9199dfb13 100644 --- a/fs/binfmt_elf_fdpic.c +++ b/fs/binfmt_elf_fdpic.c @@ -650,7 +650,7 @@ static int create_elf_fdpic_tables(struct linux_binprm *bprm, NEW_AUX_ENT(AT_EUID, (elf_addr_t) from_kuid_munged(cred->user_ns, cred->euid)); NEW_AUX_ENT(AT_GID, (elf_addr_t) from_kgid_munged(cred->user_ns, cred->gid)); NEW_AUX_ENT(AT_EGID, (elf_addr_t) from_kgid_munged(cred->user_ns, cred->egid)); - NEW_AUX_ENT(AT_SECURE, security_bprm_secureexec(bprm)); + NEW_AUX_ENT(AT_SECURE, bprm->secureexec); NEW_AUX_ENT(AT_EXECFN, bprm->exec); #ifdef ARCH_DLINFO diff --git a/fs/exec.c b/fs/exec.c index 26b98072be50..0f361115c88f 100644 --- a/fs/exec.c +++ b/fs/exec.c @@ -1343,6 +1343,8 @@ EXPORT_SYMBOL(would_dump); void setup_new_exec(struct linux_binprm * bprm) { + bprm->secureexec |= security_bprm_secureexec(bprm); + arch_pick_mmap_layout(current->mm); current->sas_ss_sp = current->sas_ss_size = 0; diff --git a/include/linux/binfmts.h b/include/linux/binfmts.h index 9023e1d2d5cd..16838ba7ee75 100644 --- a/include/linux/binfmts.h +++ b/include/linux/binfmts.h @@ -31,9 +31,15 @@ struct linux_binprm { * binfmt_script/misc). */ called_set_creds:1, - cap_effective:1;/* true if has elevated effective capabilities, + cap_effective:1,/* true if has elevated effective capabilities, * false if not; except for init which inherits * its parent's caps anyway */ + /* + * Set by bprm_set_creds hook to indicate a privilege-gaining + * exec has happened. Used to sanitize execution environment + * and to set AT_SECURE auxv for glibc. + */ + secureexec:1; #ifdef __alpha__ unsigned int taso:1; #endif