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

Re: [PATCH v3 60/70] x86: Build check for embedded endbr64 instructions


  • To: Jan Beulich <jbeulich@xxxxxxxx>
  • From: Andrew Cooper <Andrew.Cooper3@xxxxxxxxxx>
  • Date: Wed, 23 Feb 2022 12:05:09 +0000
  • Accept-language: en-GB, en-US
  • Arc-authentication-results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=citrix.com; dmarc=pass action=none header.from=citrix.com; dkim=pass header.d=citrix.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=WbsRgmoUasaXVoGoDDiAqVNaSlHnpV7a6AYVQIYHgVI=; b=kpKGRBnoU/i7QJs+1XzOmxTiJn0HBNP6PouB01MgQZthE+95jRC87XA4CWAmwtC3a2E3A9tKBVUgE0aA7LHY/+SBCh1NSPmOjmEDrQ4qwSZZE+w/RMjmbD2hmompqrvHAhNyyQCgUGmpRgM2jpM4BE0lGMKC4sOi+E2PL/mpdc9vco0OerQ0/r4l0jaz7Xz3y35WJud/FyHlPMj8Gbp7PUXo93UmAPUM6jRjVWQwjaGZMBLVpN0UExMny+JDw/Ks7mZNTSvLRz2TIXBA2Wrk1zY/HEG1jH0zQb5NhlmAEeP+PrjfUg7bSHJbS83rMi1BlLSumtpz6sJj8JbZxjDFAA==
  • Arc-seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=SFXnxPjfppIrvzEXF3fOlJXNkJuyDB0YD0Bfne4YZqgkXPcKGg7p8NPZT+8RBgKuzcyy+rG3vuUUeB3Na6/XFNMOHU0AYl/dvWYgNJvYpOLEjlgHuL50PK2nyPDKGYM1ZmahE3d4emnYsonnsxanp+DZR5oaXAnCuNPwtXXd0NrlV4JmK5ZRPRzc8Rp31KVbepXUKWsmNU2mfHkWR30A6+q/+XwPnkKD61YpVzwPRwhaxkHt4xZgTInG5CfESkpZdjaSk9AsdwklemYWMflZ4bpFMadW69YXB9RmiW7Vnqm6LdqQtHSKevfLWCtHBCUfUfTk4QOi1tou50zoBwBKrQ==
  • Authentication-results: esa1.hc3370-68.iphmx.com; dkim=pass (signature verified) header.i=@citrix.onmicrosoft.com
  • Cc: Marek Marczykowski-Górecki <marmarek@xxxxxxxxxxxxxxxxxxxxxx>, Roger Pau Monne <roger.pau@xxxxxxxxxx>, Wei Liu <wl@xxxxxxx>, Xen-devel <xen-devel@xxxxxxxxxxxxxxxxxxxx>
  • Delivery-date: Wed, 23 Feb 2022 12:05:26 +0000
  • Ironport-data: A9a23:xZGv1K/1DZiQyzFaS5TKDrUDvX6TJUtcMsCJ2f8bNWPcYEJGY0x3z zAeWm/Sb6zYZWT1eNtxOYTn8BlVv8PTnIdiHVA9pX08E34SpcT7XtnIdU2Y0wF+jyHgoOCLy +1EN7Es+ehtFie0Si+Fa+Sn9T8mvU2xbuKU5NTsY0idfic5Dndx4f5fs7Rh2NQw24LiW1rlV e7a+KUzBnf0g1aYDUpMg06zgEsHUCPa4W5wUvQWPJinjXeG/5UnJMt3yZKZdhMUdrJ8DO+iL 9sv+Znilo/vE7XBPfv++lrzWhVirrc/pmFigFIOM0SpqkAqSiDfTs/XnRfTAKtao2zhojx/9 DlCnaG5RQ0uLIT9pN1DDwZ5Azp4HIda9paSdBBTseTLp6HHW37lwvEoB0AqJ4wIvO1wBAmi9 9RBdmpLNErawbvrnvTrEYGAhex6RCXvFKoZtmtt0nfyCvE+TIqYa67L+cVZzHE7gcUm8fP2O ZdDMGI3MkSojxtnAXpOMKA1s/uUm1bdYzlIpFO3obEm/D2GpOB2+Oe0a4eEEjCQfu1Kmm6Iq 2SA+H72ajkKOdraxTeb/3aEgu7UgTi9SI8UDKe/9PNhnBuU3GN7IB8cWEa/oPK5olWjQN8ZI EsRkgIrpLI3/VamTfH8WQO5u3+OuhMAW9tWHPY+4QvLwa3Rizt1HUBdEGQHMoZ/8pZrG3p6j Tdlgu8FGxRSubGfTmC0x4ut82+tGDgOK04oeSEtGF5tD8bYnKk/iRfGT9BGGaGzj8HoFTyY/ w1mvBTSlJ1I05dVivzTEUTvxmv1+8OXFlJdChD/Azr9hj6VcrJJcGBBBbLzyf9bZLiUQVCa1 JTvs5jPtbteZX1hecHkfQnsIF1Lz6vdWNE/qQQ2d3XEy9hL0yT/FWy3yGsjTHqFyu5eJVfUj Lb74Gu9HqN7MnqwdrNQaImsEcksxqWIPY27Cq2JM4QWMsItK1/vEMRSiai4hTyFfK8Ey/xXB HtmWZz0USZy5VpPllJauNvxIZd0n3tjlAs/tLjwzgi90Kr2WZJmYextDbd6VchgtPnsiFyMq 753bpLWoz0CALyWSnSGquY7cAFVRUXX8Lir8qS7gMbYeVE4cIzgYteMqY4cl3tNxfoNzb6Qp innMqKaoXKm7UD6xcyxQikLQJvkXIplrGJ9OiopPF2y3GMkb5rp56AaH6bbt5F8nAC/5ZaYl 8U4Rvg=
  • Ironport-hdrordr: A9a23:i73QNKnsQpMREVDdDpieYIjlL+/pDfOCimdD5ihNYBxZY6Wkfp +V88jzhCWZtN9OYhwdcIi7SdS9qXO1z+8R3WGIVY3SEzUOy1HYUL2KirGSjQEIeheOutK1sJ 0PT0EQMqyIMbEXt7eY3OD8Kadb/DDlytHouQ699QYUcegCUcgJhG0ZajpzUHcGPzWubaBJT6 Z0jfA3wwZIDE5nCPhTcUN1ONQryee79q7OUFojPVoK+QOOhTSn5PrRCB6DxCoTVDtJ3PML7X XFuxaR3NTij9iLjjvnk0PD5ZVfn9XsjvFZAtaXt8QTIjLwzi61eYVaXaGYtjxdmpDt1L9qqq iPn/4TBbU215rjRBDznfIr4Xin7N8a0Q6m9bZfuwq7nSW2fkNjNyMLv/MnTvKQ0TtfgDg76t MQ44vRjesmMfuL9h6NluTgRlVkkFG5rmEllvNWh3tDUZEGYLsUtoAH+lhJea1wVx4SxbpXWd WGNvusrMq+sGnqG0zxry1q2pihT34zFhCJTgwLvdGUySFfmDR8w1EDzMISk38c/NZlIqM0qt jsI+BtjvVDX8UWZaVyCKMIRta2EHXERVbJPHiJKVrqGakbMzbGqoLx4r8y+Oa2EaZ4hqcaid DEShdVpGQyc0XhBYmH24BK6AnERCGnUTHk2qhllu5EU33HNc3W2AG4OSITepGb0oYi6+XgKo OOBK4=
  • List-id: Xen developer discussion <xen-devel.lists.xenproject.org>
  • Thread-index: AQHYKAHJByKzjV/vxUOU3yFx/Fz376yhAcIAgAAJbQA=
  • Thread-topic: [PATCH v3 60/70] x86: Build check for embedded endbr64 instructions

