From patchwork Fri Sep 30 14:52:57 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Oleg Nesterov X-Patchwork-Id: 9358475 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 8AFB26075E for ; Fri, 30 Sep 2016 14:54:12 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 7BB1E2A07C for ; Fri, 30 Sep 2016 14:54:12 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 6D5E02A082; Fri, 30 Sep 2016 14:54:12 +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.9 required=2.0 tests=BAYES_00,RCVD_IN_DNSWL_HI 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 10DFA2A07C for ; Fri, 30 Sep 2016 14:54:12 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S933799AbcI3OyK (ORCPT ); Fri, 30 Sep 2016 10:54:10 -0400 Received: from mx1.redhat.com ([209.132.183.28]:37422 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S933395AbcI3OyJ (ORCPT ); Fri, 30 Sep 2016 10:54:09 -0400 Received: from int-mx10.intmail.prod.int.phx2.redhat.com (int-mx10.intmail.prod.int.phx2.redhat.com [10.5.11.23]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id E86FA4ACCF; Fri, 30 Sep 2016 14:54:07 +0000 (UTC) Received: from tranklukator.brq.redhat.com (dhcp-1-131.brq.redhat.com [10.34.1.131]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with SMTP id u8UEs1c5031599; Fri, 30 Sep 2016 10:54:01 -0400 Received: by tranklukator.brq.redhat.com (nbSMTP-1.00) for uid 500 oleg@redhat.com; Fri, 30 Sep 2016 16:53:03 +0200 (CEST) Date: Fri, 30 Sep 2016 16:52:57 +0200 From: Oleg Nesterov To: Jann Horn Cc: Alexander Viro , Roland McGrath , John Johansen , James Morris , "Serge E. Hallyn" , Paul Moore , Stephen Smalley , Eric Paris , Casey Schaufler , Kees Cook , Andrew Morton , Janis Danisevskis , Seth Forshee , "Eric . Biederman" , Thomas Gleixner , Benjamin LaHaise , Ben Hutchings , Andy Lutomirski , Linus Torvalds , linux-fsdevel@vger.kernel.org, linux-security-module@vger.kernel.org, security@kernel.org Subject: Re: [PATCH v2 4/8] futex: don't leak robust_list pointer Message-ID: <20160930145256.GB12862@redhat.com> References: <1474663238-22134-1-git-send-email-jann@thejh.net> <1474663238-22134-5-git-send-email-jann@thejh.net> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <1474663238-22134-5-git-send-email-jann@thejh.net> User-Agent: Mutt/1.5.18 (2008-05-17) X-Scanned-By: MIMEDefang 2.68 on 10.5.11.23 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.38]); Fri, 30 Sep 2016 14:54:08 +0000 (UTC) Sender: owner-linux-security-module@vger.kernel.org Precedence: bulk List-ID: X-Virus-Scanned: ClamAV using ClamSMTP On 09/23, Jann Horn wrote: > > This prevents an attacker from determining the robust_list or > compat_robust_list userspace pointer of a process created by executing > a setuid binary. Such an attack could be performed by racing > get_robust_list() with a setuid execution. The impact of this issue is that > an attacker could theoretically bypass ASLR when attacking setuid binaries. Well. I am not sure this actually needs a fix, but I won't argue. I can't really understand what this patch actually fixes, > @@ -3007,31 +3007,43 @@ SYSCALL_DEFINE3(get_robust_list, int, pid, > if (!futex_cmpxchg_enabled) > return -ENOSYS; > > - rcu_read_lock(); > - > - ret = -ESRCH; > - if (!pid) > + if (!pid) { > p = current; > - else { > + get_task_struct(p); > + } else { > + rcu_read_lock(); > p = find_task_by_vpid(pid); > + /* pin the task to permit dropping the RCU read lock before > + * acquiring the mutex > + */ > + if (p) > + get_task_struct(p); > + rcu_read_unlock(); > if (!p) > - goto err_unlock; > + return -ESRCH; > } > > + ret = mutex_lock_killable(&p->signal->cred_guard_light); > + if (ret) > + goto err_put; > + > ret = -EPERM; > if (!ptrace_may_access(p, PTRACE_MODE_READ_REALCREDS)) > goto err_unlock; > > head = p->robust_list; > - rcu_read_unlock(); OK, suppose it races with setuid exec, and mutex_lock_killable() + ptrace_may_access() comes after flush_old_exec() but before install_exec_creds(), in this case ptrace_may_access() can wrongly succeed. In theory, it is possible that the execing thread can complete exec, return to user-mode and call sys_set_robust_list() before we read head = p->robust_list. Yes, this is unlikely, but unless I am totally confused the race you are trying to fix is equally unlikely? perhaps we can make a much simpler change to prevent this, see below. We can rely on fact that both ptrace_may_access() and exec_mmap() takes the same task_lock(). Sure, this can "leak" robust_list too, a set-uid binary can exec and/or lower its credentials after we read p->robust_list, but personally I think we do not care. Or I missed something else? Oleg. --- To unsubscribe from this list: send the line "unsubscribe linux-security-module" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html --- x/kernel/futex.c +++ x/kernel/futex.c @@ -3019,10 +3019,10 @@ SYSCALL_DEFINE3(get_robust_list, int, pi } ret = -EPERM; + head = p->robust_list; if (!ptrace_may_access(p, PTRACE_MODE_READ_REALCREDS)) goto err_unlock; - head = p->robust_list; rcu_read_unlock(); if (put_user(sizeof(*head), len_ptr))