From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from casper.infradead.org (casper.infradead.org [90.155.50.34]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 85C83158520 for ; Fri, 29 Nov 2024 12:52:41 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=90.155.50.34 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1732884763; cv=none; b=PxfDmvTHRoWWlpSy0W8xJAAKNV5uZWXdt+RSqMHD1t+soAyBemq3WVM232nkETQ7yRhatwhDnHmoJJKACZXmsmJNfM+0l7SGWMjRBcV6bwcfZCpp2UEmM/QwqzqTUeCrmDuQU8t5153/7G/ckcN5Q8bdmF1Cxj9C3eYk8HwSXf8= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1732884763; c=relaxed/simple; bh=7g4xY9WlgkLviDGu83CxLhZQcZxK55b2b6651Ky9PNw=; h=Date:From:To:Cc:Subject:Message-ID:References:MIME-Version: Content-Type:Content-Disposition:In-Reply-To; b=EzLfpGJ/6uNrhFybHlx4QS0d6DHQKfdxq21yLz2PG6eKSSwLVwLESjLjZ1IECh3GqxNp5PcigCD70yLf5zJBcmEoRTFnwCWHIYjTUKETx3vdunIDB+7CnXdi7cTFdxkx0PsbdTMikSHTXu3qeYX9FDnG1s1r90EGY7Gp3JCPO2g= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=infradead.org; spf=none smtp.mailfrom=infradead.org; dkim=pass (2048-bit key) header.d=infradead.org header.i=@infradead.org header.b=JvrHoPiZ; arc=none smtp.client-ip=90.155.50.34 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=infradead.org Authentication-Results: smtp.subspace.kernel.org; spf=none smtp.mailfrom=infradead.org Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=infradead.org header.i=@infradead.org header.b="JvrHoPiZ" DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=casper.20170209; h=In-Reply-To:Content-Type:MIME-Version: References:Message-ID:Subject:Cc:To:From:Date:Sender:Reply-To: Content-Transfer-Encoding:Content-ID:Content-Description; bh=73QdvqWCembaH7+L7IbabYGc2vdehmRPH2zGdyoFrlM=; b=JvrHoPiZ0EunD7AsrEPo9IzYzE OXSGAqSOIho4ScbKSx5e8+68G1ho60YH5mt85MLx6Ya7CqepWA9Gf6h4pjlsH4OzY8ytutM8Opp/z SI3bopVBrdxQ6cOp1x4EDVzXIKTwDzvMbDPgibWrsM1R46IK38Ko9nCCGwlgJVFjhBnfgg1GeXCdR TQhMkXLcD8BdRr1dXlgLfOu8QzOLDHMg2nZHc8hKE7A3uEiXkSkHn8gmMb7GHEVXJ0UrKvDu2kixK evegvNW1kpk1dTpMhyyGQXu77EqA+2T8Ssj7x6s64V3RcRlkZ7JKwki0/I5T0SCMeEhKlsJ42yw35 qcV+iihw==; Received: from 77-249-17-89.cable.dynamic.v4.ziggo.nl ([77.249.17.89] helo=noisy.programming.kicks-ass.net) by casper.infradead.org with esmtpsa (Exim 4.98 #2 (Red Hat Linux)) id 1tH0U9-000000041pg-2Gd9; Fri, 29 Nov 2024 12:52:38 +0000 Received: by noisy.programming.kicks-ass.net (Postfix, from userid 1000) id 434D930026A; Fri, 29 Nov 2024 13:52:38 +0100 (CET) Date: Fri, 29 Nov 2024 13:52:38 +0100 From: Peter Zijlstra To: Jakub Jelinek Cc: linux-toolchains@vger.kernel.org, Linus Torvalds , x86@kernel.org Subject: Re: GCC 15 -fzero-init-padding-bits= option and redzone clobber Message-ID: <20241129125238.GI24400@noisy.programming.kicks-ass.net> References: Precedence: bulk X-Mailing-List: linux-toolchains@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: On Thu, Nov 28, 2024 at 12:19:10PM +0100, Jakub Jelinek wrote: > Hi! > > This is just a FYI, since today GCC 15 no longer zero initializes padding > bits in unions where the standard doesn't require it. > So e.g. > void foo (void) > { > union U { int a; long b[64]; }; > /* This clears everything including padding bits, > required by at least C23 (note, GCC 15 defaults to -std=gnu23) */ > union U u = {}; > /* This used to clear everything, but only clears > v.a in GCC 15 by default. */ > union U v = {0}; > } > If you want to keep the old behavior e.g. for security purposes (the whole > union can be copied to user etc.), one can use > -fzero-init-padding-bits=unions to restore the GCC 14 and older behavior. > And, -fzero-init-padding-bits=all can be used to clear padding bits even > in cases where the standard doesn't require them even in structures, e.g. > void bar (void) > { > struct S { char a; int b; }; > /* C23 requires padding bits to be cleared here. */ > struct S s = {}; > /* But not here. -fzero-init-padding-bits=all does that anyway. */ > struct S t = { 1, 2 }; > } > Note, there is also __builtin_clear_padding builtin to clear padding bits > already since GCC 11, though it doesn't clear bits in unions unless they > are padding bits for all possible members, as it doesn't know which union > member is current. *groan* I suppose we should enable that flag when present :/ > Another new feature since today that might be relevant to kernel is > the "redzone" inline asm clobber. > It can/should be used on inline asm which does or could clobber memory > below the stack pointer and so its presence must disable use of redzone > (currently on x86_64 and powerpc*), At least on x86_64 we don't currently have a redzone. I'm assuming the "memory" clobber still very much includes everything? And why was it deemed okay to change behaviour that might break existing code? > whether because say pushf/pop pair > or because the inline asm performs calls without taking into account > the red zone (e.g. on x86_64 that would be something like subtracting > 128 from %rsp at the start and restoring at the end). > In the past I think kernel used some hacks like clobbering rsp, that is > something that really shouldn't be used even if it happened to work, > inline asm is of course allowed to change the stack pointer temporarily, > but before returning (if it returns at all) it needs to restore it back, > and clobbers are not about temporary changes during the execution of inline > asm, but about changes from the start to the end of inline asm. Mostly we call a full C function on another stack, I don't think we ever swizzle the stack while inside a C function. > So > asm ("call something" : ... : ... : "redzone"); > (of course it likely needs tons of other clobbers for call clobbered > registers unless it saves them and restores them in the inline asm or > in whatever it calls). We have this thing: /* * This output constraint should be used for any inline asm which has a "call" * instruction. Otherwise the asm may be inserted before the frame pointer * gets set up by the containing function. If you forget to do this, objtool * may print a "call without frame pointer save/setup" warning. */ register unsigned long current_stack_pointer asm(_ASM_SP); #define ASM_CALL_CONSTRAINT "+r" (current_stack_pointer) which we use a *LOT*.