From patchwork Sun Oct 30 21:46:34 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jann Horn X-Patchwork-Id: 9404743 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 455166022E for ; Sun, 30 Oct 2016 21:47:02 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 41B3C28E58 for ; Sun, 30 Oct 2016 21:47:02 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 3660C28E73; Sun, 30 Oct 2016 21:47:02 +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 C085F28E58 for ; Sun, 30 Oct 2016 21:47:01 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754155AbcJ3Vq7 (ORCPT ); Sun, 30 Oct 2016 17:46:59 -0400 Received: from thejh.net ([37.221.195.125]:54381 "EHLO thejh.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753118AbcJ3Vqu (ORCPT ); Sun, 30 Oct 2016 17:46:50 -0400 Received: from pc.thejh.net (pc.vpn [192.168.44.2]) by thejh.net (Postfix) with ESMTPSA id 741F518134D; Sun, 30 Oct 2016 22:46:48 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=thejh.net; s=s2016; t=1477864009; bh=YFjjUnJXlOLWJ6N5OBNAwzjXg6qvK9JYGB7BXFDj8MM=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=o7CfxbWO4LFqZaRoRHRRfNcYPbW0BVG3HZcm+bfJ+fqa4V/mmS9cKjcPPXN6W5gdm Nf/HxcYeNnYN8nHv38+RxFP9wdb1KcBJk/e21WA6UjAQXg8O40HTS1iWzOEKlNxIva 6yVwdEX7JOPRUWNQCcZIlMSRr2eC7+WoA5rFxEj2xL3BSTOhzpqSCyxzF0gSzdpA1X 8oRzlHaBEy25duCe4lOno8QCCMHo+ezF993XZ3p1kMEYnvcP7IyadlLuRSI786nHed h59EP+uWwzNdT08cP3IEY1P/50ohKIHR8xRMTeW5UukyMPrFQ9f92rrnDion7CpJsF tg6T8VNhTsEiw== From: Jann Horn To: Alexander Viro , Roland McGrath , Oleg Nesterov , John Johansen , James Morris , "Serge E. Hallyn" , Paul Moore , Stephen Smalley , Eric Paris , Casey Schaufler , Kees Cook , Andrew Morton , Janis Danisevskis , Seth Forshee , "Eric W. Biederman" , Thomas Gleixner , Benjamin LaHaise , Ben Hutchings , Andy Lutomirski , Linus Torvalds , Krister Johansen Cc: linux-fsdevel@vger.kernel.org, linux-security-module@vger.kernel.org, security@kernel.org Subject: [PATCH v3 4/8] futex: don't leak robust_list pointer Date: Sun, 30 Oct 2016 22:46:34 +0100 Message-Id: <1477863998-3298-5-git-send-email-jann@thejh.net> X-Mailer: git-send-email 2.1.4 In-Reply-To: <1477863998-3298-1-git-send-email-jann@thejh.net> References: <1477863998-3298-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 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. changed in v2: - only get_task_struct(p) if p!=NULL (Ben Hutchings) - move the -ESRCH return check Signed-off-by: Jann Horn --- kernel/futex.c | 30 +++++++++++++++++++++--------- kernel/futex_compat.c | 30 +++++++++++++++++++++--------- 2 files changed, 42 insertions(+), 18 deletions(-) diff --git a/kernel/futex.c b/kernel/futex.c index 2c4be467fecd..f0697e0d55b8 100644 --- a/kernel/futex.c +++ b/kernel/futex.c @@ -3016,31 +3016,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(); + + mutex_unlock(&p->signal->cred_guard_light); + put_task_struct(p); if (put_user(sizeof(*head), len_ptr)) return -EFAULT; return put_user(head, head_ptr); err_unlock: - rcu_read_unlock(); - + mutex_unlock(¤t->signal->cred_guard_light); +err_put: + put_task_struct(p); return ret; } diff --git a/kernel/futex_compat.c b/kernel/futex_compat.c index 4ae3232e7a28..92c350f05ff8 100644 --- a/kernel/futex_compat.c +++ b/kernel/futex_compat.c @@ -143,31 +143,43 @@ COMPAT_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->compat_robust_list; - rcu_read_unlock(); + + mutex_unlock(&p->signal->cred_guard_light); + put_task_struct(p); if (put_user(sizeof(*head), len_ptr)) return -EFAULT; return put_user(ptr_to_compat(head), head_ptr); err_unlock: - rcu_read_unlock(); - + mutex_unlock(¤t->signal->cred_guard_light); +err_put: + put_task_struct(p); return ret; }