Received: by 2002:a25:ad19:0:0:0:0:0 with SMTP id y25csp9451073ybi; Wed, 24 Jul 2019 04:22:02 -0700 (PDT) X-Google-Smtp-Source: APXvYqytsvdt3mfNru7f1Mi7jKZgIwDCq6U9ulpQV70nKDmyzQaK8wusFEHrU+GXF4Bz2y83hBm3 X-Received: by 2002:a17:902:1566:: with SMTP id b35mr87562102plh.147.1563967322382; Wed, 24 Jul 2019 04:22:02 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1563967322; cv=none; d=google.com; s=arc-20160816; b=QsqRUfLk7D+rtqqe/ZlRuMf04dStRoyvl59JZW3dnLXm3XgPDIkYDwoaoAhQBdCv+L 0rSCLtDAYnN2LgbpsoVFswB7x3nBrWTU1bOsk7lDqTUWmJ2RO4Q+dwZ9ypvklhFu417a EFs6ihGJRcQqiJXSzEmgJaz5oh2GKjqvaaF50gV4C+MZiy5RQMz9X8/tpNTgp6sRncI0 7R7QzO7DN4zw365EIHmEgUdWXqQvH+v5YtRIgCoMdeUrck5gQ8ZS74KZujGYbSg8A3c3 xBz+BDsX/q1+FNRLcgVISTbMA8FLGzNl6LdF08fH0l424CJ6eIZqYecZ9ZrCFe9poY7Y DDMg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:user-agent:in-reply-to :content-disposition:mime-version:references:message-id:subject:cc :to:from:date; bh=QHQJUaZZkzs4yscjNg3LzVbbsFpMOM8JY+junwLUnQ0=; b=LhvYkYXZW6+4IKi4k0ZFfZB4JK/w/M6UDhFZYCZ9eavv2Pu6XznKHLIbSdDf4jtSua 0yw1DN3qpD9m1xgNxCW5JD3QZtS2BwCcsCcjrF4/UOvIy1Hmo0aDbnAd7m9Ee6e2w/X2 na8KGJKx+Qha1ffWPtO/3WmMXKBSS51W96wI/IWt7ekGgkP9omUbIhPK0tDsZZHtE+Sb VBaLnesgD6YFd7SYT8C3amH5Jqwf8s/lzrk4q6fWTXTOvcQULUmuYgzhGihfa3lbj2lu 8fkbV5gR85PCerXgMZLWb2US/Grn4ey4PITAw/exvDu1bJV0i6dvRjfQDqH3/vmrblmW IMIg== ARC-Authentication-Results: i=1; mx.google.com; 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 Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id v184si13083255pgd.278.2019.07.24.04.21.47; Wed, 24 Jul 2019 04:22:02 -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; 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 Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727365AbfGXLVG (ORCPT + 99 others); Wed, 24 Jul 2019 07:21:06 -0400 Received: from foss.arm.com ([217.140.110.172]:39328 "EHLO foss.arm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727267AbfGXLVG (ORCPT ); Wed, 24 Jul 2019 07:21:06 -0400 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id E4E2B1509; Wed, 24 Jul 2019 04:21:05 -0700 (PDT) Received: from lakrids.cambridge.arm.com (usa-sjc-imap-foss1.foss.arm.com [10.121.207.14]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 3F4013F71A; Wed, 24 Jul 2019 04:21:04 -0700 (PDT) Date: Wed, 24 Jul 2019 12:21:02 +0100 From: Mark Rutland To: Dmitry Vyukov Cc: Marco Elver , LKML , Thomas Gleixner , Ingo Molnar , Borislav Petkov , "H. Peter Anvin" , Andrey Ryabinin , Alexander Potapenko , Andrey Konovalov , Peter Zijlstra , the arch/x86 maintainers , kasan-dev Subject: Re: [PATCH 1/2] kernel/fork: Add support for stack-end guard page Message-ID: <20190724112101.GB2624@lakrids.cambridge.arm.com> References: <20190719132818.40258-1-elver@google.com> <20190723164115.GB56959@lakrids.cambridge.arm.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.11.1+11 (2f07cb52) (2018-12-01) Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Wed, Jul 24, 2019 at 11:11:49AM +0200, Dmitry Vyukov wrote: > On Tue, Jul 23, 2019 at 6:41 PM Mark Rutland wrote: > > > > On Fri, Jul 19, 2019 at 03:28:17PM +0200, Marco Elver wrote: > > > Enabling STACK_GUARD_PAGE helps catching kernel stack overflows immediately > > > rather than causing difficult-to-diagnose corruption. Note that, unlike > > > virtually-mapped kernel stacks, this will effectively waste an entire page of > > > memory; however, this feature may provide extra protection in cases that cannot > > > use virtually-mapped kernel stacks, at the cost of a page. > > > > > > The motivation for this patch is that KASAN cannot use virtually-mapped kernel > > > stacks to detect stack overflows. An alternative would be implementing support > > > for vmapped stacks in KASAN, but would add significant extra complexity. > > > > Do we have an idea as to how much additional complexity? > > We would need to map/unmap shadow for vmalloc region on stack > allocation/deallocation. We may need to track shadow pages that cover > both stack and an unused memory, or 2 different stacks, which are > mapped/unmapped at different times. This may have some concurrency > concerns. Not sure what about page tables for other CPU, I've seen > some code that updates pages tables for vmalloc region lazily on page > faults. Not sure what about TLBs. Probably also some problems that I > can't thought about now. Ok. So this looks big, we this hasn't been prototyped, so we don't have a concrete idea. I agree that concurrency is likely to be painful. :) [...] > > > diff --git a/arch/x86/include/asm/page_64_types.h b/arch/x86/include/asm/page_64_types.h > > > index 288b065955b7..b218b5713c02 100644 > > > --- a/arch/x86/include/asm/page_64_types.h > > > +++ b/arch/x86/include/asm/page_64_types.h > > > @@ -12,8 +12,14 @@ > > > #define KASAN_STACK_ORDER 0 > > > #endif > > > > > > +#ifdef CONFIG_STACK_GUARD_PAGE > > > +#define STACK_GUARD_SIZE PAGE_SIZE > > > +#else > > > +#define STACK_GUARD_SIZE 0 > > > +#endif > > > + > > > #define THREAD_SIZE_ORDER (2 + KASAN_STACK_ORDER) > > > -#define THREAD_SIZE (PAGE_SIZE << THREAD_SIZE_ORDER) > > > +#define THREAD_SIZE ((PAGE_SIZE << THREAD_SIZE_ORDER) - STACK_GUARD_SIZE) > > > > I'm pretty sure that common code relies on THREAD_SIZE being a > > power-of-two. I also know that if we wanted to enable this on arm64 that > > would very likely be a requirement. > > > > For example, in kernel/trace/trace_stack.c we have: > > > > | this_size = ((unsigned long)stack) & (THREAD_SIZE-1); > > > > ... and INIT_TASK_DATA() allocates the initial task stack using > > THREAD_SIZE, so that may require special care, as it might not be sized > > or aligned as you expect. > > We've built it, booted it, stressed it, everything looked fine... that > should have been a build failure. I think it's been an implicit assumption for so long that no-one saw the need for built-time assertions where they depend on it. I also suspect that in practice there are paths that you won't have stressed in your environment, e.g. in the ACPI wakeup path where we end up calling: /* Unpoison the stack for the current task beyond a watermark sp value. */ asmlinkage void kasan_unpoison_task_stack_below(const void *watermark) { /* * Calculate the task stack base address. Avoid using 'current' * because this function is called by early resume code which hasn't * yet set up the percpu register (%gs). */ void *base = (void *)((unsigned long)watermark & ~(THREAD_SIZE - 1)); kasan_unpoison_shadow(base, watermark - base); } > Is it a property that we need to preserve? Or we could fix the uses > that assume power-of-2? Generally, I think that those can be fixed up. Someone just needs to dig through how THREAD_SIZE and THREAD_SIZE_ORDER are used to generate or manipulate addresses. For local-task stuff, I think it's easy to rewrite in terms of task_stack_page(), but I'm not entirely sure what we'd do for cases where we look at another task, e.g. static int proc_stack_depth(struct seq_file *m, struct pid_namespace *ns, struct pid *pid, struct task_struct *task) { unsigned long prev_depth = THREAD_SIZE - (task->prev_lowest_stack & (THREAD_SIZE - 1)); unsigned long depth = THREAD_SIZE - (task->lowest_stack & (THREAD_SIZE - 1)); seq_printf(m, "previous stack depth: %lu\nstack depth: %lu\n", prev_depth, depth); return 0; } ... as I'm not sure of the lifetime of task->stack relative to task. I know that with THREAD_INFO_IN_TASK the stack can be freed while the task is still live. Thanks, Mark.