is_cpu_vulnerable: implement check for multi-arm systems

This commit is contained in:
Stéphane Lesimple 2018-01-18 18:50:19 +01:00
parent 7fa2d6347b
commit 56d4f82484

View File

@ -177,9 +177,9 @@ is_cpu_vulnerable()
# (note that in shell, a return of 0 is success) # (note that in shell, a return of 0 is success)
# by default, everything is vulnerable, we work in a "whitelist" logic here. # by default, everything is vulnerable, we work in a "whitelist" logic here.
# usage: is_cpu_vulnerable 2 && do something if vulnerable # usage: is_cpu_vulnerable 2 && do something if vulnerable
variant1=0 variant1=''
variant2=0 variant2=''
variant3=0 variant3=''
# we also set a friendly name for the CPU to be used in the script if needed # we also set a friendly name for the CPU to be used in the script if needed
cpu_friendly_name=$(grep '^model name' /proc/cpuinfo | cut -d: -f2- | head -1) cpu_friendly_name=$(grep '^model name' /proc/cpuinfo | cut -d: -f2- | head -1)
@ -191,18 +191,29 @@ is_cpu_vulnerable()
# model name : Intel(R) Atom(TM) CPU N270 @ 1.60GHz # model name : Intel(R) Atom(TM) CPU N270 @ 1.60GHz
# model name : Intel(R) Atom(TM) CPU 330 @ 1.60GHz # model name : Intel(R) Atom(TM) CPU 330 @ 1.60GHz
if grep -qE '^model name.+ Intel\(R\) (Atom\(TM\) CPU +(S|D|N|230|330)|CPU N[0-9]{3} )' /proc/cpuinfo; then if grep -qE '^model name.+ Intel\(R\) (Atom\(TM\) CPU +(S|D|N|230|330)|CPU N[0-9]{3} )' /proc/cpuinfo; then
variant2=1 variant1=vuln
variant3=1 [ -z "$variant2" ] && variant2=immune
[ -z "$variant3" ] && variant3=immune
fi fi
elif grep -q AuthenticAMD /proc/cpuinfo; then elif grep -q AuthenticAMD /proc/cpuinfo; then
# AMD revised their statement about variant2 => vulnerable # AMD revised their statement about variant2 => vulnerable
# https://www.amd.com/en/corporate/speculative-execution # https://www.amd.com/en/corporate/speculative-execution
variant3=1 variant1=vuln
elif grep -qi 'CPU implementer\s*:\s*0x41' /proc/cpuinfo; then variant2=vuln
[ -z "$variant3" ] && variant3=immune
elif grep -qi 'CPU implementer[[:space:]]*:[[:space:]]*0x41' /proc/cpuinfo; then
# ARM # ARM
# reference: https://developer.arm.com/support/security-update # reference: https://developer.arm.com/support/security-update
cpupart=$(awk '/CPU part/ {print $4;exit}' /proc/cpuinfo) # some devices (phones or other) have several ARMs and as such different part numbers,
cpuarch=$(awk '/CPU architecture/ {print $3;exit}' /proc/cpuinfo) # an example is "bigLITTLE". we shouldn't rely on the first CPU only, so we check the whole list
cpupart_list=$(awk '/CPU part/ {print $4}' /proc/cpuinfo)
cpuarch_list=$(awk '/CPU architecture/ {print $3}' /proc/cpuinfo)
i=0
for cpupart in $cpupart_list
do
i=$(( i + 1 ))
cpuarch=$(echo $cpuarch_list | awk '{ print $'$i' }')
_debug "checking cpu$i: <$cpupart> <$cpuarch>"
# some kernels report AArch64 instead of 8 # some kernels report AArch64 instead of 8
[ "$cpuarch" = "AArch64" ] && cpuarch=8 [ "$cpuarch" = "AArch64" ] && cpuarch=8
if [ -n "$cpupart" -a -n "$cpuarch" ]; then if [ -n "$cpupart" -a -n "$cpuarch" ]; then
@ -212,23 +223,43 @@ is_cpu_vulnerable()
# model R7 R8 A9 A15 A17 A57 A72 A73 A75 # model R7 R8 A9 A15 A17 A57 A72 A73 A75
# part ? ? 0xc09 0xc0f 0xc0e 0xd07 0xd08 0xd09 0xd0a # part ? ? 0xc09 0xc0f 0xc0e 0xd07 0xd08 0xd09 0xd0a
# arch 7? 7? 7 7 7 8 8 8 8 # arch 7? 7? 7 7 7 8 8 8 8
#
# variant 1 & variant 2
if [ "$cpuarch" = 7 ] && echo "$cpupart" | grep -Eq '^0x(c09|c0f|c0e)$'; then if [ "$cpuarch" = 7 ] && echo "$cpupart" | grep -Eq '^0x(c09|c0f|c0e)$'; then
# armv7 vulnerable chips # armv7 vulnerable chips
: _debug "checking cpu$i: this armv7 vulnerable to spectre 1 & 2"
variant1=vuln
variant2=vuln
elif [ "$cpuarch" = 8 ] && echo "$cpupart" | grep -Eq '^0x(d07|d08|d09|d0a)$'; then elif [ "$cpuarch" = 8 ] && echo "$cpupart" | grep -Eq '^0x(d07|d08|d09|d0a)$'; then
# armv8 vulnerable chips # armv8 vulnerable chips
: _debug "checking cpu$i: this armv8 vulnerable to spectre 1 & 2"
variant1=vuln
variant2=vuln
else else
_debug "checking cpu$i: this arm non vulnerable to 1 & 2"
# others are not vulnerable # others are not vulnerable
variant1=1 [ -z "$variant1" ] && variant1=immune
variant2=1 [ -z "$variant2" ] && variant2=immune
fi fi
# for variant3, only A75 is vulnerable # for variant3, only A75 is vulnerable
if ! [ "$cpuarch" = 8 -a "$cpupart" = 0xd0a ]; then if [ "$cpuarch" = 8 -a "$cpupart" = 0xd0a ]; then
variant3=1 _debug "checking cpu$i: arm A75 vulnerable to meltdown"
variant3=vuln
else
_debug "checking cpu$i: this arm non vulnerable to meltdown"
[ -z "$variant3" ] && variant3=immune
fi fi
fi fi
_debug "is_cpu_vulnerable: for cpu$i and so far, we have <$variant1> <$variant2> <$variant3>"
done
fi fi
_debug "is_cpu_vulnerable: temp results are <$variant1> <$variant2> <$variant3>"
# if at least one of the cpu is vulnerable, then the system is vulnerable
[ "$variant1" = "immune" ] && variant1=1 || variant1=0
[ "$variant2" = "immune" ] && variant2=1 || variant2=0
[ "$variant3" = "immune" ] && variant3=1 || variant3=0
_debug "is_cpu_vulnerable: final results are <$variant1> <$variant2> <$variant3>"
[ "$1" = 1 ] && return $variant1 [ "$1" = 1 ] && return $variant1
[ "$1" = 2 ] && return $variant2 [ "$1" = 2 ] && return $variant2