From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on inbox.vuxu.org X-Spam-Level: X-Spam-Status: No, score=-1.4 required=5.0 tests=HEADER_FROM_DIFFERENT_DOMAINS, MAILING_LIST_MULTI,RCVD_IN_DNSWL_MED,T_SCC_BODY_TEXT_LINE,URIBL_BLACK autolearn=ham autolearn_force=no version=3.4.4 Received: from second.openwall.net (second.openwall.net [193.110.157.125]) by inbox.vuxu.org (Postfix) with SMTP id 4D22F250A9 for ; Wed, 14 Feb 2024 03:19:22 +0100 (CET) Received: (qmail 26585 invoked by uid 550); 14 Feb 2024 02:16:19 -0000 Mailing-List: contact musl-help@lists.openwall.com; run by ezmlm Precedence: bulk List-Post: List-Help: List-Unsubscribe: List-Subscribe: List-ID: Reply-To: musl@lists.openwall.com Received: (qmail 26550 invoked from network); 14 Feb 2024 02:16:19 -0000 Date: Tue, 13 Feb 2024 21:19:25 -0500 From: Rich Felker To: Markus Wichmann Cc: musl@lists.openwall.com, enh Message-ID: <20240214021925.GC4163@brightrain.aerifal.cx> References: <20240212184236.GZ4163@brightrain.aerifal.cx> <20240212224657.GA4163@brightrain.aerifal.cx> <20240213020834.GB4163@brightrain.aerifal.cx> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.5.21 (2010-09-15) Subject: Re: [musl] PAC/BTI Support on aarch64 On Tue, Feb 13, 2024 at 06:51:47PM +0100, Markus Wichmann wrote: > Am Tue, Feb 13, 2024 at 08:47:42AM -0600 schrieb William Roberts: > > It should. Is there a known minimal tool chain requirement and I can test? > > Typically the first C99 compiler or the first aarch64 compiler, > whichever is younger. I think binutils is the relevant component, and that'd be whichever version of binutils added aarch64. > > No, anywhere branches are allowed, a BTI instruction must be the first > > instruction. BTI is just a way for software to say, hey this is a > > valid jump/branch > > target, allow it. This reduces the amount of gadgets available to an > > attacker, which > > is why libc is such a juicy target, as it's in everything. A lot of > > things static link it, > > which effectively turns it off for the whole process. > > > > So this means there must be a BTI instruction following every single BL > instruction. > > But in the end this isn't that much different from endbr64 on the PC. > Whatever happened to those patches, BTW? What is the situation on x86? Does it use the same kind of per-page enforcement mode, or is it only global, requiring disabling it if any DSO lacks support? Is the endbr64 opcode a guaranteed-safe nop on older ISA levels, or does it need to be conditional? > > Yes, so the kernel will manage the EL1 register flag for this, and then > > mprotect sets the PROT_BTI flag during dlopen(). > > Well, this is a novelty. This is the first time there will be an > arch-specific flag in mmap()/mprotect() for the musl dynlinker. So far > that code has been entirely portable. Can the flag be used at mmap time, or only in mprotect? It would be a lot more efficient to do it as part of the mmap, but getting visibility to the note to know you need it at mmap time seems difficult and more costly than doing the mprotect later... I assume we would either add the code conditional on the existence of a PROT_BTI macro (#ifdef) and define that to the corresponding thing on other archs in the future, or abstract it with a new name in arch/$ARCH/reloc.h defined in terms of whatever the arch provides so as to be a little bit more naming-agnostic. It should not be #ifdef __aarch64__ or similar. > > It's important to note, that even when enabling the assembly code files, if the > > C level source is not built with -mbranch-protection=standard, the feature will > > remain off for the library. > > > > Arch-specific compiler flags are not a problem; configure.sh can add > those as needed. Yep, that's fine. Possibly a question of whether it should be on by default or configurable, but if there's essentially no cost, on-by-default seems fine. > > I can't think of anything like this offhand, but aarches may want to add prot > > flags to mprotect calls. > > That hasn't happened yet. Of course, this may be as simple as adding a > static inline function. The fact that the important information is in a > note section is yet another novelty, of course. So far, the important > information (even arch-specific) has been contained in the dynamic > section. Yes, that's gratuitously annoying. Ideally it would have been somewhere easily accessible from the Ehdr so it's available at initial mmap time... :/ > > it usually > > #ifdef aarch64 > > if (gnu_notes_bti_set && (prot & PROT_EXEC)) { > > prot |= PROT_BTI; > > else { > > prot &= ~PROT_BTI; > > } > > #endif > > > > mprotect(..., prot); > > > > So far we have managed to steer clear of conditional inclusion, and I > think we should try to keep it that way. Yes. I think reloc.h should define a predicate macro (which may call a static inline function if the predicate is complex) to check if a DSO needs branch protection on its PROT_EXEC segments. src/internal/dynlink.h could provide a default always-false one if it's not defined. Then dynlink.c can just, when that predicate evaluates true, loop thru the segments and mprotect any PROT_EXEC ones to also have PROT_BTI or whatever. This remains very arch-agnostic and the code should be either directly usable on other archs, or admit easy generalization if needed. Rich