From patchwork Wed Sep 28 22:54:41 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jann Horn X-Patchwork-Id: 9355123 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 0A63D60756 for ; Wed, 28 Sep 2016 22:55:08 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id F162F29529 for ; Wed, 28 Sep 2016 22:55:07 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id E47C02964E; Wed, 28 Sep 2016 22:55:07 +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=ham 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 12FE929529 for ; Wed, 28 Sep 2016 22:55:06 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S933052AbcI1Wy7 (ORCPT ); Wed, 28 Sep 2016 18:54:59 -0400 Received: from thejh.net ([37.221.195.125]:52544 "EHLO thejh.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753548AbcI1Wy5 (ORCPT ); Wed, 28 Sep 2016 18:54:57 -0400 Received: from pc.thejh.net (pc.vpn [192.168.44.2]) by thejh.net (Postfix) with ESMTPSA id 837BD1809C2; Thu, 29 Sep 2016 00:54:55 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=thejh.net; s=s2016; t=1475103296; bh=8Btts8qbU0UElp5kXTzOuXXiuWtSu8OzVo5j3JSLgZ8=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Fem4/ULavY5jErhrOJYvQiBOF62pC34bRAWVF0TqopSBCvrk94C46IH/f1RBmUJot YwU57AYGktZSnAEaLEhdQq5S37As7cK3iAOzVzTeqNMLRW26uwP8KeQa7F0hbkAFD/ wUpzLMeqHG9WviMgk5NZCZj3NCFqNWBPIH4R7LeKaPxjG3fTTlpkVGEdaBjkDyohrb rQrIuTkgSY+eBVruuAkMtg9pw5Ho1R5YSfDjBs+VurcwmFbSuEOZv5hi7AjKFUHSwb e4Rs5Ht2BDNVWzfjujjVP/X2aWZOmHTF29b7V7twht+taFyLT9hw/bWgQv7qMQlfRo SY93rpisA4xKQ== From: Jann Horn To: security@kernel.org, Alexander Viro , Paul Moore , Stephen Smalley , Eric Paris , James Morris , "Serge E. Hallyn" Cc: Nick Kralevich , Janis Danisevskis , linux-security-module@vger.kernel.org, linux-mm@kvack.org, linux-kernel@vger.kernel.org Subject: [PATCH v2 3/3] selinux: require EXECMEM for forced ptrace poke Date: Thu, 29 Sep 2016 00:54:41 +0200 Message-Id: <1475103281-7989-4-git-send-email-jann@thejh.net> X-Mailer: git-send-email 2.1.4 In-Reply-To: <1475103281-7989-1-git-send-email-jann@thejh.net> References: <1475103281-7989-1-git-send-email-jann@thejh.net> Sender: owner-linux-security-module@vger.kernel.org Precedence: bulk List-ID: X-Virus-Scanned: ClamAV using ClamSMTP This is a breaking change for SELinux users that restrict EXECMEM: It might break gdb if gdb is executed in a domain that does not have EXECMEM privilege over the debuggee domain. Unlike most other SELinux hooks, this one takes the subject credentials as an argument instead of looking up current_cred(). This is done because the security_forced_write() LSM hook can be invoked from within the write handler of /proc/$pid/mem, where current_cred() is pretty useless. Signed-off-by: Jann Horn Reviewed-by: Janis Danisevskis --- security/selinux/hooks.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 13185a6..e36682a 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -2149,6 +2149,20 @@ static int selinux_ptrace_traceme(struct task_struct *parent) return task_has_perm(parent, current, PROCESS__PTRACE); } +static int selinux_forced_write(struct vm_area_struct *vma, + const struct cred *subject_cred, + const struct cred *object_cred) +{ + /* Permitting a write to readonly memory is fine - making the readonly + * memory executable afterwards would require EXECMOD permission because + * anon_vma would be non-NULL. + */ + if ((vma->vm_flags & VM_EXEC) == 0) + return 0; + + return cred_has_perm(subject_cred, object_cred, PROCESS__EXECMEM); +} + static int selinux_capget(struct task_struct *target, kernel_cap_t *effective, kernel_cap_t *inheritable, kernel_cap_t *permitted) { @@ -6033,6 +6047,7 @@ static struct security_hook_list selinux_hooks[] = { LSM_HOOK_INIT(ptrace_access_check, selinux_ptrace_access_check), LSM_HOOK_INIT(ptrace_traceme, selinux_ptrace_traceme), + LSM_HOOK_INIT(forced_write, selinux_forced_write), LSM_HOOK_INIT(capget, selinux_capget), LSM_HOOK_INIT(capset, selinux_capset), LSM_HOOK_INIT(capable, selinux_capable),