diff --git a/.gitignore b/.gitignore index 84142de..68217c5 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,4 @@ SOURCES/06-2d-07 SOURCES/06-55-04 -SOURCES/microcode-20191115.tar.gz +SOURCES/microcode-20200602.tar.gz SOURCES/microcode_ctl-2.1-18.tar.xz diff --git a/.microcode_ctl.metadata b/.microcode_ctl.metadata index cc2b497..b2dead3 100644 --- a/.microcode_ctl.metadata +++ b/.microcode_ctl.metadata @@ -1,4 +1,4 @@ bcf2173cd3dd499c37defbc2533703cfa6ec2430 SOURCES/06-2d-07 2e405644a145de0f55517b6a9de118eec8ec1e5a SOURCES/06-55-04 -774636f4d440623b0ee6a2dad65260e81208074d SOURCES/microcode-20191115.tar.gz +ea699fd62ba3625062cae60d4a657fa11822b372 SOURCES/microcode-20200602.tar.gz 3959afc5d69a916a730131ce0f768db263e9e4f1 SOURCES/microcode_ctl-2.1-18.tar.xz diff --git a/SOURCES/06-2d-07_readme b/SOURCES/06-2d-07_readme index 60c20d4..2a9f5ec 100644 --- a/SOURCES/06-2d-07_readme +++ b/SOURCES/06-2d-07_readme @@ -1,17 +1,21 @@ Intel Sandy Bridge-E/EN/EP CPU models (SNB-EP, family 6, model 45, stepping 7) have issues with MDS-related microcode update that may lead to a system hang -after a microcode update. In order to address this, microcode update +after a microcode update[1][2]. In order to address this, microcode update to the MDS-related revision 0x718 has been disabled, and the previously published microcode revision 0x714 is used by default for the OS-driven microcode update. +[1] https://github.com/intel/Intel-Linux-Processor-Microcode-Data-Files/issues/15 +[2] https://access.redhat.com/solutions/4593951 + For the reference, SHA1 checksums of 06-2d-07 microcode files containing microcode revisions in question are listed below: * 06-2d-07, revision 0x714: bcf2173cd3dd499c37defbc2533703cfa6ec2430 * 06-2d-07, revision 0x718: 837cfebbfc09b911151dfd179082ad99cf87e85d + * 06-2d-07, revision 0x71a: 4512c8149e63e5ed15f45005d7fb5be0041f66f6 Please contact your system vendor for a BIOS/firmware update that contains -the latest microcode version. For the information regarding microcode versions +the latest microcode version. For the information regarding microcode versions required for mitigating specific side-channel cache attacks, please refer to the following knowledge base articles: * CVE-2017-5715 ("Spectre"): diff --git a/SOURCES/06-4f-01_disclaimer b/SOURCES/06-4f-01_disclaimer index d5bc60d..c978958 100644 --- a/SOURCES/06-4f-01_disclaimer +++ b/SOURCES/06-4f-01_disclaimer @@ -1,4 +1,4 @@ -microcode update for Intel Broadwell-EP/EX (BDX-ML B/M/R0; family 6, model 79, +Microcode update for Intel Broadwell-EP/EX (BDX-ML B/M/R0; family 6, model 79, stepping 1; CPUID 0x406f1) CPUs is disabled as it may cause system instability. Please refer to /usr/share/doc/microcode_ctl/caveats/06-4f-01_readme and /usr/share/doc/microcode_ctl/README.caveats for details. diff --git a/SOURCES/06-55-04_config b/SOURCES/06-55-04_config index 6ba6d76..df081c9 100644 --- a/SOURCES/06-55-04_config +++ b/SOURCES/06-55-04_config @@ -1,3 +1,10 @@ model GenuineIntel 06-55-04 path intel-ucode/06-55-04 -disable early late +# Bug https://github.com/intel/Intel-Linux-Processor-Microcode-Data-Files/issues/21 +# affects only SKX-W/X (Workstation and HEDT segments); product segment +# can be determined by checking bits 5..3 of the CAPID0 field in PCU registers +# device (see https://www.intel.com/content/dam/www/public/us/en/documents/specification-updates/xeon-scalable-spec-update.pdf#page=13 +# for Server/FPGA/Fabric segments description; for SKX-W/X no public +# documentation seems to be available). Specific device/function numbers +# are provided for speeding up the search only, VID:DID is the real selector. +pci_config_val mode=success-all device=0x1e function=3 vid=0x8086 did=0x2083 offset=0x84 size=4 mask=0x38 val=0x38,0x18,0x8 diff --git a/SOURCES/06-55-04_disclaimer b/SOURCES/06-55-04_disclaimer index 238d233..afeb511 100644 --- a/SOURCES/06-55-04_disclaimer +++ b/SOURCES/06-55-04_disclaimer @@ -1,6 +1,5 @@ -Microcode revision 0x2000065 for Intel Skylake-SP/X/W (family 6, model 85, -stepping 4; CPUID 0x50654) CPUs that has been included into microcode-20191112 -release is disabled as it may cause system instability and the previous revision -0x2000064 is used instead. +Microcode revisions 0x2000065 and higher for Intel Skylake-X/W (family 6, +model 85, stepping 4; CPUID 0x50654) are disabled as they may cause system +hangs on reboot and the previous revision 0x2000064 is used instead. Please refer to /usr/share/doc/microcode_ctl/caveats/06-55-04_readme and /usr/share/doc/microcode_ctl/README.caveats for details. diff --git a/SOURCES/06-55-04_readme b/SOURCES/06-55-04_readme index 41fb757..fbfeeba 100644 --- a/SOURCES/06-55-04_readme +++ b/SOURCES/06-55-04_readme @@ -1,10 +1,13 @@ -Intel Skulake Scalable Platform CPU models (SKL-SP/W/X, family 6, model 85, -stepping 4) have reports of system hangs when revision 0x2000065 of microcode, -that is included since microcode-20191112 update, is applied. In order -to address this, microcode update to this revision has been disabled, +Intel Skulake Scalable Platform CPU models that belong to Workstation and HEDT +(Basin Falls) segment (SKL-W/X, family 6, model 85, stepping 4) have reports +of system hangs on reboot when revision 0x2000065 of microcode, that is included +since microcode-20191112 update, is applied[1]. In order to address this, +microcode update to this revision has been disabled by default on these systems, and the previously published microcode revision 0x2000064 is used by default for the OS-driven microcode update. +[1] https://github.com/intel/Intel-Linux-Processor-Microcode-Data-Files/issues/21 + For the reference, SHA1 checksums of 06-55-04 microcode files containing microcode revisions in question are listed below: * 06-55-04, revision 0x2000064: 2e405644a145de0f55517b6a9de118eec8ec1e5a diff --git a/SOURCES/README.caveats b/SOURCES/README.caveats index 263a40b..c101801 100644 --- a/SOURCES/README.caveats +++ b/SOURCES/README.caveats @@ -159,6 +159,49 @@ separated by white space. Currently, the following options are supported: one model name per line. The model name of the running CPU (as reported in /proc/cpuinfo) is compared against the names in the provided list, and, if there is a match, caveat check fails. + * "pci_config_val" performs check for specific values in selected parts + of configuration space of specified PCI devices. If "-m" option + is not specified, then the actual check is skipped, and the check returns + result in accordance with the provided "mode" option (se below). Check + arguments are a white-space-separated list of "key=value" pairs. + The following keys are supported: + * "domain" - PCI domain number, or "*" (an asterisk) for any domain. + Default is "*". + * "bus" - PCI bus number, or "*" (an asterisk) for any bus. Default is "*". + * "device" - PCI device number, or "*" (an asterisk) for any device. + Default is "*". + * "function" - PCI function number, or "*" (an asterisk) for any function. + Default is "*". + * "vid" - PCI vendor ID, or empty string for any vendor ID. Default + is empty string. + * "did" - PCI device ID, or empty string for any device ID. Default + is empty string. + * "offset" - offset in device's configuration space where the value resides. + Default is 0. + * "size" - field size. Possible values are 1, 2, 4, or 8. Default is 4. + * "mask" - mask applied to the values during the check. Default is 0. + * "val" - comma-separated list of matching values. Default is 0. + * "mode" - check mode, the way matches are interpreted: + * "success-any" - check succeeds if there was at least one match, + otherwise it fails. + * "success-all" - check succeeds if there was at least one device checked + and all the checked devices have matches, otherwise the check fails. + * "fail-any" - check fails if there was at least one match, otherwise + it succeeds. + * "fail-all" - check fails if there was at least one device checked + and all the checked devices have matches, otherwise the check succeeds. + An example of a check: + pci_config_val mode=success-all device=30 function=3 vid=0x8086 did=0x2083 offset=0x84 size=4 mask=0x38 val=0x38,0x18,0x8 + It interprets 4 bytes at offset 0x84 of special files "config" under + directories that match glob pattern "/sys/bus/pci/devices/*:*:1e.3" + as an unsigned integer value, applies mask 0x38 (thus selecting bit 5..3 + of it) and checks whether it is one of the values 0x38, 0x18, or 0x8 (0b111, + 0b011, or 0b001 in bits 5..3, respectively); if there are such files, + and all the checked values in every checked file has matched at least one + of the aforementioned value, then the check is successful, otherwise + it fails (in accordance with "mode=success-all" semantics). This check fails + if "-m" option is not specified. + check_caveats script @@ -342,10 +385,6 @@ by creation of a file "/etc/microcode_ctl/ignore-hypervisor-flag". The script has no options and always returns 0. -In addition to overrides that affect check_caveats, the presence of the -"/etc/microcode_ctl/ignore-hypervisor-flag" flag provides an ability -to skip "hypervisor" flag check. - 99microcode_ctl-fw_dir_override dracut module --------------------------------------------- @@ -442,13 +481,16 @@ Minimum versions of the kernel package that contain the fix: Intel Sandy Bridge-E/EN/EP caveat --------------------------------- MDS-related microcode revision 0x718 for Intel Sandy Bridge-E/EN/EP -(SNB-EP, family 6, model 45, stepping 7) may lead to system instability. +(SNB-EP, family 6, model 45, stepping 7) may lead to system instability[1][2]. In order to address this, this microcode update is not used and the previous microcode revision is provided instead by default; the microcode file, however, is still shipped as part of microcode_ctl package and can be used for performing a microcode update if it is enforced via the aforementioned overrides. (See the sections "check_caveats script" and "reload_microcode script" for details.) +[1] https://github.com/intel/Intel-Linux-Processor-Microcode-Data-Files/issues/15 +[2] https://access.redhat.com/solutions/4593951 + Caveat name: intel-06-2d-07 Affected microcode: intel-ucode/06-2d-07. @@ -458,14 +500,17 @@ Mitigation: previously published microcode revision 0x714 is used by default. Intel Skylake-SP/W/X caveat --------------------------- -Microcode revision 0x2000065 for Intel Skylake Scalable Platform (SKL-SP/W/X, -family 6, model 85, stepping 4) may lead to system instability. -In order to address this, this microcode update is not used and the previous -microcode revision is provided instead by default; the microcode file, however, -is still shipped as part of microcode_ctl package and can be used for performing -a microcode update if it is enforced via the aforementioned overrides. -(See the sections "check_caveats script" and "reload_microcode script" -for details.) +Microcode revisions 0x2000065 and later for some CPU models that belong to +Intel Skylake Scalable Platform (SKL-W/X, family 6, model 85, stepping 4, +Workstation/HEDT segments) may lead to hangs during reboot[1]. In order +to address this, by default these microcode updates are not used +and the previous microcode revision is provided instead; the microcode file, +however, is still shipped as part of microcode_ctl package and can be used +for performing a microcode update if it is enforced via the aforementioned +overrides. (See the sections "check_caveats script" and "reload_microcode +script" for details.) + +[1] https://github.com/intel/Intel-Linux-Processor-Microcode-Data-Files/issues/21 Caveat name: intel-06-55-04 diff --git a/SOURCES/check_caveats b/SOURCES/check_caveats index 462d541..f43fb4a 100755 --- a/SOURCES/check_caveats +++ b/SOURCES/check_caveats @@ -132,6 +132,132 @@ check_kver() return 1 } +# It is needed for SKX[1] for which different product segments +# are differentiated by a value in the CAPID0 field of PCU registers +# device[2]. +# [1] https://github.com/intel/Intel-Linux-Processor-Microcode-Data-Files/issues/21 +# [2] https://www.intel.com/content/dam/www/public/us/en/documents/specification-updates/xeon-scalable-spec-update.pdf#page=13 +# +# $1 - params in config file, space-spearated, in key=value form: +# domain=* - PCI domain, '*' or number +# bus=* - PCI bus, '*' or number +# device=* - PCI device, '*' or number +# function=* - PCI function, '*' or number +# vid= - PCI vendor ID, empty or number +# did= - PCI device ID, empty or number +# offset=0 - offset in configuration space +# size=4 - field size +# mask=0 - mask applied to the data read +# val=0 - comma-separated list of possible values +# mode=success-any [ success-ail, fail-any, fail-all ] - matching mode: +# success-any: Returns 0 if there was at least one match, otherwise 1. +# success-all: Returns 0 if there was at least one device checked and all +# the checked devices have matches, otherwise 1. +# fail-any: Returns 1 if there was at least one match, otherwise 0. +# fail-all: Returns 1 if there was at least one device checked and all +# the checked devices have matches, otherwise 0. +# $2 - whether model filter is engaged (if it is not '1', just return the result +# based on "mode" value that assumes that there were 0 checks/0 matches). +check_pci_config_val() +{ + local domain='*' bus='*' device='*' func='*' vid= did= + local offset=0 size=4 mask=0 val=0 mode=success-any + local checked=0 matched=0 path='' + local dev_path dev_vid dev_did dev_val + local opts="${1:-}" + local match_model="${2:0}" + + set -- $1 + while [ "$#" -gt 0 ]; do + [ "x${1#domain=}" = "x${1}" ] || domain="${1#domain=}" + [ "x${1#bus=}" = "x${1}" ] || bus="${1#bus=}" + [ "x${1#device=}" = "x${1}" ] || device="${1#device=}" + [ "x${1#function=}" = "x${1}" ] || func="${1#function=}" + [ "x${1#vid=}" = "x${1}" ] || vid="${1#vid=}" + [ "x${1#did=}" = "x${1}" ] || did="${1#did=}" + [ "x${1#offset=}" = "x${1}" ] || offset="${1#offset=}" + [ "x${1#size=}" = "x${1}" ] || size="${1#size=}" + [ "x${1#mask=}" = "x${1}" ] || mask="${1#mask=}" + [ "x${1#val=}" = "x${1}" ] || val="${1#val=}" + [ "x${1#mode=}" = "x${1}" ] || mode="${1#mode=}" + + shift + done + + path="$domain" + if [ "x$bus" = 'x*' ]; then + path="$path:$bus"; + else + path=$(printf '%s:%02x' "$path" "$bus") + fi + if [ "x$device" = 'x*' ]; then + path="$path:$device"; + else + path=$(printf '%s:%02x' "$path" "$device") + fi + if [ "x$func" = 'x*' ]; then + path="$path.$func"; + else + path=$(printf '%s.%01x' "$path" "$func") + fi + + # Normalise VID, DID + [ -n "$vid" ] || vid="$(printf '0x%04x' "$vid")" + [ -n "$did" ] || did="$(printf '0x%04x' "$did")" + + ( [ 1 != "$match_model" ] \ + || /usr/bin/find /sys/bus/pci/devices/ -maxdepth 1 -name "$path" \ + || : ) | ( + while read -r dev_path; do + # Filter VID, DID + if [ -n "$vid" ]; then + dev_vid=$(/bin/cat "$dev_path/vendor") + [ "x$vid" = "x$dev_vid" ] || continue + fi + if [ -n "$did" ]; then + dev_did=$(/bin/cat "$dev_path/device") + [ "x$did" = "x$dev_did" ] || continue + fi + + checked="$((checked + 1))" + + dev_val="$(/usr/bin/od -j "$offset" -N "$size" -A n \ + -t "u$size" "$dev_path/config")" + + val_rest="${val}" + while :; do + cur_val="${val_rest%%,*}" + if [ "$((dev_val & mask))" = "$((cur_val & mask))" ] + then + matched="$((matched + 1))" + break + fi + [ "x${val_rest}" != "x${val_rest#*,}" ] || break + val_rest="${val_rest#*,}" + done + + case "$mode" in + success-any) [ "$matched" -eq 0 ] || { echo 0; exit; } ;; + success-all) [ "$matched" -eq "$checked" ] || { echo 1; exit; } ;; + fail-any) [ "$matched" -eq 0 ] || { echo 1; exit; } ;; + fail-all) [ "$matched" -eq "$checked" ] || { echo 0; exit; } ;; + *) echo 2; exit;; + esac + done + + debug "PCI config value check ($opts): checked $checked," \ + "matched $matched (model check is set to $match_model)" + + case "$mode" in + success-any) if [ "$matched" -eq 0 ]; then echo 1; else echo 0; fi ;; + success-all) if [ "$matched" -gt 0 -a "$matched" -eq "$checked" ]; then echo 0; else echo 1; fi ;; + fail-any) if [ "$matched" -eq 0 ]; then echo 0; else echo 1; fi ;; + fail-all) if [ "$matched" -gt 0 -a "$matched" -eq "$checked" ]; then echo 1; else echo 0; fi ;; + *) echo 2; exit;; + esac + ) +} + # Provides model in format "VENDOR_ID FAMILY-MODEL-STEPPING" # # We check only the first processor as we don't expect non-symmetrical setups @@ -182,7 +308,7 @@ fail() fail_paths="$fail_paths $cfg_path" [ 0 -eq "$print_disclaimers" ] || [ ! -e "${dir}/disclaimer" ] \ - || cat "${dir}/disclaimer" + || /bin/cat "${dir}/disclaimer" } #check_kver "$@" @@ -225,7 +351,7 @@ while getopts "dek:c:mv" opt; do esac done -: ${configs:=$(find "${MC_CAVEATS_DATA_DIR}" -maxdepth 1 -mindepth 1 -type d -printf "%f\n")} +: "${configs:=$(find "${MC_CAVEATS_DATA_DIR}" -maxdepth 1 -mindepth 1 -type d -printf "%f\n")}" cpu_model=$(get_model_string) cpu_model_name=$(get_model_name) @@ -273,6 +399,7 @@ for cfg in $(echo "${configs}"); do cfg_blacklist= cfg_mc_min_ver_late= cfg_disable= + cfg_pci= while read -r key value; do case "$key" in @@ -299,7 +426,17 @@ for cfg in $(echo "${configs}"); do ;; blacklist) cfg_blacklist=1 - break + ;; + pci_config_val) + cfg_pci="$cfg_pci + $value" + ;; + '#'*|'') + continue + ;; + *) + debug "Unknown key '$key' (value '$value') in config" \ + "'$cfg'" ;; esac done < "${dir}/config" @@ -388,12 +525,14 @@ for cfg in $(echo "${configs}"); do cfg_mc_present=0 for p in $(printf "%s" "$cfg_path"); do - find "$MC_CAVEATS_DATA_DIR/$cfg" \ - -path "$MC_CAVEATS_DATA_DIR/$cfg/$p" -print0 \ - | grep -zFxq "$cpu_mc_path" \ + { /usr/bin/find "$MC_CAVEATS_DATA_DIR/$cfg" \ + -path "$MC_CAVEATS_DATA_DIR/$cfg/$p" -print0; + /bin/true; } \ + | /bin/grep -zFxq "$cpu_mc_path" \ || continue cfg_mc_present=1 + break done [ 1 = "$cfg_mc_present" ] || { @@ -478,6 +617,28 @@ for cfg in $(echo "${configs}"); do } fi + # Check PCI devices if model filter is enabled + # Note that the model filter check is done inside check_pci_config_val + # based on the 'mode=' parameter. + if [ -n "$cfg_pci" ]; then + pci_line="$(printf "%s\n" "$cfg_pci" | while read -r pci_line; do + [ -n "$pci_line" ] || continue + pci_res=$(check_pci_config_val "$pci_line" \ + "$match_model") + [ 0 != "$pci_res" ] || continue + echo "$pci_res $pci_line" + break + done + echo "0 ")" + + [ -z "${pci_line#* }" ] || { + debug "PCI configuration word check '${pci_line#* }'" \ + "failed (with return code ${pci_line%% *})" + fail + continue + } + fi + ok_cfgs="$ok_cfgs $cfg" ok_paths="$ok_paths $cfg_path" done diff --git a/SOURCES/dracut_99microcode_ctl-fw_dir_override_module_init.sh b/SOURCES/dracut_99microcode_ctl-fw_dir_override_module_init.sh index 8dc327a..854e278 100755 --- a/SOURCES/dracut_99microcode_ctl-fw_dir_override_module_init.sh +++ b/SOURCES/dracut_99microcode_ctl-fw_dir_override_module_init.sh @@ -48,29 +48,6 @@ install() { dinfo " microcode_ctl: processing data directory " \ "\"$DATA_DIR/$i\"..." - if ! cc_out=$($check_caveats -e -k "$kernel" -c "$i" $verbose_opt) - then - dinfo " microcode_ctl: kernel version \"$kernel\"" \ - "failed early load check for \"$i\", skipping" - continue - fi - - path=$(printf "%s" "$cc_out" | sed -n 's/^paths //p') - [ -n "$path" ] || { - ignored=$(printf "%s" "$cc_out" | \ - sed -n 's/^skip_cfgs //p') - - if [ -n "$ignored" ]; then - dinfo " microcode_ctl: configuration" \ - "\"$i\" is ignored" - else - dinfo " microcode_ctl: no microcode paths" \ - "are associated with \"$i\", skipping" - fi - - continue - } - if [ "x" != "x$hostonly" ]; then do_skip_host_only=0 @@ -92,55 +69,33 @@ install() { do_skip_host_only=1 fi - if [ 0 -eq "$do_skip_host_only" ]; then - local hostonly_passed=0 - local ucode - local uvendor - local ucode_dir="" - - ucode=$(get_ucode_file) - uvendor=$(get_cpu_vendor) - - case "$uvendor" in - Intel) - ucode_dir="intel-ucode" - ;; - AMD) - ucode_dir="amd-ucode" - ;; - *) - dinfo " microcode_ctl: unknown CPU" \ - "vendor: \"$uvendor\", bailing out of" \ - "Host-Only check" - continue - ;; - esac - - # $path is a list of globs, so it needs special care - for p in $(printf "%s" "$path"); do - find "$DATA_DIR/$i" -path "$DATA_DIR/$i/$p" \ - -print0 \ - | grep -zFxq \ - "$DATA_DIR/$i/$ucode_dir/$ucode" \ - || continue - - dinfo " microcode_ctl: $i: Host-Only" \ - "mode is enabled and" \ - "\"$ucode_dir/$ucode\" matches \"$p\"" - - hostonly_passed=1 - break - done + match_model_opt="" + [ 1 = "$do_skip_host_only" ] || match_model_opt="-m" - [ 1 -eq "$hostonly_passed" ] || { - dinfo " microcode_ctl: $i: Host-Only mode" \ - "is enabled and ucode name does not" \ - "match the expected one, skipping" \ - "caveat (\"$ucode\" not in \"$path\")" - continue - } + if ! cc_out=$($check_caveats -e -k "$kernel" -c "$i" \ + $verbose_opt $match_model_opt) + then + dinfo " microcode_ctl: kernel version \"$kernel\"" \ + "failed early load check for \"$i\", skipping" + continue fi + path=$(printf "%s" "$cc_out" | sed -n 's/^paths //p') + [ -n "$path" ] || { + ignored=$(printf "%s" "$cc_out" | \ + sed -n 's/^skip_cfgs //p') + + if [ -n "$ignored" ]; then + dinfo " microcode_ctl: configuration" \ + "\"$i\" is ignored" + else + dinfo " microcode_ctl: no microcode paths" \ + "are associated with \"$i\", skipping" + fi + + continue + } + dinfo " microcode_ctl: $i: caveats check for kernel" \ "version \"$kernel\" passed, adding" \ "\"$DATA_DIR/$i\" to fw_dir variable" diff --git a/SOURCES/gen_provides.sh b/SOURCES/gen_provides.sh index c0c6b1d..5e2a2a4 100755 --- a/SOURCES/gen_provides.sh +++ b/SOURCES/gen_provides.sh @@ -21,31 +21,75 @@ for f in $(grep -E '/intel-ucode.*/[0-9a-f][0-9a-f]-[0-9a-f][0-9a-f]-[0-9a-f][0- ucode_fname="$ucode_caveat/$ucode" file_sz="$(stat -c "%s" "$f")" skip=0 + ext_hdr=0 + ext_sig_cnt=0 + ext_sig_pos=0 + next_skip=0 + # Microcode header format description: + # https://gitlab.com/iucode-tool/iucode-tool/blob/master/intel_microcode.c while :; do [ "$skip" -lt "$file_sz" ] || break - # Microcode header format description: - # https://gitlab.com/iucode-tool/iucode-tool/blob/master/intel_microcode.c - IFS=' ' read hdrver rev \ - date_y date_d date_m \ - cpuid cksum ldrver \ - pf_mask datasz totalsz <<- EOF - $(dd if="$f" bs=1 skip="$skip" count=36 status=none \ - | hexdump -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"') - EOF - - [ 0 != "$datasz" ] || datasz=2000 - [ 0 != "$totalsz" ] || totalsz=2048 - - # TODO: add some sanity/safety checks here. As of now, there's - # a (pretty fragile) assumption that all the matched files - # are valid Intel microcode files in the expected format. - - skip=$((skip + totalsz)) + # Do we parse ext_sig table or another microcode header? + if [ 0 != "$next_skip" ]; then + # Check whether we should abort ext_sig table parsing + [ \( "${skip}" -lt "${next_skip}" \) -a \ + \( "${ext_sig_pos}" -lt "${ext_sig_cnt}" \) ] || { + skip="${next_skip}" + next_skip=0 + continue + } + + # 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") + EOF + + skip="$((skip + 12))" + ext_sig_pos="$((ext_sig_pos + 1))" + else + # Microcode header, 48 bytes, last 3 fields reserved + IFS=' ' read hdrver rev \ + date_y date_d date_m \ + 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") + EOF + + [ 0 != "$datasz" ] || datasz=2000 + [ 0 != "$totalsz" ] || totalsz=2048 + + # TODO: add some sanity/safety checks here. As of now, + # there's a (pretty fragile) assumption that all + # the matched files are valid Intel microcode + # files in the expected format. + + # ext_sig table is after the microcode payload, + # check for its presence + if [ 48 -lt "$((totalsz - datasz))" ]; then + next_skip="$((skip + totalsz))" + skip="$((skip + datasz + 48))" + ext_sig_pos=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") + EOF + + skip="$((skip + 20))" + else + skip="$((skip + totalsz))" + next_skip=0 + fi + fi #[ -n "$rev" ] || continue diff --git a/SOURCES/intel_config b/SOURCES/intel_config index d37878d..1f47b87 100644 --- a/SOURCES/intel_config +++ b/SOURCES/intel_config @@ -1,5 +1,5 @@ path intel-ucode/* -vendor_id GenuineIntel +vendor GenuineIntel kernel_early 4.10.0 kernel_early 3.10.0-930 kernel_early 3.10.0-862.14.1 diff --git a/SOURCES/microcode_ctl-use-microcode-20191115-tgz.patch b/SOURCES/microcode_ctl-use-microcode-20191115-tgz.patch deleted file mode 100644 index 0548343..0000000 --- a/SOURCES/microcode_ctl-use-microcode-20191115-tgz.patch +++ /dev/null @@ -1,13 +0,0 @@ -Index: microcode_ctl-2.1-18/Makefile -=================================================================== ---- microcode_ctl-2.1-18.orig/Makefile 2018-07-24 09:15:12.463115045 +0200 -+++ microcode_ctl-2.1-18/Makefile 2018-08-09 06:18:45.524503945 +0200 -@@ -8,7 +8,7 @@ - # 2 of the License, or (at your option) any later version. - - PROGRAM = intel-microcode2ucode --MICROCODE_INTEL = microcode-20180703.tgz -+MICROCODE_INTEL = microcode-20191115.tar.gz - - INS = install - CC = gcc diff --git a/SOURCES/microcode_ctl-use-microcode-20200602-tgz.patch b/SOURCES/microcode_ctl-use-microcode-20200602-tgz.patch new file mode 100644 index 0000000..d10700e --- /dev/null +++ b/SOURCES/microcode_ctl-use-microcode-20200602-tgz.patch @@ -0,0 +1,13 @@ +Index: microcode_ctl-2.1-18/Makefile +=================================================================== +--- microcode_ctl-2.1-18.orig/Makefile 2018-07-24 09:15:12.463115045 +0200 ++++ microcode_ctl-2.1-18/Makefile 2018-08-09 06:18:45.524503945 +0200 +@@ -8,7 +8,7 @@ + # 2 of the License, or (at your option) any later version. + + PROGRAM = intel-microcode2ucode +-MICROCODE_INTEL = microcode-20180703.tgz ++MICROCODE_INTEL = microcode-20200602.tar.gz + + INS = install + CC = gcc diff --git a/SPECS/microcode_ctl.spec b/SPECS/microcode_ctl.spec index c8f4d0c..78e63d5 100644 --- a/SPECS/microcode_ctl.spec +++ b/SPECS/microcode_ctl.spec @@ -1,6 +1,5 @@ %define upstream_version 2.1-18 -%define intel_ucode_version 20191115 -%define intel_ucode_file_id 28727 +%define intel_ucode_version 20200602 %define caveat_dir %{_datarootdir}/microcode_ctl/ucode_with_caveats %define microcode_ctl_libexec %{_libexecdir}/microcode_ctl @@ -22,7 +21,7 @@ Summary: Tool to transform and deploy CPU microcode update for x86. Name: microcode_ctl Version: 2.1 -Release: 61%{?dist} +Release: 61.6%{?dist} Epoch: 2 Group: System Environment/Base License: GPLv2+ and Redistributable, no modification permitted @@ -95,10 +94,13 @@ Patch6: microcode_ctl-ignore-first-directory-level-in-archive.patch Buildroot: %{_tmppath}/%{name}-%{version}-root ExclusiveArch: %{ix86} x86_64 BuildRequires: systemd-units -Requires(post): systemd -Requires(preun): systemd -Requires(postun): systemd -Requires(posttrans): kernel +# hexdump is used in gen_provides.sh +BuildRequires: coreutils util-linux +Requires: coreutils +Requires(post): systemd coreutils +Requires(preun): systemd coreutils +Requires(postun): systemd coreutils +Requires(posttrans): dracut coreutils %global _use_internal_dependency_generator 0 %define __find_provides "%{SOURCE200}" @@ -156,7 +158,7 @@ cp "%{SOURCE3}" intel-ucode/ sed "%{SOURCE40}" \ -e "s/@DATE@/2019-05-09/g" \ -e "s/@VERSION@/%{version}-%{release}/g" \ - -e "s|@MICROCODE_URL@|https://downloadcenter.intel.com/download/%{intel_ucode_file_id}|g" > "%{i_m2u_man}" + -e "s|@MICROCODE_URL@|https://github.com/intel/Intel-Linux-Processor-Microcode-Data-Files|g" > "%{i_m2u_man}" %install rm -rf %{buildroot} @@ -273,14 +275,113 @@ exit 0 # dependency, it is pointless at best to regenerate the initramfs, # and also does not work with rpm-ostree: # https://bugzilla.redhat.com/show_bug.cgi?id=1199582 +# https://bugzilla.redhat.com/show_bug.cgi?id=1530400 +[ -d /run/systemd/system ] || exit 0 + +# We can't simply update all initramfs images, since "dracut --regenerate-all" +# generates initramfs even for removed kernels and if dracut generates botched +# initramfs image, that results in unbootable system, even with older kernels +# that can't be used as a fallback: +# https://bugzilla.redhat.com/show_bug.cgi?id=1420180 +# https://access.redhat.com/support/cases/#/case/01779274 +# https://access.redhat.com/support/cases/#/case/01814106 # -# Also check that the running kernel is actually installed: -# https://bugzilla.redhat.com/show_bug.cgi?id=1591664 -# We use the presence of symvers file as an indicator, the check similar -# to what weak-modules script does. -if [ -d /run/systemd/system -a -e "/boot/symvers-$(uname -r).gz" ]; then - dracut -f -fi +# ...and we can't simply limit ourselves to updating only the currently +# running kernel, as this doesn't work well with cases where kernel +# is installed before the updated microcode, or in the same transaction. +# And we can't rely on late update either, due to issues like this: +# https://bugzilla.redhat.com/show_bug.cgi?id=1710445 +# +# ...and there are also issues with setups with increased "installonly_limit" +# in /etc/yum.conf, which could lead to unacceptably long package installation +# times. +# +# So, in the end, we try to grab no more than 2 most recently installed kernels +# that are installed after the currently running one (with the currently running +# kernel that makes up to 3 in total, the default "installonly_limit" value) +# as a kernel package selection heuristic that tries to accomodate both the need +# to put the latest microcode in freshly installed kernels and also addresses +# existing concerns. +# +# For RPM selection, kernel flavours (like "debug" or "kdump" or "zfcp", +# with only the former being relevant to x86 architecture) are a part or RPM +# name; it's also a part of uname, with different separator used in RHEL 6/7 +# and RHEL 8. RT kernel, however, is special, as "rt" is another part +# of RPM name and it has its own versioning scheme both in NVR and uname. +# And there's the kernel package split in RHEL 8, so one should look for *-core +# and not the main package. +pkgs="kernel kernel-debug kernel-rt kernel-rt-debug" +qf='%%{NAME} %%{VERSION}-%%{RELEASE}.%%{ARCH} %%{installtime}\n' +: "${MICROCODE_RPM_KVER_LIMIT=2}" + +rpm -qa --qf "${qf}" ${pkgs} | sort -r -n -k'3,3' | { + kver_cnt=0 + processed="" + skipped="" + skip=0 + + while read -r pkgname vra install_ts; do + flavour='' + + # For x86, only "debug" flavour exists in RHEL 8 + [ "x${pkgname%*-debug}" = "x${pkgname}" ] \ + || flavour='.debug' + + kver_cnt="$((kver_cnt + 1))" + kver_uname="${vra}${flavour}" + + # Also check that the kernel is actually installed: + # https://bugzilla.redhat.com/show_bug.cgi?id=1591664 + # We use the presence of symvers file as an indicator, the check + # similar to what weak-modules script does. + # + # XXX: Not sure if this check is still needed, since we now + # iterate over the rpm output. + [ -e "/boot/symvers-${kver_uname}.gz" ] || continue + # Check that modules.dep for the kernel is present as well, + # otherwise dracut complains with "/lib/modules/.../modules.dep + # is missing. Did you run depmod?". + [ -e "/lib/modules/${kver_uname}/modules.dep" ] || continue + + # We update the kernels with the same uname as the running kernel + # regardless of the selected limit + if [ "x$(uname -r)" = "x${kver_uname}" \ + -o \( "${kver_cnt}" -le "${MICROCODE_RPM_KVER_LIMIT}" \ + -a "${skip}" = 0 \) ] + then + dracut -f --kver "${kver_uname}" + + processed="${processed} ${pkgname}-${vra}" + else + skipped="${skipped} ${pkgname}-${vra}" + fi + + # The packages are processed until a package with the same uname + # as the running kernel is hit (since they are sorted + # in the descending installation time stamp older). + [ "x$(uname -r)" != "x${kver_uname}" ] || skip=1 + done + + if [ -n "${skipped}" ]; then + skip_msg="After installation of a new version of microcode_ctl package, +initramfs hasn't been re-generated for all the installed kernel packages. +The following kernel packages have been skipped:${skipped}. +Please re-generate initramfs manually for these kernel packages with the +\"dracut -f --kver KERNEL_VERSION\" command in order to get the latest +Intel CPU microcode included into early initramfs image for it, if needed." + + if [ -e /usr/bin/logger ]; then + echo "${skip_msg}" | + /usr/bin/logger -p syslog.notice -t microcode_ctl + fi + + if [ -e /dev/kmsg ]; then + echo "${skip_msg}" > /dev/kmsg + fi + fi +} + +exit 0 %global rpm_state_dir %{_localstatedir}/lib/rpm-state @@ -317,7 +418,7 @@ if [ -e "%{update_ucode}" ]; then %{update_ucode} --action remove --cleanup \ "%{rpm_state_dir}/microcode_ctl_un_intel-ucode_diff" \ - "%{rpm_state_dir}/microcode_ctl_un_ucode_caveats_diff" || exit 0 + "%{rpm_state_dir}/microcode_ctl_un_ucode_caveats_diff" || : rm -f "%{rpm_state_dir}/microcode_ctl_un_ucode_caveats_after" rm -f "%{rpm_state_dir}/microcode_ctl_un_ucode_caveats_diff" @@ -350,10 +451,10 @@ rm -f "%{rpm_state_dir}/microcode_ctl_un_file_list" exit 0 -%triggerin -- kernel +%triggerin -- kernel, kernel-debug, kernel-rt, kernel-rt-debug %{update_ucode} -%triggerpostun -- kernel +%triggerpostun -- kernel, kernel-debug, kernel-rt, kernel-rt-debug %{update_ucode} @@ -373,6 +474,76 @@ rm -rf %{buildroot} %changelog +* Thu Jun 04 2020 Eugene Syromiatnikov - 2:2.1-61.6 +- Avoid temporary file creation, used for here-documents in check_caveats. + +* Thu Jun 04 2020 Eugene Syromiatnikov - 2:2.1-61.5 +- Update Intel CPU microcode to microcode-20200602 release, addresses + CVE-2020-0543, CVE-2020-0548, CVE-2020-0549 (#1827189): + - Update of 06-2d-06/0x6d (SNB-E/EN/EP C1/M0) microcode from revision 0x61f + up to 0x621; + - Update of 06-2d-07/0x6d (SNB-E/EN/EP C2/M1) microcode from revision 0x718 + up to 0x71a; + - Update of 06-3c-03/0x32 (HSW C0) microcode from revision 0x27 up to 0x28; + - Update of 06-3d-04/0xc0 (BDW-U/Y E0/F0) microcode from revision 0x2e + up to 0x2f; + - Update of 06-45-01/0x72 (HSW-U C0/D0) microcode from revision 0x25 + up to 0x26; + - Update of 06-46-01/0x32 (HSW-H C0) microcode from revision 0x1b up to 0x1c; + - Update of 06-47-01/0x22 (BDW-H/Xeon E3 E0/G0) microcode from revision 0x21 + up to 0x22; + - Update of 06-4e-03/0xc0 (SKL-U/Y D0) microcode from revision 0xd6 + up to 0xdc; + - Update of 06-55-03/0x97 (SKX-SP B1) microcode from revision 0x1000151 + up to 0x1000157; + - Update of 06-55-04/0xb7 (SKX-SP H0/M0/U0, SKX-D M1) microcode + (in intel-06-55-04/intel-ucode/06-55-04) from revision 0x2000065 + up to 0x2006906; + - Update of 06-55-06/0xbf (CLX-SP B0) microcode from revision 0x400002c + up to 0x4002f01; + - Update of 06-55-07/0xbf (CLX-SP B1) microcode from revision 0x500002c + up to 0x5002f01; + - Update of 06-5e-03/0x36 (SKL-H/S R0/N0) microcode from revision 0xd6 + up to 0xdc; + - Update of 06-7e-05/0x80 (ICL-U/Y D1) microcode from revision 0x46 + up to 0x78; + - Update of 06-8e-09/0x10 (AML-Y22 H0) microcode from revision 0xca + up to 0xd6; + - Update of 06-8e-09/0xc0 (KBL-U/Y H0) microcode from revision 0xca + up to 0xd6; + - Update of 06-8e-0a/0xc0 (CFL-U43e D0) microcode from revision 0xca + up to 0xd6; + - Update of 06-8e-0b/0xd0 (WHL-U W0) microcode from revision 0xca + up to 0xd6; + - Update of 06-8e-0c/0x94 (AML-Y42 V0, CML-Y42 V0, WHL-U V0) microcode + from revision 0xca up to 0xd6; + - Update of 06-9e-09/0x2a (KBL-G/H/S/X/Xeon E3 B0) microcode from revision + 0xca up to 0xd6; + - Update of 06-9e-0a/0x22 (CFL-H/S/Xeon E3 U0) microcode from revision 0xca + up to 0xd6; + - Update of 06-9e-0b/0x02 (CFL-S B0) microcode from revision 0xca up to 0xd6; + - Update of 06-9e-0c/0x22 (CFL-H/S P0) microcode from revision 0xca + up to 0xd6; + - Update of 06-9e-0d/0x22 (CFL-H R0) microcode from revision 0xca up to 0xd6. +- Change the URL in the intel-microcode2ucode.8 to point to the GitHub + repository since the microcode download section at Intel Download Center + does not exist anymore. + +* Thu Jun 04 2020 Eugene Syromiatnikov - 2:2.1-61.4 +- Narrow down SKL-SP/W/X blacklist to exclude Server/FPGA/Fabric segment + models. + +* Thu Jun 04 2020 Eugene Syromiatnikov - 2:2.1-61.3 +- Re-generate initramfs not only for the currently running kernel, + but for several recently installed kernels as well. + +* Thu Jun 04 2020 Eugene Syromiatnikov - 2:2.1-61.2 +- Avoid find being SIGPIPE'd on early "grep -q" exit in the dracut script. + +* Thu Jun 04 2020 Eugene Syromiatnikov - 2:2.1-61.1 +- Update stale posttrans dependency, add triggers for proper handling + of the debug kernel flavour along with kernel-rt. + * Wed Nov 20 2019 Eugene Syromiatnikov - 2:2.1-61 - Do not update 06-55-04 (SKL-SP/W/X) to revision 0x2000065, use 0x2000064 by default (#1774329).