[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [PATCH v2 07/70] x86: Build check for embedded endbr64 instructions


  • To: Andrew Cooper <amc96@xxxxxxxx>, Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
  • From: Jan Beulich <jbeulich@xxxxxxxx>
  • Date: Wed, 16 Feb 2022 09:41:44 +0100
  • Arc-authentication-results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=suse.com; dmarc=pass action=none header.from=suse.com; dkim=pass header.d=suse.com; arc=none
  • Arc-message-signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=Alk9KMejPJ+5ydPZltrpBZ3oRaO32Id6ixGtBB0nXbU=; b=YQWwi3LY91YvKXF4MkfotNccA32etA85midRNUHGJP27RUF7O+JOTop/YhMGTDTxSmhqotp+k73yrQ3QA0QyAiGCBefXiIy5aZU9uYGL/yD3VWhFeTgpr/sLXa28zp4iuBCWyuwRrjNetoBP3V/S5fUhdjQMC+7cg8iO9vv67PeShwr5NEWsaGad/BdQu8BeI9AwjJZRgcdtke6ysLFdvLp2uLACtYQK5cUkmtrM/klPLTBaUmlG9enYQGdpTojS+WgfsK4Qiu4XtqBLqq88cMcQamy7jLaAa3Oi64mI3gvVCAdXfYCAadGLk1lcHg5N6fDvX6amzDnExreMK4GByQ==
  • Arc-seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=fA1wyMFb7YHy2hihRgLHS/tZW5/Maim9PfZAJgT/cA7Atv+oBxiG04H/tbgz0WfvI2ueEObgdnCxe1ce/HgibAy2Ok236Zqb8YKIKf30dndOgyVeovf2TlKX2j42r9V34U4++rPbHJU0OZz33Z/DoQpS+FA5Wu68qzmSioztfJgdG0iN0hQHiLwt3wMxZmI13jQ/uGDQHHak1LwxerTxUsmIL68lqvFxq5gTKveEouLqL0aZnBx8X2C1cDtHI7sgVj3h/M47nlFSMnUZRSCALH27qs5ahf0ojBtDpAMwRHVHIjeI/FCHhV2AByJ3lTIP/sEc+IqzKdlp9sIyS9BKFw==
  • Authentication-results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=suse.com;
  • Cc: Xen-devel <xen-devel@xxxxxxxxxxxxxxxxxxxx>, Marek Marczykowski-Górecki <marmarek@xxxxxxxxxxxxxxxxxxxxxx>
  • Delivery-date: Wed, 16 Feb 2022 08:42:09 +0000
  • List-id: Xen developer discussion <xen-devel.lists.xenproject.org>

On 15.02.2022 18:52, Andrew Cooper wrote:
> On 15/02/2022 15:12, Jan Beulich wrote:
>> On 14.02.2022 13:50, Andrew Cooper wrote:
>>> --- /dev/null
>>> +++ b/xen/tools/check-endbr.sh
>>> @@ -0,0 +1,76 @@
>>> +#!/bin/sh
>>> +
>>> +#
>>> +# Usage ./$0 xen-syms
>>> +#
>>> +
>>> +set -e
>>> +
>>> +OBJCOPY="${OBJCOPY:-objcopy} -j .text $1"
>>> +OBJDUMP="${OBJDUMP:-objdump} -j .text $1"
>>> +
>>> +D=$(mktemp -d)
>>> +trap "rm -rf $D" EXIT
>>> +
>>> +TEXT_BIN=$D/xen-syms.text
>>> +VALID=$D/valid-addrs
>>> +ALL=$D/all-addrs
>>> +BAD=$D/bad-addrs
>>> +
>>> +#
>>> +# First, look for all the valid endbr64 instructions.
>>> +# A worst-case disassembly, viewed through cat -A, may look like:
>>> +#
>>> +# ffff82d040337bd4 <endbr64>:$
>>> +# ffff82d040337bd4:^If3 0f 1e fa          ^Iendbr64 $
>>> +# ffff82d040337bd8:^Ieb fe                ^Ijmp    ffff82d040337bd8 
>>> <endbr64+0x4>$
>>> +# ffff82d040337bda:^Ib8 f3 0f 1e fa       ^Imov    $0xfa1e0ff3,%eax$
>>> +#
>>> +# Want to grab the address of endbr64 instructions only, ignoring function
>>> +# names/jump labels/etc, so look for 'endbr64' preceeded by a tab and with 
>>> any
>>> +# number of trailing spaces before the end of the line.
>>> +#
>>> +${OBJDUMP} -d | grep '     endbr64 *$' | cut -f 1 -d ':' > $VALID &
>> Since you look at only .text the risk of the disassembler coming
>> out of sync with the actual instruction stream is lower than when
>> 32- and 16-bit code was also part of what is disassembled, but it's
>> not zero.
> 
> I'm not sure that we have any interesting non-64bit code at all in .text.
> 
> _start is technically 32bit but is mode-invariant as far as decoding goes.
> 
> The kexec trampoline is here too, but when I dust off my cleanup patch,
> there will no longer be data or mode-dependent things to disassemble.
> 
> Everything else I can think of is in .init.text.
> 
>> Any zero-padding inserted anywhere by the linker can
>> result in an immediately following ENDBR to be missed (because
>> sequences of zeros resemble 2-byte insns).
> 
> I'm not sure this is a problem.  This pass is looking for everything
> that objdump thinks is a legal endbr64 instruction, and it splits at labels.

Oh, right - I did miss the splitting at labels aspect. Hopefully
objdump is really consistent with this.

> Only the hand-written stubs can legitimately have an endbr64 without a
> symbol pointing at it.
> 
> We also don't have any 0 padding.  It's specified as 0x90 in the linker
> file, although I've been debating switching this to 0xcc for a while now
> already.

The linker script comes into play only in the final linking step.
Prior "ld -r" could easily have inserted other padding.

>>> +#
>>> +# Second, look for any endbr64 byte sequence
>>> +# This has a couple of complications:
>>> +#
>>> +# 1) Grep binary search isn't VMA aware.  Copy .text out as binary, causing
>>> +#    the grep offset to be from the start of .text.
>>> +#
>>> +# 2) AWK can't add 64bit integers, because internally all numbers are 
>>> doubles.
>>> +#    When the upper bits are set, the exponents worth of precision is lost 
>>> in
>>> +#    the lower bits, rounding integers to the nearest 4k.
>>> +#
>>> +#    Instead, use the fact that Xen's .text is within a 1G aligned region, 
>>> and
>>> +#    split the VMA in half so AWK's numeric addition is only working on 32 
>>> bit
>>> +#    numbers, which don't lose precision.
>>> +#
>>> +eval $(${OBJDUMP} -h | awk '$2 == ".text" {printf 
>>> "vma_hi=%s\nvma_lo=%s\n", substr($4, 1, 8), substr($4, 9, 16)}')
>>> +
>>> +${OBJCOPY} -O binary $TEXT_BIN
>>> +grep -aob "$(printf '\363\17\36\372')" $TEXT_BIN |
>>> +    awk -F':' '{printf "%s%x\n", "'$vma_hi'", strtonum(0x'$vma_lo') + $1}' 
>>> > $ALL
>> None of the three options passed to grep look to be standardized.
>> Is this going to cause problems on non-Linux systems? Should this
>> checking perhaps be put behind a separate Kconfig option?
> 
> CI says that FreeBSD is entirely happy, while Alpine Linux isn't.  This
> is because Alpine has busybox's grep unless you install the GNU grep
> package, and I'm doing a fix to our container.
> 
> My plan to fix this is to just declare a "grep capable of binary
> searching" a conditional build requirement for Xen.  I don't think this
> is onerous, and there no other plausible alternatives here.
> 
> The other option is to detect the absence of support an skip the check. 
> It is after all a defence in depth scheme, and anything liable to cause
> a problem would be caught in CI anyway.

I'd favor the latter approach (but I wouldn't mind the conditional build
requirement, if you and others deem that better), with a warning issued
when the check can't be performed. I have to admit that I didn't expect
there would be no simple and standardized binary search tool on Unix-es.

Jan




 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.