Received: by 2002:a25:d7c1:0:0:0:0:0 with SMTP id o184csp4141280ybg; Fri, 25 Oct 2019 14:00:28 -0700 (PDT) X-Google-Smtp-Source: APXvYqz6jPFcERKitJT5irCVecLyZFBIsJh1vFSBPtLs48S4Rm9cZdodYA4qNV+GoWYsXjoqkX5X X-Received: by 2002:a17:906:22cc:: with SMTP id q12mr5493703eja.131.1572037228079; Fri, 25 Oct 2019 14:00:28 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1572037228; cv=none; d=google.com; s=arc-20160816; b=YA+DXMoSUi0D8Dx/In037yi+DmVHm64o+B8M/3eua0sti7FVviOFuzM7WcCKoZfBUp hrPYea/Zd7FPj9LEoYr5dJsZbOJ3VdzDmAhFDcgO6pSoyxCsmkbRbqjm1gdi/jMvxFEV jR+gy5wt7fcybqUF2RyJJI7KREUUCtwplLLa83cj0iqc7BuH9AjC2st5xQbF3Imzf1K7 xxOvcCilPV+k5xmGfa+99hqnNVa5PsCoQV2pbyLJtCKjgf5ldKcCmEkGb8iJSmkNa2WW hzzq1fX4eOVTtu8pacQW7TgMYSbWDGlYXrZivioarF7bNRvZa6bJnIlU6yA0BiN6m0Kx A7Kg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:cc:to:subject:message-id:date:from :in-reply-to:references:mime-version:dkim-signature; bh=B01qVjfF1LUa0PK52bjL02zxaBRU3eQBI1v+W/4JeHk=; b=1EUswOKlJC/tyNQxdDWl16GFzmuLbU6IDsdZvFwpnnbBFjLLbuuydgXarQzKftuxMs 9G+NzQ7jW7xBjHtIsa2pKN5uf9qOAy2EuZ+f5/reWY4bAn1dqlw554eEuiqvIE29Uhgl mw7Em/KJ6kqfaOhn5kFyXArrVsWz4Wfc0zqbYxpemwpOkQ/M0cShLV3BDscsNeCJTejG ptUXZJdlPxc1L89tauHDxElDIpCPO5F9ixtlfDVbr2Ih1xg+v0cqnUQz395ILl8VAkzI 73z5JI+7ONOYWwAnGOWShpownc5gWAwU+0QMYQ9XJ/4/6jM0pvbFxUAYR/EMTdVTWyLN Te0g== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@google.com header.s=20161025 header.b=LoSD3OZa; 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=REJECT sp=REJECT dis=NONE) header.from=google.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id a28si2158515edc.5.2019.10.25.14.00.04; Fri, 25 Oct 2019 14:00:28 -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=@google.com header.s=20161025 header.b=LoSD3OZa; 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=REJECT sp=REJECT dis=NONE) header.from=google.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728664AbfJYUtf (ORCPT + 99 others); Fri, 25 Oct 2019 16:49:35 -0400 Received: from mail-vs1-f65.google.com ([209.85.217.65]:40804 "EHLO mail-vs1-f65.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725874AbfJYUte (ORCPT ); Fri, 25 Oct 2019 16:49:34 -0400 Received: by mail-vs1-f65.google.com with SMTP id v10so2364900vsc.7 for ; Fri, 25 Oct 2019 13:49:33 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=mime-version:references:in-reply-to:from:date:message-id:subject:to :cc; bh=B01qVjfF1LUa0PK52bjL02zxaBRU3eQBI1v+W/4JeHk=; b=LoSD3OZaEiLCMCyYB7WH+dmOE3giL1Rn/oOCaqr8KZIUPs9oNnBAX6h7DIpplETh/t Omaop/utJ7AeIZA9zdG2w3rvVFoP7cm2sHz8InOOQrKWFNZwxRR99vskLqIZWxI+akK7 Cn8Rjj+QMmBCU8FITbSo18rQdoyRMsKUvjpt6Ar8qszVQ65XaVmFB+VKjRWHMe854GK3 ASqeAGPJEm1/jq31LvxmrmHzMfPkeiCJgRdv49M55kLjJgk0flgNf6HmaNmtlpmBIPyW bbCRcDAnLzrC5k0HlPPGloTl1WOPl/1JYKEDPIqkdq+OQXGt/qBiXYUzNyt2hflsRSK0 sD9Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to:cc; bh=B01qVjfF1LUa0PK52bjL02zxaBRU3eQBI1v+W/4JeHk=; b=WtEkPP1Q/zXQnWNUAyF2K6nVgx45nSDzTZyoVEA7H6g83O9IQqJZ+CbFn972SHkrsJ qdOqmIYe7COh2v8s17exATboeW52wILaZ7/TiHkSmvK+4L584sJ7PI8dNpapaVnFSsQP T0HIUBhACN9FBZFKjtDKYBArIZc3CrCjiZhzeoBk7jKl7VRlmAXW+wBxdiEUnmkK2XRU /Tlqthts8L+r8BcqH1iZFhsNwBWFmkDxnRfiuYJL+ammEXaFv3HhLSNgs5/UgLCsKsZ/ pCI2JWGYS6g/j8opMCiUEJuhZX734kI1wo4oz9RdXAH3Oi4bc9gnSjitb0ApELahOS66 b5jA== X-Gm-Message-State: APjAAAU1yyIXuIHYwYewZFvbuiH/Xs9XXwDA0txJpQgY8lyoXio7HYng wymqL/oswUvdXDObwqjqwHep0gy+qo8T55Zk4negHA== X-Received: by 2002:a67:ffc7:: with SMTP id w7mr3154037vsq.15.1572036572738; Fri, 25 Oct 2019 13:49:32 -0700 (PDT) MIME-Version: 1.0 References: <20191018161033.261971-1-samitolvanen@google.com> <20191024225132.13410-1-samitolvanen@google.com> <20191024225132.13410-6-samitolvanen@google.com> <20191025105643.GD40270@lakrids.cambridge.arm.com> In-Reply-To: <20191025105643.GD40270@lakrids.cambridge.arm.com> From: Sami Tolvanen Date: Fri, 25 Oct 2019 13:49:21 -0700 Message-ID: Subject: Re: [PATCH v2 05/17] add support for Clang's Shadow Call Stack (SCS) To: Mark Rutland Cc: Will Deacon , Catalin Marinas , Steven Rostedt , Masami Hiramatsu , Ard Biesheuvel , Dave Martin , Kees Cook , Laura Abbott , Nick Desaulniers , Jann Horn , Miguel Ojeda , Masahiro Yamada , clang-built-linux , Kernel Hardening , linux-arm-kernel , LKML Content-Type: text/plain; charset="UTF-8" Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Fri, Oct 25, 2019 at 3:56 AM Mark Rutland wrote: > > +#define SCS_SIZE 1024 > > I think it'd be worth a comment on how this size was chosen. IIRC this > empirical? Correct. I'll add a comment. > > +#define SCS_END_MAGIC 0xaf0194819b1635f6UL > > Keyboard smash? ... or is there a prize for whoever figures out the > secret? ;) It's a random number, so if someone figures out a secret in it, they'll definitely deserve a prize. :) > > +static inline void task_set_scs(struct task_struct *tsk, void *s) > > +{ > > + task_thread_info(tsk)->shadow_call_stack = s; > > +} > > This should probably be named get and set, or have: > > #define task_scs(tsk) (task_thread_info(tsk)->shadow_call_stack) > > ... which can have a trivial implementation as NULL for the !SCS case. Sure, sounds good. > For all the trivial wrappers you can put the implementation on the same > line as the prototype. That makes it a bit easier to compare against the > prototypes on the other side of the ifdeffery. > > e.g. this lot can be: > > static inline void *task_scs(struct task_struct *tsk) { return 0; } > static inline void task_set_scs(struct task_struct *tsk, void *s) { } > static inline void scs_init(void) { } Agreed. > > diff --git a/kernel/fork.c b/kernel/fork.c > > index bcdf53125210..ae7ebe9f0586 100644 > > --- a/kernel/fork.c > > +++ b/kernel/fork.c > > @@ -94,6 +94,7 @@ > > #include > > #include > > #include > > +#include > > Nit: alphabetical order, please (this should come before stackleak.h). The includes in kernel/fork.c aren't in alphabetical order, so I just added this to the end here. > > + retval = scs_prepare(p, node); > > + if (retval) > > + goto bad_fork_cleanup_thread; > > Can we please fold scs_prepare() into scs_task_init() and do this in > dup_task_struct()? That way we set this up consistently in one place, > where we're also allocating the regular stack. Yes, that does sound cleaner. I'll change that. > > + scs_task_reset(idle); > > I'm a bit confused by this -- please see comments below on > scs_task_reset(). > > +static inline void *__scs_base(struct task_struct *tsk) > > +{ > > + return (void *)((uintptr_t)task_scs(tsk) & ~(SCS_SIZE - 1)); > > +} > > We only ever assign the base to task_scs(tsk), with the current live > value being in a register that we don't read. Are we expecting arch code > to keep this up-to-date with the register value? > > I would have expected that we just leave this as the base (as we do for > the regular stack in the task struct), and it's down to arch code to > save/restore the current value where necessary. > > Am I missing some caveat with that approach? To keep the address of the currently active shadow stack out of memory, the arm64 implementation clears this field when it loads x18 and saves the current value before a context switch. The generic code doesn't expect the arch code to necessarily do so, but does allow it. This requires us to use __scs_base() when accessing the base pointer and to reset it in idle tasks before they're reused, hence scs_task_reset(). > > + BUILD_BUG_ON(SCS_SIZE > PAGE_SIZE); > > It's probably worth a comment on why we rely on SCS_SIZE <= PAGE_SIZE. Ack. > > +static inline unsigned long *scs_magic(struct task_struct *tsk) > > +{ > > + return (unsigned long *)(__scs_base(tsk) + SCS_SIZE - sizeof(long)); > > Slightly simpler as: > > return (unsigned long *)(__scs_base(tsk) + SCS_SIZE) - 1; Yes, that's a bit cleaner. I'll fix these in v3. Thank you for the review! Sami