Received: by 2002:a05:6a10:6744:0:0:0:0 with SMTP id w4csp47212pxu; Tue, 6 Oct 2020 18:19:09 -0700 (PDT) X-Google-Smtp-Source: ABdhPJwlhbiMcCAiOiDfKVA4xyop1Z7oc+5g3CzAXPVZIYbvQs4v6iB8FZtxmYwC8Bt15v07y8o3 X-Received: by 2002:aa7:dd4b:: with SMTP id o11mr921334edw.251.1602033548847; Tue, 06 Oct 2020 18:19:08 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1602033548; cv=none; d=google.com; s=arc-20160816; b=tjpdaMudThk5bI0OqY12DRBpZQ78qfQiVjjGoKqhVmoxw3KyMIUDVHFDKqEGXbWpp4 kPohXD78Oln78wyjegMV4OGE5BO6fzOV7prTx/xlnK/MY54C/1buStkoFr8aVqsFqu/f BJHVoUDcm9Xjdi1JGwkh/bqDhX5sJ53iIpErubkU3QV4cHkGo6kvHApRFToGyyzXEv/2 Ta3ReTcD/j6hqDBQSFgMz4AmDcmQLSTHHG1CyTsdM2fQg2xfbaPa2KcADd/JCS/Q2rrb IbYo+mMflWgIVsgajgmqSmrx9Y64MIiIZ+iX1w0jWx8HUsZWtM09BbYgueBpDUV6JGvf AA9w== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:cc:to:subject:message-id:date:from:in-reply-to :references:mime-version:dkim-signature; bh=WTiyxcbY8Ljelc9eXf3vCo7Tcz+qObqxq0r/I8j+cAg=; b=IIljKEZMBgxIF7j3Fdnb2O0ReCAFj5TvCc3oD8YqWybTrinwtQnx5zELJYTz0RHCcZ 0qkEx3HotRhufpugMnKH6nPrMTkbUq0RESevsP9QkBaBAXLkEyJl1ivCjKdQXZj6JwGD 5W1gRmJBaNM707AQV8uRyMErkmnMCtyTCU2Q9pvAaCkGBP+6ye6EWhigIksuYLEv0vBp 0FXVUfyqKL4moSGY0zWWk7pnjK2GZX/sZJ5S8qBHTslAnZLfVtcic3kMKN23/Tnifepj jTbmo/YMhmVplaug7f71LsGiYPHF63VzunMsgyoMQ+81I48seVwAaFe25sbHEKIftf8E nLOg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b="IPIkDm/Y"; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id w16si372497ejn.471.2020.10.06.18.18.46; Tue, 06 Oct 2020 18:19:08 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b="IPIkDm/Y"; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726934AbgJGBQX (ORCPT + 99 others); Tue, 6 Oct 2020 21:16:23 -0400 Received: from mail.kernel.org ([198.145.29.99]:60718 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725996AbgJGBQX (ORCPT ); Tue, 6 Oct 2020 21:16:23 -0400 Received: from mail-wr1-f49.google.com (mail-wr1-f49.google.com [209.85.221.49]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id 15E7E207EA for ; Wed, 7 Oct 2020 01:16:22 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1602033382; bh=larqh/Ss0SS1K6WLUhcJSM7WQfj+/MkCFwSauHcYI30=; h=References:In-Reply-To:From:Date:Subject:To:Cc:From; b=IPIkDm/YmZl+Zli/+slyQg7Xb0SXOC8Pj+XOdIxNQRxIGPes77SessZzdxSbaa3w5 1GNMaqJZVzQduHpgZuY/2Hm4uincpHlUaaRgC8aPSVtZVOUudp52UYHBv808e5Gyi/ bbQ+TD1MhCttbMRD6aItBbPcvh4EE7qpvUcHpWqU= Received: by mail-wr1-f49.google.com with SMTP id t10so262665wrv.1 for ; Tue, 06 Oct 2020 18:16:22 -0700 (PDT) X-Gm-Message-State: AOAM530Y5q6AEc4u7+FhaXYuIFxrvb7Momw9fTsVtTH6TNal1BQ3yTo4 8Xl0cMK4eKs+QrzKoX+yHQ2/1rwthQCV60i2E7TAOQ== X-Received: by 2002:adf:a3c3:: with SMTP id m3mr616084wrb.70.1602033380467; Tue, 06 Oct 2020 18:16:20 -0700 (PDT) MIME-Version: 1.0 References: <4b3b4fbf8e9806840135e95cef142a0adefc3455.1601925251.git.luto@kernel.org> In-Reply-To: From: Andy Lutomirski Date: Tue, 6 Oct 2020 18:16:07 -0700 X-Gmail-Original-Message-ID: Message-ID: Subject: Re: [PATCH 1/2] x86/stackprotector/32: Make the canary into a regular percpu variable To: Brian Gerst Cc: Andy Lutomirski , "the arch/x86 maintainers" , LKML , "Christopherson, Sean J" Content-Type: text/plain; charset="UTF-8" Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Tue, Oct 6, 2020 at 10:14 AM Brian Gerst wrote: > > On Mon, Oct 5, 2020 at 3:31 PM Andy Lutomirski wrote: > > > > On 32-bit kernels, the stackprotector canary is quite nasty -- it is > > stored at %gs:(20), which is nasty because 32-bit kernels use %fs for > > percpu storage. It's even nastier because it means that whether %gs > > contains userspace state or kernel state while running kernel code > > sepends on whether stackprotector is enabled (this is > > CONFIG_X86_32_LAZY_GS), and this setting radically changes the way > > that segment selectors work. Supporting both variants is a > > maintenance and testing mess. > > > > Merely rearranging so that percpu and the stack canary > > share the same segment would be messy as the 32-bit percpu address > > layout isn't currently compatible with putting a variable at a fixed > > offset. > > > > Fortunately, GCC 8.1 added options that allow the stack canary to be > > accessed as %fs:stack_canary, effectively turning it into an ordinary > > percpu variable. This lets us get rid of all of the code to manage > > the stack canary GDT descriptor and the CONFIG_X86_32_LAZY_GS mess. > > > > This patch forcibly disables stackprotector on older compilers that > > don't support the new options and makes the stack canary into a > > percpu variable. > > This doesn't consider !SMP builds, where per-cpu variable are just > normal variables, and the FS segment is disabled. Unfortunately, > -mstack-protector-guard-reg=ds is not accepted. The simplest fix > would be to define __KERNEL_PERCPU when either SMP or STACKPROTECTOR > are enabled. I don't love this because it breaks the "stack canary is just a regular PERCPU variable" idea. GCC accepts -mstack-protector-guard=global to get rid of the segment override, but then it ignores -mstack-protector-guard-offset=stack_canary. So I could do this: #ifdef CONFIG_SMP EXPORT_PER_CPU_SYMBOL(stack_canary); #else /* * GCC can't use a symbol called 'stack_canary' as the stack canary with * an FS or GS segment override, and SMP=n percpu variables are just normal * variables. But GCC can use '__stack_chk_guard'. */ extern unsigned long __attribute__((alias("stack_canary"))) __stack_chk_guard; EXPORT_SYMBOL(__stack_chk_guard); #endif Or I suppose I could just rename the thing __stack_chk_guard. The only downside of the latter seems to be that an accidental mix of SMP and !SMP object files (or modules!) would crash, but I suppose they likely crash anyway.