# vim: set ts=4 sw=4 sts=4 et: ############################### # CVE-2018-3639, Variant 4, SSB, Speculative Store Bypass check_CVE_2018_3639() { check_cve 'CVE-2018-3639' } check_CVE_2018_3639_linux() { local status sys_interface_available msg kernel_ssb kernel_ssbd_enabled mitigated_processes status=UNK sys_interface_available=0 msg='' if sys_interface_check "$VULN_SYSFS_BASE/spec_store_bypass"; then # this kernel has the /sys interface, trust it over everything sys_interface_available=1 status=$ret_sys_interface_check_status fi if [ "$opt_sysfs_only" != 1 ]; then pr_info_nol "* Kernel supports disabling speculative store bypass (SSB): " if [ "$opt_live" = 1 ]; then if grep -Eq 'Speculation.?Store.?Bypass:' "$g_procfs/self/status" 2>/dev/null; then kernel_ssb="found in $g_procfs/self/status" pr_debug "found Speculation.Store.Bypass: in $g_procfs/self/status" fi fi # arm64 kernels can have cpu_show_spec_store_bypass with ARM64_SSBD, so exclude them if [ -z "$kernel_ssb" ] && [ -n "$g_kernel" ] && ! grep -q 'arm64_sys_' "$g_kernel"; then kernel_ssb=$("${opt_arch_prefix}strings" "$g_kernel" | grep spec_store_bypass | head -n1) [ -n "$kernel_ssb" ] && kernel_ssb="found $kernel_ssb in kernel" fi # arm64 kernels can have cpu_show_spec_store_bypass with ARM64_SSBD, so exclude them if [ -z "$kernel_ssb" ] && [ -n "$opt_map" ] && ! grep -q 'arm64_sys_' "$opt_map"; then kernel_ssb=$(grep spec_store_bypass "$opt_map" | awk '{print $3}' | head -n1) [ -n "$kernel_ssb" ] && kernel_ssb="found $kernel_ssb in System.map" fi # arm64 only: if [ -z "$kernel_ssb" ] && [ -n "$opt_map" ]; then kernel_ssb=$(grep -w cpu_enable_ssbs "$opt_map" | awk '{print $3}' | head -n1) [ -n "$kernel_ssb" ] && kernel_ssb="found $kernel_ssb in System.map" fi if [ -z "$kernel_ssb" ] && [ -n "$opt_config" ]; then kernel_ssb=$(grep -w 'CONFIG_ARM64_SSBD=y' "$opt_config") [ -n "$kernel_ssb" ] && kernel_ssb="CONFIG_ARM64_SSBD enabled in kconfig" fi if [ -z "$kernel_ssb" ] && [ -n "$g_kernel" ]; then # this string only appears in kernel if CONFIG_ARM64_SSBD is set kernel_ssb=$(grep -w "Speculative Store Bypassing Safe (SSBS)" "$g_kernel") [ -n "$kernel_ssb" ] && kernel_ssb="found 'Speculative Store Bypassing Safe (SSBS)' in kernel" fi # /arm64 only if [ -n "$kernel_ssb" ]; then pstatus green YES "$kernel_ssb" else pstatus yellow NO fi kernel_ssbd_enabled=-1 if [ "$opt_live" = 1 ]; then # https://elixir.bootlin.com/linux/v5.0/source/fs/proc/array.c#L340 pr_info_nol "* SSB mitigation is enabled and active: " if grep -Eq 'Speculation.?Store.?Bypass:[[:space:]]+thread' "$g_procfs/self/status" 2>/dev/null; then kernel_ssbd_enabled=1 pstatus green YES "per-thread through prctl" elif grep -Eq 'Speculation.?Store.?Bypass:[[:space:]]+globally mitigated' "$g_procfs/self/status" 2>/dev/null; then kernel_ssbd_enabled=2 pstatus green YES "global" elif grep -Eq 'Speculation.?Store.?Bypass:[[:space:]]+vulnerable' "$g_procfs/self/status" 2>/dev/null; then kernel_ssbd_enabled=0 pstatus yellow NO elif grep -Eq 'Speculation.?Store.?Bypass:[[:space:]]+not vulnerable' "$g_procfs/self/status" 2>/dev/null; then kernel_ssbd_enabled=-2 pstatus blue NO "not vulnerable" elif grep -Eq 'Speculation.?Store.?Bypass:[[:space:]]+unknown' "$g_procfs/self/status" 2>/dev/null; then kernel_ssbd_enabled=0 pstatus blue NO else pstatus blue UNKNOWN "unknown value: $(grep -E 'Speculation.?Store.?Bypass:' "$g_procfs/self/status" 2>/dev/null | cut -d: -f2-)" fi if [ "$kernel_ssbd_enabled" = 1 ]; then pr_info_nol "* SSB mitigation currently active for selected processes: " # silence grep's stderr here to avoid ENOENT errors from processes that have exited since the shell's expansion of the * mitigated_processes=$(find /proc -mindepth 2 -maxdepth 2 -type f -name status -print0 2>/dev/null | xargs -r0 grep -El 'Speculation.?Store.?Bypass:[[:space:]]+thread (force )?mitigated' 2>/dev/null | sed s/status/exe/ | xargs -r -n1 readlink -f 2>/dev/null | xargs -r -n1 basename | sort -u | tr "\n" " " | sed 's/ $//') if [ -n "$mitigated_processes" ]; then pstatus green YES "$mitigated_processes" else pstatus yellow NO "no process found using SSB mitigation through prctl" fi fi fi elif [ "$sys_interface_available" = 0 ]; then # we have no sysfs but were asked to use it only! msg="/sys vulnerability interface use forced, but it's not available!" status=UNK fi if ! is_cpu_affected "$cve"; then # override status & msg in case CPU is not vulnerable after all pvulnstatus "$cve" OK "your CPU vendor reported your CPU model as not affected" elif [ -z "$msg" ] || [ "$msg" = "Vulnerable" ]; then # if msg is empty, sysfs check didn't fill it, rely on our own test if [ -n "$cap_ssbd" ]; then if [ -n "$kernel_ssb" ]; then if [ "$opt_live" = 1 ]; then if [ "$kernel_ssbd_enabled" -gt 0 ]; then pvulnstatus "$cve" OK "your CPU and kernel both support SSBD and mitigation is enabled" else pvulnstatus "$cve" VULN "your CPU and kernel both support SSBD but the mitigation is not active" fi else pvulnstatus "$cve" OK "your system provides the necessary tools for software mitigation" fi else pvulnstatus "$cve" VULN "your kernel needs to be updated" explain "You have a recent-enough CPU microcode but your kernel is too old to use the new features exported by your CPU's microcode. If you're using a distro kernel, upgrade your distro to get the latest kernel available. Otherwise, recompile the kernel from recent-enough sources." fi else if [ -n "$kernel_ssb" ]; then pvulnstatus "$cve" VULN "Your CPU doesn't support SSBD" explain "Your kernel is recent enough to use the CPU microcode features for mitigation, but your CPU microcode doesn't actually provide the necessary features for the kernel to use. The microcode of your CPU hence needs to be upgraded. This is usually done at boot time by your kernel (the upgrade is not persistent across reboots which is why it's done at each boot). If you're using a distro, make sure you are up to date, as microcode updates are usually shipped alongside with the distro kernel. Availability of a microcode update for you CPU model depends on your CPU vendor. You can usually find out online if a microcode update is available for your CPU by searching for your CPUID (indicated in the Hardware Check section)." else pvulnstatus "$cve" VULN "Neither your CPU nor your kernel support SSBD" explain "Both your CPU microcode and your kernel are lacking support for mitigation. If you're using a distro kernel, upgrade your distro to get the latest kernel available. Otherwise, recompile the kernel from recent-enough sources. The microcode of your CPU also needs to be upgraded. This is usually done at boot time by your kernel (the upgrade is not persistent across reboots which is why it's done at each boot). If you're using a distro, make sure you are up to date, as microcode updates are usually shipped alongside with the distro kernel. Availability of a microcode update for you CPU model depends on your CPU vendor. You can usually find out online if a microcode update is available for your CPU by searching for your CPUID (indicated in the Hardware Check section)." fi fi else pvulnstatus "$cve" "$status" "$msg" fi } check_CVE_2018_3639_bsd() { local kernel_ssb ssb_enabled ssb_active pr_info_nol "* Kernel supports speculation store bypass: " if sysctl hw.spec_store_bypass_disable >/dev/null 2>&1; then kernel_ssb=1 pstatus green YES else kernel_ssb=0 pstatus yellow NO fi pr_info_nol "* Speculation store bypass is administratively enabled: " ssb_enabled=$(sysctl -n hw.spec_store_bypass_disable 2>/dev/null) pr_debug "hw.spec_store_bypass_disable=$ssb_enabled" case "$ssb_enabled" in 0) pstatus yellow NO "disabled" ;; 1) pstatus green YES "enabled" ;; 2) pstatus green YES "auto mode" ;; *) pstatus yellow NO "unavailable" ;; esac pr_info_nol "* Speculation store bypass is currently active: " ssb_active=$(sysctl -n hw.spec_store_bypass_disable_active 2>/dev/null) pr_debug "hw.spec_store_bypass_disable_active=$ssb_active" case "$ssb_active" in 1) pstatus green YES ;; *) pstatus yellow NO ;; esac if ! is_cpu_affected "$cve"; then pvulnstatus "$cve" OK "your CPU vendor reported your CPU model as not affected" else if [ "$ssb_active" = 1 ]; then pvulnstatus "$cve" OK "SSBD mitigates the vulnerability" elif [ -n "$cap_ssbd" ]; then if [ "$kernel_ssb" = 1 ]; then pvulnstatus "$cve" VULN "you need to enable SSBD through sysctl to mitigate the vulnerability" explain "To enable SSBD right now, you can run \`sysctl hw.spec_store_bypass_disable=2'. To make this change persistent across reboots, you can add 'sysctl hw.spec_store_bypass_disable=2' to /etc/sysctl.conf." else pvulnstatus "$cve" VULN "your kernel needs to be updated" fi else if [ "$kernel_ssb" = 1 ]; then pvulnstatus "$cve" VULN "Your CPU doesn't support SSBD" else pvulnstatus "$cve" VULN "Neither your CPU nor your kernel support SSBD" fi fi fi }