Received: by 2002:ac0:a594:0:0:0:0:0 with SMTP id m20-v6csp981727imm; Fri, 11 May 2018 09:14:55 -0700 (PDT) X-Google-Smtp-Source: AB8JxZrgMOO8mjJFzXc33eTuLLLS/uCvqgcL4TdWtcEN0IHw5fC8aXCRI4jj9JR5E+O6uaaEEGf7 X-Received: by 2002:a63:5f56:: with SMTP id t83-v6mr4822695pgb.200.1526055295724; Fri, 11 May 2018 09:14:55 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1526055295; cv=none; d=google.com; s=arc-20160816; b=h9Br/mYm64QHru217i3ihG7H8MEk8oLCNJ/9tVPdytbn0Ld9Dmr4g6yNuTISWpQtAL pxsK0aagrIUIgxm/qE2HTxLY5VNo9DTX+P+6Eqa8JF+dX0HWZTQZ+7VqtczbrzRLpU1M o9r+LlwBeaCQw5uB9c8ztTaEfC18pY4/Y0pvwu8PEx1Z1Pzq2AtJ0pmg2Y37ceW4ALiG 5PbRObXa5L0jXrZR+BP/Di/AwoeMDXMxAvNeGYcCMGKBPhtdo+RWvLhhqwBAWlCprMzj q1mkdAwV9ezIbEVVtrHHN0qIgW26uFSSjFMaM8h+bf2oCF06wWTo+5YashZaysNrx5SJ //pw== 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:arc-authentication-results; bh=i815HHmvDb4hNIXfKq6y1hB1waeb6iUu2ojKYxtpjvo=; b=gum49WvGR0YJnJVk/I3Gw98TF7S4J6MNyBmjmQw4/Jy3OE4k9/w2JgiNvRD4cftB4J 8w29CFYp2TW+LI8HzZsh6k8KfA12Q/8o7LAolaDkEoYKaBeR7Zlpe2vdaNNHeWnnp3Gs 2f6sv9xkXct0JASr0Spw2qpL07elB8esZF6oOgRMLsQafyyIQAZxoah5ne4SXsD+r13z fzLmWj4UZWHWKlgUR8cFX8S3ecqgtcEdxspKe/GtIPBLiY5N64lQmQEUkD4SMmEquO7M 9otMVERyq04kJPFg5TSBAsMXSMrRkEMOuO4KK7pZvp3CGEw0xk6jdkkx7NY9vLOHCa3f FrBg== 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 v10-v6si3654107plz.190.2018.05.11.09.14.41; Fri, 11 May 2018 09:14:55 -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 S1751717AbeEKQN1 (ORCPT + 99 others); Fri, 11 May 2018 12:13:27 -0400 Received: from usa-sjc-mx-foss1.foss.arm.com ([217.140.101.70]:44040 "EHLO foss.arm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751096AbeEKQN0 (ORCPT ); Fri, 11 May 2018 12:13:26 -0400 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.72.51.249]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id BDC1B1435; Fri, 11 May 2018 09:13:25 -0700 (PDT) Received: from lakrids.cambridge.arm.com (usa-sjc-imap-foss1.foss.arm.com [10.72.51.249]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 45A793F53D; Fri, 11 May 2018 09:13:24 -0700 (PDT) Date: Fri, 11 May 2018 17:13:18 +0100 From: Mark Rutland To: Alexander Popov Cc: Andy Lutomirski , Laura Abbott , Kees Cook , Ard Biesheuvel , kernel-hardening@lists.openwall.com, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org Subject: Re: [PATCH 2/2] arm64: Clear the stack Message-ID: <20180511161317.57k6prl54xjmsit3@lakrids.cambridge.arm.com> References: <20180502203326.9491-1-labbott@redhat.com> <20180502203326.9491-3-labbott@redhat.com> <20180503071917.xm2xvgagvzkworay@salmiak> <20180504110907.c2dw33kjmyybso6t@lakrids.cambridge.arm.com> <4badae50-be9b-2c6d-854b-57ab48664800@linux.com> <71199506-b46b-5f91-e489-e6450b6d1067@linux.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <71199506-b46b-5f91-e489-e6450b6d1067@linux.com> User-Agent: NeoMutt/20170113 (1.7.2) Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Fri, May 11, 2018 at 06:50:09PM +0300, Alexander Popov wrote: > Hello everyone, > > On 06.05.2018 11:22, Alexander Popov wrote: > > On 04.05.2018 14:09, Mark Rutland wrote: > >>>>> + stack_left = sp & (THREAD_SIZE - 1); > >>>>> + BUG_ON(stack_left < 256 || size >= stack_left - 256); > >>>> > >>>> Is this arbitrary, or is there something special about 256? > >>>> > >>>> Even if this is arbitrary, can we give it some mnemonic? > >>> > >>> It's just a reasonable number. We can introduce a macro for it. > >> > >> I'm just not sure I see the point in the offset, given things like > >> VMAP_STACK exist. BUG_ON() handling will likely require *more* than 256 > >> bytes of stack, so it seems superfluous, as we'd be relying on stack > >> overflow detection at that point. > >> > >> I can see that we should take the CONFIG_SCHED_STACK_END_CHECK offset > >> into account, though. > > > > Mark, thank you for such an important remark! > > > > In Kconfig STACKLEAK implies but doesn't depend on VMAP_STACK. In fact x86_32 > > doesn't have VMAP_STACK at all but can have STACKLEAK. > > > > [Adding Andy Lutomirski] > > > > I've made some additional experiments: I exhaust the thread stack to have only > > (MIN_STACK_LEFT - 1) bytes left and then force alloca. If VMAP_STACK is > > disabled, BUG_ON() handling causes stack depth overflow, which is detected by > > SCHED_STACK_END_CHECK. If VMAP_STACK is enabled, the kernel hangs on BUG_ON() > > handling! Enabling CONFIG_PROVE_LOCKING gives the needed report from VMAP_STACK: I can't see why CONFIG_VMAP_STACK would only work in conjunction with CONFIG_PROVE_LOCKING. On arm64 at least, if we overflow the stack while handling a BUG(), we *should* trigger the overflow handler as usual, and that should work, unless I'm missing something. Maybe it gets part-way into panic(), sets up some state, stack-overflows, and we get wedged because we're already in a panic? Perhaps CONFIG_PROVE_LOCKING causes more stack to be used, so it dies a little earlier in panic(), before setting up some state that causes wedging. ... which sounds like something best fixed in those code paths, and not here. > [...] > > > I can't say why VMAP_STACK report hangs during BUG_ON() handling on defconfig. > > Andy, can you give a clue? > > > > I see that MIN_STACK_LEFT = 2048 is enough for BUG_ON() handling on both x86_64 > > and x86_32. So I'm going to: > > - set MIN_STACK_LEFT to 2048; > > - improve the lkdtm test to cover this case. > > > > Mark, Kees, Laura, does it sound good? > > > Could you have a look at the following changes in check_alloca() before I send > the next version? > > If VMAP_STACK is enabled and alloca causes stack depth overflow, I write to > guard page below the thread stack to cause double fault and VMAP_STACK report. On arm64 at least, writing to the guard page will not itself trigger a stack overflow, but will trigger a data abort. I suspect similar is true on x86, if the stack pointer is sufficiently far above the guard page. > If VMAP_STACK is disabled, I use MIN_STACK_LEFT = 2048, which seems to be enough > for BUG_ON() handling both on x86_32 and x86_64. Unfortunately, I can't > guarantee that it is always enough. I don't think that we can choose something that's guaranteed to be sufficient for BUG() handling and also not wasting a tonne of space under normal operation. Let's figure out what's going wrong on x86 in the case that you mention, and try to solve that. Here I don't think we should reserve space at all -- it's completely arbitrary, and as above we can't guarantee that it's sufficient anyway. > #ifdef CONFIG_GCC_PLUGIN_STACKLEAK > -#define MIN_STACK_LEFT 256 > +#define MIN_STACK_LEFT 2048 > > void __used check_alloca(unsigned long size) > { > unsigned long sp = (unsigned long)&sp; > struct stack_info stack_info = {0}; > unsigned long visit_mask = 0; > unsigned long stack_left; > > BUG_ON(get_stack_info(&sp, current, &stack_info, &visit_mask)); > > stack_left = sp - (unsigned long)stack_info.begin; > + > +#ifdef CONFIG_VMAP_STACK > + /* > + * If alloca oversteps the thread stack boundary, we touch the guard > + * page provided by VMAP_STACK to trigger handle_stack_overflow(). > + */ > + if (size >= stack_left) > + *(stack_info.begin - 1) = 42; > +#else On arm64, this won't trigger our stack overflow handler, unless the SP is already very close to the boundary. Please just use BUG(). If there is an issue on x86, it would be good to solve that in the x86 code. > BUG_ON(stack_left < MIN_STACK_LEFT || > size >= stack_left - MIN_STACK_LEFT); I really don't think we should bother with this arbitrary offset at all. Thanks, Mark.