From 315a5ea0a97a5795d1a3e28e9ff42cc2bfc630d7 Mon Sep 17 00:00:00 2001 From: Eugene Syromiatnikov Date: Mon, 26 Jul 2021 22:21:00 +0200 Subject: [PATCH] gen_provides.sh: make microcode header decoding endianness-agnostic Unfortunately, hexdump doesn't support enforcing endianness of printed fields (or printing of fields out of order, for that matter), and there is no trivial analogue of dd conv=swab for 4-byte swaps, so we use xxd's so-called "little-endian mode" to convert the endianness to big endian, then print fields per-byte with hexdump and process the constructed 0xaabbccdd numbers. Note that this also swaps the order of the date fields to mm.dd.yyYY (instead of YYyy.mm.dd). * gen_provides.sh: Pipe dd, xxd, and xxd -r to swap quad-bytes into big endian, print them as sequences of bytes to construct the fields of necessary size. * microcode_ctl.spec (BuildRequires): Add /usr/bin/xxd. Resolves: #1880064 Signed-off-by: Eugene Syromiatnikov --- gen_provides.sh | 41 +++++++++++++++++++++++++++++++---------- microcode_ctl.spec | 4 ++-- 2 files changed, 33 insertions(+), 12 deletions(-) diff --git a/gen_provides.sh b/gen_provides.sh index c719694..16abba1 100755 --- a/gen_provides.sh +++ b/gen_provides.sh @@ -43,25 +43,43 @@ for f in $(grep -E '/intel-ucode.*/[0-9a-f][0-9a-f]-[0-9a-f][0-9a-f]-[0-9a-f][0- # ext_sig, 12 bytes in size IFS=' ' read cpuid pf_mask <<- EOF - $(hexdump -s "$skip" -n 8 \ - -e '"" 1/4 "%08x " 1/4 "%u" "\n"' "$f") + $(dd if="$f" ibs=1 skip="$skip" count=8 status=none \ + | xxd -e -g4 | xxd -r | hexdump -n 8 \ + -e '"" 4/1 "%02x" " 0x" 4/1 "%02x" "\n"') EOF + # Converting values from the constructed %#08x format + pf_mask="$((pf_mask))" skip="$((skip + 12))" ext_sig_pos="$((ext_sig_pos + 1))" else # Microcode header, 48 bytes, last 3 fields reserved + # cksum, ldrver are ignored IFS=' ' read hdrver rev \ - date_y date_d date_m \ + date_m date_d date_y \ cpuid cksum ldrver \ pf_mask datasz totalsz <<- EOF - $(hexdump -s "$skip" -n 36 \ - -e '"" 1/4 "%u " 1/4 "%#x " \ - 1/2 "%04x " 1/1 "%02x " 1/1 "%02x " \ - 1/4 "%08x " 1/4 "%x " 1/4 "%#x " \ - 1/4 "%u " 1/4 "%u " 1/4 "%u" "\n"' "$f") + $(dd if="$f" ibs=1 skip="$skip" count=36 status=none \ + | xxd -e -g4 | xxd -r | hexdump -n 36 \ + -e '"0x" 4/1 "%02x" " 0x" 4/1 "%02x" " " \ + 1/1 "%02x " 1/1 "%02x " 2/1 "%02x" " " \ + 4/1 "%02x" " 0x" 4/1 "%02x" " 0x" 4/1 "%02x" \ + " 0x" 4/1 "%x" \ + " 0x" 4/1 "%02x" " 0x" 4/1 "%02x" "\n"') EOF + # Converting values from the constructed %#08x format + rev="$(printf '%#x' "$((rev))")" + pf_mask="$((pf_mask))" + datasz="$((datasz))" + totalsz="$((totalsz))" + + # Skipping files with unexpected hdrver value + [ 1 = "$((hdrver))" ] || { + echo "$f+$skip@$file_sz: incorrect hdrver $((hdrver))" >&2 + break + } + [ 0 != "$datasz" ] || datasz=2000 [ 0 != "$totalsz" ] || totalsz=2048 @@ -80,9 +98,12 @@ for f in $(grep -E '/intel-ucode.*/[0-9a-f][0-9a-f]-[0-9a-f][0-9a-f]-[0-9a-f][0- # ext_sig table header, 20 bytes in size, # last 3 fields are reserved. IFS=' ' read ext_sig_cnt <<- EOF - $(hexdump -s "$skip" -n 4 \ - -e '"" 1/4 "%u" "\n"' "$f") + $(dd if="$f" ibs=1 skip="$skip" count=4 status=none \ + | xxd -e -g4 | hexdump -n 4 \ + -e '"0x" 4/1 "%02x" "\n"') EOF + # Converting values from the constructed format + ext_sig_cnt="$((ext_sig_cnt))" skip="$((skip + 20))" else diff --git a/microcode_ctl.spec b/microcode_ctl.spec index 09f783b..eeed042 100644 --- a/microcode_ctl.spec +++ b/microcode_ctl.spec @@ -124,8 +124,8 @@ Source1002: gen_updates2.py ExclusiveArch: %{ix86} x86_64 BuildRequires: systemd-units -# hexdump is used in gen_provides.sh -BuildRequires: coreutils util-linux +# dd, hexdump, and xxd are used in gen_provides.sh +BuildRequires: coreutils util-linux /usr/bin/xxd # gen_updates2.py requires python interpreter BuildRequires: /usr/bin/python3 Requires: coreutils