On 23/02/2022 11:31, Jan Beulich wrote:
> On 22.02.2022 16:26, Andrew Cooper wrote:
>> up on a non-instruction boundary.  Such embedded instructions mark legal
>> indirect branch targets as far as the CPU is concerned, which aren't legal as
>> far as the logic is concerned.
> Thinking about it: Wouldn't it be yet slightly more reassuring to also
> look for ENDBR32?

I considered that, but it's awkward to do and doubles the length of this
already ~0.7s (x2 for efi because this step isn't performed in parallel)
delay to the build.

We do not have __HYPERVISOR_CS32, so ENDBR32 will yield #CP[endbr] if
encountered.

If an attacker has managed to edit the GDT to insert a compatibility
code segment, and hijacked a far transfer to use it, then the absence of
ENDBR32's in the binary isn't going to be an impediment.

>
>> When CET-IBT is active, check for embedded byte sequences.  Example failures
>> look like:
>>
>>   check-endbr.sh xen-syms Fail: Found 2 embedded endbr64 instructions
>>   0xffff82d040325677: test_endbr64 at 
>> /local/xen.git/xen/arch/x86/x86_64/entry.S:28
>>   0xffff82d040352da6: init_done at /local/xen.git/xen/arch/x86/setup.c:675
>>
>> Signed-off-by: Marek Marczykowski-Górecki <marmarek@xxxxxxxxxxxxxxxxxxxxxx>
>> Signed-off-by: Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
> Reviewed-by: Jan Beulich <jbeulich@xxxxxxxx>

Thanks.

>
>> --- a/README
>> +++ b/README
>> @@ -68,6 +68,7 @@ provided by your OS distributor:
>>  In addition to the above there are a number of optional build
>>  prerequisites. Omitting these will cause the related features to be
>>  disabled at compile time:
>> +    * Binary-search capable grep (if building Xen with CET support)
> Nit: With this (maybe this was the case already earlier though)
> s/will/may/ in the previous sentence?

I'm planning a separate overhaul to README because bits of it are quite
wrong, including lots of this section.  This was the lead bad addition I
could come up with that didn't involve a major rewrite.

>> --- /dev/null
>> +++ b/xen/tools/check-endbr.sh
>> @@ -0,0 +1,85 @@
>> +#!/bin/sh
>> +#
>> +# Usage ./$0 xen-syms
>> +#
>> +set -e
>> +
>> +# Prettyprint parameters a little for message
>> +MSG_PFX="${0##*/} ${1##*/}"
>> +
>> +OBJCOPY="${OBJCOPY:-objcopy} -j .text $1"
>> +OBJDUMP="${OBJDUMP:-objdump} -j .text $1"
> While embedding the arguments here shortens the lines where these are
> used, the appearance especially of $OBJCOPY with a single file name
> argument ...
>
>> +ADDR2LINE="${ADDR2LINE:-addr2line}"
>> +
>> +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
>> +
>> +# Check that grep can do binary searches.  Some, e.g. busybox, can't.  
>> Leave a
>> +# warning but don't fail the build.
>> +echo "X" | grep -aob "X" -q 2>/dev/null ||
>> +    { echo "$MSG_PFX Warning: grep can't do binary searches" >&2; exit 0; }
>> +
>> +#
>> +# 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 -w | grep '   endbr64 *$' | cut -f 1 -d ':' > $VALID &
>> +
>> +#
>> +# 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) dash's printf doesn't understand hex escapes, hence the use of octal.
>> +#
>> +# 3) 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
> ..., like here, is then somewhat misleading considering that the tool
> can take one or two filenames as arguments.

I can re-expand them if you'd prefer.  This would be the delta:

diff --git a/xen/tools/check-endbr.sh b/xen/tools/check-endbr.sh
index 85878353112a..3019ca1c7db0 100755
--- a/xen/tools/check-endbr.sh
+++ b/xen/tools/check-endbr.sh
@@ -7,8 +7,8 @@ set -e
 # Prettyprint parameters a little for message
 MSG_PFX="${0##*/} ${1##*/}"
 
-OBJCOPY="${OBJCOPY:-objcopy} -j .text $1"
-OBJDUMP="${OBJDUMP:-objdump} -j .text $1"
+OBJCOPY="${OBJCOPY:-objcopy}"
+OBJDUMP="${OBJDUMP:-objdump}"
 ADDR2LINE="${ADDR2LINE:-addr2line}"
 
 D=$(mktemp -d)
@@ -37,7 +37,7 @@ echo "X" | grep -aob "X" -q 2>/dev/null ||
 # 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 -w | grep '      endbr64 *$' | cut -f 1 -d ':' > $VALID &
+${OBJDUMP} -j .text $1 -d -w | grep '  endbr64 *$' | cut -f 1 -d ':' >
$VALID &
 
 #
 # Second, look for any endbr64 byte sequence
@@ -56,9 +56,10 @@ ${OBJDUMP} -d -w | grep '    endbr64 *$' | cut -f 1
-d ':' > $VALID &
 #    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)}')
+eval $(${OBJDUMP} -j .text $1 -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
+${OBJCOPY} -j .text $1 -O binary $TEXT_BIN
 grep -aob "$(printf '\363\17\36\372')" $TEXT_BIN |
     awk -F':' '{printf "%s%x\n", "'$vma_hi'", int(0x'$vma_lo') + $1}' >
$ALL
 

~Andrew

 


Rackspace

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