Received: by 2002:ac0:a581:0:0:0:0:0 with SMTP id m1-v6csp5598863imm; Tue, 26 Jun 2018 14:17:53 -0700 (PDT) X-Google-Smtp-Source: ADUXVKLAUu9FfloLs2Q50ihH+T+Fuukad2m7BozHEoCgTTFA9OzKH+/lezbYv/0KxAswbHR2hnSF X-Received: by 2002:a17:902:a9ca:: with SMTP id b10-v6mr3192411plr.275.1530047873712; Tue, 26 Jun 2018 14:17:53 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1530047873; cv=none; d=google.com; s=arc-20160816; b=puf/clofYWi/k8PEtJFx11k4ssGjLzbi9rv1gD7m5D0iAzhOIKPx4apl3ori8rr+NU G4V+FZX0TL9a8ffkn7B/RRz0vx6iwGXNM0DoMsaVQpXyz8aBaf/MulXWrUHLR7nA/PlS q6UvyfxWkIYs5WbnlM3m+GSlWg6Wr2jpSVhfDBMcEufiyJfCPEfuscjc4liA4GiO7oL+ 0tlyJwZSMNgU90XEAY45AhSOc3m7/nrb64EfKd7njX76XY2RTDdhg2omK0Lg8wSHzfnI YcwemK32yjtbN/Ti5kuPQUaO2ezfDclVuxyjJADB1xDxoPv9VheZ/aO5LvxGZtbQXh3z j/iw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from:dkim-signature:dkim-filter :arc-authentication-results; bh=WBwv6QEJ+AnZsA+DKfS+FkbwPQxsu9f9rU/PGtoYXzg=; b=DZFvuiY0vEFw2ehjIo49gqNry/kFf+lPAI8MeFvuYuJ13+BmzzRQtiuo4KJoeL4Yi4 j3yzdDAnirdY98EwlWymRE/sLEmPIHOSvu8B0k9/TAyB0cv4exUQW0vieNkTUfoOcAnJ Us1qqvZat/H7s35HLIXERjxnvl3G+2W47OaUA5x2trE6rb7R095Cf0QX65FXYGp7jeOH pTq8AhAYP6rJAvRLdB/3oWvl15VfYP+Kz9ONrop7EPIfk3MYFuD5UAy32kvNAfqjxF+N 50Wil4uyfLEkORQlTqxVUbENYlGL10RoEVdDTY7IEOOk7Eu3b4B5vkelFDKbp4BdQtTA GoqA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@efficios.com header.s=default header.b="C/3keOi5"; 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; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=efficios.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id cc1-v6si2313258plb.458.2018.06.26.14.17.39; Tue, 26 Jun 2018 14:17:53 -0700 (PDT) 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; dkim=pass header.i=@efficios.com header.s=default header.b="C/3keOi5"; 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; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=efficios.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752690AbeFZVQm (ORCPT + 99 others); Tue, 26 Jun 2018 17:16:42 -0400 Received: from mail.efficios.com ([167.114.142.138]:40998 "EHLO mail.efficios.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752048AbeFZVQh (ORCPT ); Tue, 26 Jun 2018 17:16:37 -0400 Received: from localhost (ip6-localhost [IPv6:::1]) by mail.efficios.com (Postfix) with ESMTP id 96BA522DAE2; Tue, 26 Jun 2018 17:16:36 -0400 (EDT) Received: from mail.efficios.com ([IPv6:::1]) by localhost (mail02.efficios.com [IPv6:::1]) (amavisd-new, port 10032) with ESMTP id IZkYaDCE8Pu0; Tue, 26 Jun 2018 17:16:36 -0400 (EDT) Received: from localhost (ip6-localhost [IPv6:::1]) by mail.efficios.com (Postfix) with ESMTP id 1F37B22DADD; Tue, 26 Jun 2018 17:16:36 -0400 (EDT) DKIM-Filter: OpenDKIM Filter v2.10.3 mail.efficios.com 1F37B22DADD DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=efficios.com; s=default; t=1530047796; bh=WBwv6QEJ+AnZsA+DKfS+FkbwPQxsu9f9rU/PGtoYXzg=; h=From:To:Date:Message-Id; b=C/3keOi5nGTUvTdllc4wwTvK8OyvHDwyMYFJGs3TlLcxP7w4zV8YafFwbmBZV7VHY +oPA8Bbg9/egtbEa1sTqrGaSf/pf2PRqPqzQIpSJ142r0MZQ2U0vSGR1ZFOnE7sMuE 8JtZwHi+r1zoEmQPN3TKHgN7VMiw1y1O2BdDu33ua2u5qdyEuK2UPaTi1mTGqd8xCy k1w1KWNXVWtQgul3Ph4Umrs5TrdCwgKXghFcSiK/D4tHY9AI/YQKMnlY6OGU3Kppoy 0XMvWu8yH8Jnhb4PTufqAr7Ogcr6jDtAus8McD6FJUsJD1Ljx2HKBm786i9uWcEorw H8TQgfq0wmSQg== X-Virus-Scanned: amavisd-new at efficios.com Received: from mail.efficios.com ([IPv6:::1]) by localhost (mail02.efficios.com [IPv6:::1]) (amavisd-new, port 10026) with ESMTP id InlXhG8xKQCn; Tue, 26 Jun 2018 17:16:36 -0400 (EDT) Received: from thinkos.internal.efficios.com (192-222-157-41.qc.cable.ebox.net [192.222.157.41]) by mail.efficios.com (Postfix) with ESMTPSA id B358822DAD1; Tue, 26 Jun 2018 17:16:35 -0400 (EDT) From: Mathieu Desnoyers To: Andy Lutomirski , Thomas Gleixner Cc: linux-kernel@vger.kernel.org, Mathieu Desnoyers , Joel Fernandes , Peter Zijlstra , Catalin Marinas , Dave Watson , Will Deacon , Andi Kleen , "H . Peter Anvin" , Chris Lameter , Russell King , Andrew Hunter , Michael Kerrisk , "Paul E . McKenney" , Paul Turner , Boqun Feng , Josh Triplett , Steven Rostedt , Ben Maurer , linux-api@vger.kernel.org, linux-arch@vger.kernel.org, x86@kernel.org, Andrew Morton , Linus Torvalds Subject: [RFC PATCH for 4.18 2/2] rseq: compat: clear high bits of rseq_cs fields Date: Tue, 26 Jun 2018 17:16:17 -0400 Message-Id: <20180626211617.8933-2-mathieu.desnoyers@efficios.com> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20180626211617.8933-1-mathieu.desnoyers@efficios.com> References: <20180626211617.8933-1-mathieu.desnoyers@efficios.com> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Make the behavior rseq on compat tasks more robust by ensuring that kernel/rseq.c:rseq_get_rseq_cs() clears the high bits of rseq_cs->abort_ip, rseq_cs->start_ip and rseq_cs->post_commit_offset when a 32-bit binary is run on a 64-bit kernel. The intent here is that if user-space has garbage rather than zeroes in its struct rseq_cs fields padding, the behavior will be the same whether the binary is run on 32-bit or 64-bit kernels. Use in_compat_syscall() when rseq_get_rseq_cs() is invoked from system call context, and use is_compat_frame() when invoked from signal delivery. Signed-off-by: Mathieu Desnoyers Cc: Thomas Gleixner Cc: Joel Fernandes Cc: Peter Zijlstra Cc: Catalin Marinas Cc: Dave Watson Cc: Will Deacon Cc: Andi Kleen Cc: "H . Peter Anvin" Cc: Chris Lameter Cc: Russell King Cc: Andrew Hunter Cc: Michael Kerrisk Cc: "Paul E . McKenney" Cc: Paul Turner Cc: Boqun Feng Cc: Josh Triplett Cc: Steven Rostedt Cc: Ben Maurer Cc: linux-api@vger.kernel.org Cc: linux-arch@vger.kernel.org Cc: x86@kernel.org Cc: Andy Lutomirski Cc: Andrew Morton Cc: Linus Torvalds --- kernel/rseq.c | 28 +++++++++++++++++++++++----- 1 file changed, 23 insertions(+), 5 deletions(-) diff --git a/kernel/rseq.c b/kernel/rseq.c index 22b6acf1ad63..7b1d51b965fc 100644 --- a/kernel/rseq.c +++ b/kernel/rseq.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #define CREATE_TRACE_POINTS @@ -112,7 +113,23 @@ static int rseq_reset_rseq_cpu_id(struct task_struct *t) return 0; } -static int rseq_get_rseq_cs(struct task_struct *t, struct rseq_cs *rseq_cs) +#ifdef CONFIG_COMPAT +static void rseq_cs_compat(struct ksignal *ksig, struct rseq_cs *rseq_cs) +{ + if (!(ksig ? is_compat_frame(ksig) : in_compat_syscall())) + return; + + rseq_cs->abort_ip = (compat_uptr_t) rseq_cs->abort_ip; + rseq_cs->start_ip = (compat_uptr_t) rseq_cs->start_ip; + rseq_cs->post_commit_offset = + (compat_uptr_t) rseq_cs->post_commit_offset; +} +#else +static void rseq_cs_compat(struct ksignal *ksig, struct rseq_cs *rseq_cs) { } +#endif + +static int rseq_get_rseq_cs(struct ksignal *ksig, struct task_struct *t, + struct rseq_cs *rseq_cs) { struct rseq_cs __user *urseq_cs; unsigned long ptr; @@ -132,6 +149,7 @@ static int rseq_get_rseq_cs(struct task_struct *t, struct rseq_cs *rseq_cs) return -EFAULT; if (rseq_cs->version > 0) return -EINVAL; + rseq_cs_compat(ksig, rseq_cs); /* Ensure that abort_ip is not in the critical section. */ if (rseq_cs->abort_ip - rseq_cs->start_ip < rseq_cs->post_commit_offset) @@ -209,14 +227,14 @@ static bool in_rseq_cs(unsigned long ip, struct rseq_cs *rseq_cs) return ip - rseq_cs->start_ip < rseq_cs->post_commit_offset; } -static int rseq_ip_fixup(struct pt_regs *regs) +static int rseq_ip_fixup(struct ksignal *ksig, struct pt_regs *regs) { unsigned long ip = instruction_pointer(regs); struct task_struct *t = current; struct rseq_cs rseq_cs; int ret; - ret = rseq_get_rseq_cs(t, &rseq_cs); + ret = rseq_get_rseq_cs(ksig, t, &rseq_cs); if (ret) return ret; @@ -260,7 +278,7 @@ void __rseq_handle_notify_resume(struct ksignal *ksig, struct pt_regs *regs) return; if (unlikely(!access_ok(VERIFY_WRITE, t->rseq, sizeof(*t->rseq)))) goto error; - ret = rseq_ip_fixup(regs); + ret = rseq_ip_fixup(ksig, regs); if (unlikely(ret < 0)) goto error; if (unlikely(rseq_update_cpu_id(t))) @@ -287,7 +305,7 @@ void rseq_syscall(struct pt_regs *regs) if (!t->rseq) return; if (!access_ok(VERIFY_READ, t->rseq, sizeof(*t->rseq)) || - rseq_get_rseq_cs(t, &rseq_cs) || in_rseq_cs(ip, &rseq_cs)) + rseq_get_rseq_cs(NULL, t, &rseq_cs) || in_rseq_cs(ip, &rseq_cs)) force_sig(SIGSEGV, t); } -- 2.11.0