요약·해설과 원문, 전문 번역을 서로 분리했습니다. API 이름, symbol, source path는 원문 표기를 사용합니다.
1. 요약·해설
원문의 핵심 논리와 kernel programming 관점의 보충 설명입니다. 아래의 전문 번역과는 별도로 작성했습니다.
도메인별 공격 시나리오
spectre.rst:146-323사용자와 커널, 프로세스 사이, 게스트와 호스트, 게스트 사이의 공격 경로와 방어 경계를 설명합니다.
sysfs 완화 상태
spectre.rst:324-451Spectre v1·v2 상태 파일과 IBPB, STIBP, RSB, PBRSB, BHI 보고 문자열을 해설합니다.
커널·사용자·VM 완화
spectre.rst:452-589nospec, LFENCE, retpoline, Enhanced IBRS, 마이크로코드와 가상화 경계 완화를 정리합니다.
운영 제어와 참고문헌
spectre.rst:590-725커널 명령줄 옵션, 보안 수준별 선택 기준과 원문 참고문헌 13개를 보존합니다.
2. 영어 원문 전체
번역 기준이 된 Linux v6.18.37 원문입니다. 줄 번호는 이 버전의 파일 좌표입니다.
원문 전체 펼치기
.. SPDX-License-Identifier: GPL-2.0
Spectre Side Channels
=====================
Spectre is a class of side channel attacks that exploit branch prediction
and speculative execution on modern CPUs to read memory, possibly
bypassing access controls. Speculative execution side channel exploits
do not modify memory but attempt to infer privileged data in the memory.
This document covers Spectre variant 1 and Spectre variant 2.
Affected processors
-------------------
Speculative execution side channel methods affect a wide range of modern
high performance processors, since most modern high speed processors
use branch prediction and speculative execution.
The following CPUs are vulnerable:
- Intel Core, Atom, Pentium, and Xeon processors
- AMD Phenom, EPYC, and Zen processors
- IBM POWER and zSeries processors
- Higher end ARM processors
- Apple CPUs
- Higher end MIPS CPUs
- Likely most other high performance CPUs. Contact your CPU vendor for details.
Whether a processor is affected or not can be read out from the Spectre
vulnerability files in sysfs. See :ref:`spectre_sys_info`.
Related CVEs
------------
The following CVE entries describe Spectre variants:
============= ======================= ==========================
CVE-2017-5753 Bounds check bypass Spectre variant 1
CVE-2017-5715 Branch target injection Spectre variant 2
CVE-2019-1125 Spectre v1 swapgs Spectre variant 1 (swapgs)
============= ======================= ==========================
Problem
-------
CPUs use speculative operations to improve performance. That may leave
traces of memory accesses or computations in the processor's caches,
buffers, and branch predictors. Malicious software may be able to
influence the speculative execution paths, and then use the side effects
of the speculative execution in the CPUs' caches and buffers to infer
privileged data touched during the speculative execution.
Spectre variant 1 attacks take advantage of speculative execution of
conditional branches, while Spectre variant 2 attacks use speculative
execution of indirect branches to leak privileged memory.
See :ref:`[1] <spec_ref1>` :ref:`[5] <spec_ref5>` :ref:`[6] <spec_ref6>`
:ref:`[7] <spec_ref7>` :ref:`[10] <spec_ref10>` :ref:`[11] <spec_ref11>`.
Spectre variant 1 (Bounds Check Bypass)
---------------------------------------
The bounds check bypass attack :ref:`[2] <spec_ref2>` takes advantage
of speculative execution that bypasses conditional branch instructions
used for memory access bounds check (e.g. checking if the index of an
array results in memory access within a valid range). This results in
memory accesses to invalid memory (with out-of-bound index) that are
done speculatively before validation checks resolve. Such speculative
memory accesses can leave side effects, creating side channels which
leak information to the attacker.
There are some extensions of Spectre variant 1 attacks for reading data
over the network, see :ref:`[12] <spec_ref12>`. However such attacks
are difficult, low bandwidth, fragile, and are considered low risk.
Note that, despite "Bounds Check Bypass" name, Spectre variant 1 is not
only about user-controlled array bounds checks. It can affect any
conditional checks. The kernel entry code interrupt, exception, and NMI
handlers all have conditional swapgs checks. Those may be problematic
in the context of Spectre v1, as kernel code can speculatively run with
a user GS.
Spectre variant 2 (Branch Target Injection)
-------------------------------------------
The branch target injection attack takes advantage of speculative
execution of indirect branches :ref:`[3] <spec_ref3>`. The indirect
branch predictors inside the processor used to guess the target of
indirect branches can be influenced by an attacker, causing gadget code
to be speculatively executed, thus exposing sensitive data touched by
the victim. The side effects left in the CPU's caches during speculative
execution can be measured to infer data values.
.. _poison_btb:
In Spectre variant 2 attacks, the attacker can steer speculative indirect
branches in the victim to gadget code by poisoning the branch target
buffer of a CPU used for predicting indirect branch addresses. Such
poisoning could be done by indirect branching into existing code,
with the address offset of the indirect branch under the attacker's
control. Since the branch prediction on impacted hardware does not
fully disambiguate branch address and uses the offset for prediction,
this could cause privileged code's indirect branch to jump to a gadget
code with the same offset.
The most useful gadgets take an attacker-controlled input parameter (such
as a register value) so that the memory read can be controlled. Gadgets
without input parameters might be possible, but the attacker would have
very little control over what memory can be read, reducing the risk of
the attack revealing useful data.
One other variant 2 attack vector is for the attacker to poison the
return stack buffer (RSB) :ref:`[13] <spec_ref13>` to cause speculative
subroutine return instruction execution to go to a gadget. An attacker's
imbalanced subroutine call instructions might "poison" entries in the
return stack buffer which are later consumed by a victim's subroutine
return instructions. This attack can be mitigated by flushing the return
stack buffer on context switch, or virtual machine (VM) exit.
On systems with simultaneous multi-threading (SMT), attacks are possible
from the sibling thread, as level 1 cache and branch target buffer
(BTB) may be shared between hardware threads in a CPU core. A malicious
program running on the sibling thread may influence its peer's BTB to
steer its indirect branch speculations to gadget code, and measure the
speculative execution's side effects left in level 1 cache to infer the
victim's data.
Yet another variant 2 attack vector is for the attacker to poison the
Branch History Buffer (BHB) to speculatively steer an indirect branch
to a specific Branch Target Buffer (BTB) entry, even if the entry isn't
associated with the source address of the indirect branch. Specifically,
the BHB might be shared across privilege levels even in the presence of
Enhanced IBRS.
Previously the only known real-world BHB attack vector was via unprivileged
eBPF. Further research has found attacks that don't require unprivileged eBPF.
For a full mitigation against BHB attacks it is recommended to set BHI_DIS_S or
use the BHB clearing sequence.
Attack scenarios
----------------
The following list of attack scenarios have been anticipated, but may
not cover all possible attack vectors.
1. A user process attacking the kernel
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Spectre variant 1
~~~~~~~~~~~~~~~~~
The attacker passes a parameter to the kernel via a register or
via a known address in memory during a syscall. Such parameter may
be used later by the kernel as an index to an array or to derive
a pointer for a Spectre variant 1 attack. The index or pointer
is invalid, but bound checks are bypassed in the code branch taken
for speculative execution. This could cause privileged memory to be
accessed and leaked.
For kernel code that has been identified where data pointers could
potentially be influenced for Spectre attacks, new "nospec" accessor
macros are used to prevent speculative loading of data.
Spectre variant 1 (swapgs)
~~~~~~~~~~~~~~~~~~~~~~~~~~
An attacker can train the branch predictor to speculatively skip the
swapgs path for an interrupt or exception. If they initialize
the GS register to a user-space value, if the swapgs is speculatively
skipped, subsequent GS-related percpu accesses in the speculation
window will be done with the attacker-controlled GS value. This
could cause privileged memory to be accessed and leaked.
For example:
::
if (coming from user space)
swapgs
mov %gs:<percpu_offset>, %reg
mov (%reg), %reg1
When coming from user space, the CPU can speculatively skip the
swapgs, and then do a speculative percpu load using the user GS
value. So the user can speculatively force a read of any kernel
value. If a gadget exists which uses the percpu value as an address
in another load/store, then the contents of the kernel value may
become visible via an L1 side channel attack.
A similar attack exists when coming from kernel space. The CPU can
speculatively do the swapgs, causing the user GS to get used for the
rest of the speculative window.
Spectre variant 2
~~~~~~~~~~~~~~~~~
A spectre variant 2 attacker can :ref:`poison <poison_btb>` the branch
target buffer (BTB) before issuing syscall to launch an attack.
After entering the kernel, the kernel could use the poisoned branch
target buffer on indirect jump and jump to gadget code in speculative
execution.
If an attacker tries to control the memory addresses leaked during
speculative execution, he would also need to pass a parameter to the
gadget, either through a register or a known address in memory. After
the gadget has executed, he can measure the side effect.
The kernel can protect itself against consuming poisoned branch
target buffer entries by using return trampolines (also known as
"retpoline") :ref:`[3] <spec_ref3>` :ref:`[9] <spec_ref9>` for all
indirect branches. Return trampolines trap speculative execution paths
to prevent jumping to gadget code during speculative execution.
x86 CPUs with Enhanced Indirect Branch Restricted Speculation
(Enhanced IBRS) available in hardware should use the feature to
mitigate Spectre variant 2 instead of retpoline. Enhanced IBRS is
more efficient than retpoline.
There may be gadget code in firmware which could be exploited with
Spectre variant 2 attack by a rogue user process. To mitigate such
attacks on x86, Indirect Branch Restricted Speculation (IBRS) feature
is turned on before the kernel invokes any firmware code.
2. A user process attacking another user process
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
A malicious user process can try to attack another user process,
either via a context switch on the same hardware thread, or from the
sibling hyperthread sharing a physical processor core on simultaneous
multi-threading (SMT) system.
Spectre variant 1 attacks generally require passing parameters
between the processes, which needs a data passing relationship, such
as remote procedure calls (RPC). Those parameters are used in gadget
code to derive invalid data pointers accessing privileged memory in
the attacked process.
Spectre variant 2 attacks can be launched from a rogue process by
:ref:`poisoning <poison_btb>` the branch target buffer. This can
influence the indirect branch targets for a victim process that either
runs later on the same hardware thread, or running concurrently on
a sibling hardware thread sharing the same physical core.
A user process can protect itself against Spectre variant 2 attacks
by using the prctl() syscall to disable indirect branch speculation
for itself. An administrator can also cordon off an unsafe process
from polluting the branch target buffer by disabling the process's
indirect branch speculation. This comes with a performance cost
from not using indirect branch speculation and clearing the branch
target buffer. When SMT is enabled on x86, for a process that has
indirect branch speculation disabled, Single Threaded Indirect Branch
Predictors (STIBP) :ref:`[4] <spec_ref4>` are turned on to prevent the
sibling thread from controlling branch target buffer. In addition,
the Indirect Branch Prediction Barrier (IBPB) is issued to clear the
branch target buffer when context switching to and from such process.
On x86, the return stack buffer is stuffed on context switch.
This prevents the branch target buffer from being used for branch
prediction when the return stack buffer underflows while switching to
a deeper call stack. Any poisoned entries in the return stack buffer
left by the previous process will also be cleared.
User programs should use address space randomization to make attacks
more difficult (Set /proc/sys/kernel/randomize_va_space = 1 or 2).
3. A virtualized guest attacking the host
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
The attack mechanism is similar to how user processes attack the
kernel. The kernel is entered via hyper-calls or other virtualization
exit paths.
For Spectre variant 1 attacks, rogue guests can pass parameters
(e.g. in registers) via hyper-calls to derive invalid pointers to
speculate into privileged memory after entering the kernel. For places
where such kernel code has been identified, nospec accessor macros
are used to stop speculative memory access.
For Spectre variant 2 attacks, rogue guests can :ref:`poison
<poison_btb>` the branch target buffer or return stack buffer, causing
the kernel to jump to gadget code in the speculative execution paths.
To mitigate variant 2, the host kernel can use return trampolines
for indirect branches to bypass the poisoned branch target buffer,
and flushing the return stack buffer on VM exit. This prevents rogue
guests from affecting indirect branching in the host kernel.
To protect host processes from rogue guests, host processes can have
indirect branch speculation disabled via prctl(). The branch target
buffer is cleared before context switching to such processes.
4. A virtualized guest attacking other guest
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
A rogue guest may attack another guest to get data accessible by the
other guest.
Spectre variant 1 attacks are possible if parameters can be passed
between guests. This may be done via mechanisms such as shared memory
or message passing. Such parameters could be used to derive data
pointers to privileged data in guest. The privileged data could be
accessed by gadget code in the victim's speculation paths.
Spectre variant 2 attacks can be launched from a rogue guest by
:ref:`poisoning <poison_btb>` the branch target buffer or the return
stack buffer. Such poisoned entries could be used to influence
speculation execution paths in the victim guest.
Linux kernel mitigates attacks to other guests running in the same
CPU hardware thread by flushing the return stack buffer on VM exit,
and clearing the branch target buffer before switching to a new guest.
If SMT is used, Spectre variant 2 attacks from an untrusted guest
in the sibling hyperthread can be mitigated by the administrator,
by turning off the unsafe guest's indirect branch speculation via
prctl(). A guest can also protect itself by turning on microcode
based mitigations (such as IBPB or STIBP on x86) within the guest.
.. _spectre_sys_info:
Spectre system information
--------------------------
The Linux kernel provides a sysfs interface to enumerate the current
mitigation status of the system for Spectre: whether the system is
vulnerable, and which mitigations are active.
The sysfs file showing Spectre variant 1 mitigation status is:
/sys/devices/system/cpu/vulnerabilities/spectre_v1
The possible values in this file are:
.. list-table::
* - 'Not affected'
- The processor is not vulnerable.
* - 'Vulnerable: __user pointer sanitization and usercopy barriers only; no swapgs barriers'
- The swapgs protections are disabled; otherwise it has
protection in the kernel on a case by case base with explicit
pointer sanitation and usercopy LFENCE barriers.
* - 'Mitigation: usercopy/swapgs barriers and __user pointer sanitization'
- Protection in the kernel on a case by case base with explicit
pointer sanitation, usercopy LFENCE barriers, and swapgs LFENCE
barriers.
However, the protections are put in place on a case by case basis,
and there is no guarantee that all possible attack vectors for Spectre
variant 1 are covered.
The spectre_v2 kernel file reports if the kernel has been compiled with
retpoline mitigation or if the CPU has hardware mitigation, and if the
CPU has support for additional process-specific mitigation.
This file also reports CPU features enabled by microcode to mitigate
attack between user processes:
1. Indirect Branch Prediction Barrier (IBPB) to add additional
isolation between processes of different users.
2. Single Thread Indirect Branch Predictors (STIBP) to add additional
isolation between CPU threads running on the same core.
These CPU features may impact performance when used and can be enabled
per process on a case-by-case base.
The sysfs file showing Spectre variant 2 mitigation status is:
/sys/devices/system/cpu/vulnerabilities/spectre_v2
The possible values in this file are:
- Kernel status:
======================================== =================================
'Not affected' The processor is not vulnerable
'Mitigation: None' Vulnerable, no mitigation
'Mitigation: Retpolines' Use Retpoline thunks
'Mitigation: LFENCE' Use LFENCE instructions
'Mitigation: Enhanced IBRS' Hardware-focused mitigation
'Mitigation: Enhanced IBRS + Retpolines' Hardware-focused + Retpolines
'Mitigation: Enhanced IBRS + LFENCE' Hardware-focused + LFENCE
======================================== =================================
- Firmware status: Show if Indirect Branch Restricted Speculation (IBRS) is
used to protect against Spectre variant 2 attacks when calling firmware (x86 only).
========== =============================================================
'IBRS_FW' Protection against user program attacks when calling firmware
========== =============================================================
- Indirect branch prediction barrier (IBPB) status for protection between
processes of different users. This feature can be controlled through
prctl() per process, or through kernel command line options. This is
an x86 only feature. For more details see below.
=================== ========================================================
'IBPB: disabled' IBPB unused
'IBPB: always-on' Use IBPB on all tasks
'IBPB: conditional' Use IBPB on SECCOMP or indirect branch restricted tasks
=================== ========================================================
- Single threaded indirect branch prediction (STIBP) status for protection
between different hyper threads. This feature can be controlled through
prctl per process, or through kernel command line options. This is x86
only feature. For more details see below.
==================== ========================================================
'STIBP: disabled' STIBP unused
'STIBP: forced' Use STIBP on all tasks
'STIBP: conditional' Use STIBP on SECCOMP or indirect branch restricted tasks
==================== ========================================================
- Return stack buffer (RSB) protection status:
============= ===========================================
'RSB filling' Protection of RSB on context switch enabled
============= ===========================================
- EIBRS Post-barrier Return Stack Buffer (PBRSB) protection status:
=========================== =======================================================
'PBRSB-eIBRS: SW sequence' CPU is affected and protection of RSB on VMEXIT enabled
'PBRSB-eIBRS: Vulnerable' CPU is vulnerable
'PBRSB-eIBRS: Not affected' CPU is not affected by PBRSB
=========================== =======================================================
- Branch History Injection (BHI) protection status:
.. list-table::
* - BHI: Not affected
- System is not affected
* - BHI: Retpoline
- System is protected by retpoline
* - BHI: BHI_DIS_S
- System is protected by BHI_DIS_S
* - BHI: SW loop, KVM SW loop
- System is protected by software clearing sequence
* - BHI: Vulnerable
- System is vulnerable to BHI
* - BHI: Vulnerable, KVM: SW loop
- System is vulnerable; KVM is protected by software clearing sequence
Full mitigation might require a microcode update from the CPU
vendor. When the necessary microcode is not available, the kernel will
report vulnerability.
Turning on mitigation for Spectre variant 1 and Spectre variant 2
-----------------------------------------------------------------
1. Kernel mitigation
^^^^^^^^^^^^^^^^^^^^
Spectre variant 1
~~~~~~~~~~~~~~~~~
For the Spectre variant 1, vulnerable kernel code (as determined
by code audit or scanning tools) is annotated on a case by case
basis to use nospec accessor macros for bounds clipping :ref:`[2]
<spec_ref2>` to avoid any usable disclosure gadgets. However, it may
not cover all attack vectors for Spectre variant 1.
Copy-from-user code has an LFENCE barrier to prevent the access_ok()
check from being mis-speculated. The barrier is done by the
barrier_nospec() macro.
For the swapgs variant of Spectre variant 1, LFENCE barriers are
added to interrupt, exception and NMI entry where needed. These
barriers are done by the FENCE_SWAPGS_KERNEL_ENTRY and
FENCE_SWAPGS_USER_ENTRY macros.
Spectre variant 2
~~~~~~~~~~~~~~~~~
For Spectre variant 2 mitigation, the compiler turns indirect calls or
jumps in the kernel into equivalent return trampolines (retpolines)
:ref:`[3] <spec_ref3>` :ref:`[9] <spec_ref9>` to go to the target
addresses. Speculative execution paths under retpolines are trapped
in an infinite loop to prevent any speculative execution jumping to
a gadget.
To turn on retpoline mitigation on a vulnerable CPU, the kernel
needs to be compiled with a gcc compiler that supports the
-mindirect-branch=thunk-extern -mindirect-branch-register options.
If the kernel is compiled with a Clang compiler, the compiler needs
to support -mretpoline-external-thunk option. The kernel config
CONFIG_MITIGATION_RETPOLINE needs to be turned on, and the CPU needs
to run with the latest updated microcode.
On Intel Skylake-era systems the mitigation covers most, but not all,
cases. See :ref:`[3] <spec_ref3>` for more details.
On CPUs with hardware mitigation for Spectre variant 2 (e.g. IBRS
or enhanced IBRS on x86), retpoline is automatically disabled at run time.
Systems which support enhanced IBRS (eIBRS) enable IBRS protection once at
boot, by setting the IBRS bit, and they're automatically protected against
some Spectre v2 variant attacks. The BHB can still influence the choice of
indirect branch predictor entry, and although branch predictor entries are
isolated between modes when eIBRS is enabled, the BHB itself is not isolated
between modes. Systems which support BHI_DIS_S will set it to protect against
BHI attacks.
On Intel's enhanced IBRS systems, this includes cross-thread branch target
injections on SMT systems (STIBP). In other words, Intel eIBRS enables
STIBP, too.
AMD Automatic IBRS does not protect userspace, and Legacy IBRS systems clear
the IBRS bit on exit to userspace, therefore both explicitly enable STIBP.
The retpoline mitigation is turned on by default on vulnerable
CPUs. It can be forced on or off by the administrator
via the kernel command line and sysfs control files. See
:ref:`spectre_mitigation_control_command_line`.
On x86, indirect branch restricted speculation is turned on by default
before invoking any firmware code to prevent Spectre variant 2 exploits
using the firmware.
Using kernel address space randomization (CONFIG_RANDOMIZE_BASE=y
and CONFIG_SLAB_FREELIST_RANDOM=y in the kernel configuration) makes
attacks on the kernel generally more difficult.
2. User program mitigation
^^^^^^^^^^^^^^^^^^^^^^^^^^
User programs can mitigate Spectre variant 1 using LFENCE or "bounds
clipping". For more details see :ref:`[2] <spec_ref2>`.
For Spectre variant 2 mitigation, individual user programs
can be compiled with return trampolines for indirect branches.
This protects them from consuming poisoned entries in the branch
target buffer left by malicious software.
On legacy IBRS systems, at return to userspace, implicit STIBP is disabled
because the kernel clears the IBRS bit. In this case, the userspace programs
can disable indirect branch speculation via prctl() (See
:ref:`Documentation/userspace-api/spec_ctrl.rst <set_spec_ctrl>`).
On x86, this will turn on STIBP to guard against attacks from the
sibling thread when the user program is running, and use IBPB to
flush the branch target buffer when switching to/from the program.
Restricting indirect branch speculation on a user program will
also prevent the program from launching a variant 2 attack
on x86. Administrators can change that behavior via the kernel
command line and sysfs control files.
See :ref:`spectre_mitigation_control_command_line`.
Programs that disable their indirect branch speculation will have
more overhead and run slower.
User programs should use address space randomization
(/proc/sys/kernel/randomize_va_space = 1 or 2) to make attacks more
difficult.
3. VM mitigation
^^^^^^^^^^^^^^^^
Within the kernel, Spectre variant 1 attacks from rogue guests are
mitigated on a case by case basis in VM exit paths. Vulnerable code
uses nospec accessor macros for "bounds clipping", to avoid any
usable disclosure gadgets. However, this may not cover all variant
1 attack vectors.
For Spectre variant 2 attacks from rogue guests to the kernel, the
Linux kernel uses retpoline or Enhanced IBRS to prevent consumption of
poisoned entries in branch target buffer left by rogue guests. It also
flushes the return stack buffer on every VM exit to prevent a return
stack buffer underflow so poisoned branch target buffer could be used,
or attacker guests leaving poisoned entries in the return stack buffer.
To mitigate guest-to-guest attacks in the same CPU hardware thread,
the branch target buffer is sanitized by flushing before switching
to a new guest on a CPU.
The above mitigations are turned on by default on vulnerable CPUs.
To mitigate guest-to-guest attacks from sibling thread when SMT is
in use, an untrusted guest running in the sibling thread can have
its indirect branch speculation disabled by administrator via prctl().
The kernel also allows guests to use any microcode based mitigation
they choose to use (such as IBPB or STIBP on x86) to protect themselves.
.. _spectre_mitigation_control_command_line:
Mitigation control on the kernel command line
---------------------------------------------
In general the kernel selects reasonable default mitigations for the
current CPU.
Spectre default mitigations can be disabled or changed at the kernel
command line with the following options:
- nospectre_v1
- nospectre_v2
- spectre_v2={option}
- spectre_v2_user={option}
- spectre_bhi={option}
For more details on the available options, refer to Documentation/admin-guide/kernel-parameters.txt
Mitigation selection guide
--------------------------
1. Trusted userspace
^^^^^^^^^^^^^^^^^^^^
If all userspace applications are from trusted sources and do not
execute externally supplied untrusted code, then the mitigations can
be disabled.
2. Protect sensitive programs
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
For security-sensitive programs that have secrets (e.g. crypto
keys), protection against Spectre variant 2 can be put in place by
disabling indirect branch speculation when the program is running
(See :ref:`Documentation/userspace-api/spec_ctrl.rst <set_spec_ctrl>`).
3. Sandbox untrusted programs
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Untrusted programs that could be a source of attacks can be cordoned
off by disabling their indirect branch speculation when they are run
(See :ref:`Documentation/userspace-api/spec_ctrl.rst <set_spec_ctrl>`).
This prevents untrusted programs from polluting the branch target
buffer. This behavior can be changed via the kernel command line
and sysfs control files. See
:ref:`spectre_mitigation_control_command_line`.
3. High security mode
^^^^^^^^^^^^^^^^^^^^^
All Spectre variant 2 mitigations can be forced on
at boot time for all programs (See the "on" option in
:ref:`spectre_mitigation_control_command_line`). This will add
overhead as indirect branch speculations for all programs will be
restricted.
On x86, branch target buffer will be flushed with IBPB when switching
to a new program. STIBP is left on all the time to protect programs
against variant 2 attacks originating from programs running on
sibling threads.
Alternatively, STIBP can be used only when running programs
whose indirect branch speculation is explicitly disabled,
while IBPB is still used all the time when switching to a new
program to clear the branch target buffer (See "ibpb" option in
:ref:`spectre_mitigation_control_command_line`). This "ibpb" option
has less performance cost than the "on" option, which leaves STIBP
on all the time.
References on Spectre
---------------------
Intel white papers:
.. _spec_ref1:
[1] `Intel analysis of speculative execution side channels <https://www.intel.com/content/dam/www/public/us/en/documents/white-papers/analysis-of-speculative-execution-side-channels-white-paper.pdf>`_.
.. _spec_ref2:
[2] `Bounds check bypass <https://software.intel.com/security-software-guidance/software-guidance/bounds-check-bypass>`_.
.. _spec_ref3:
[3] `Deep dive: Retpoline: A branch target injection mitigation <https://software.intel.com/security-software-guidance/insights/deep-dive-retpoline-branch-target-injection-mitigation>`_.
.. _spec_ref4:
[4] `Deep Dive: Single Thread Indirect Branch Predictors <https://software.intel.com/security-software-guidance/insights/deep-dive-single-thread-indirect-branch-predictors>`_.
AMD white papers:
.. _spec_ref5:
[5] `AMD64 technology indirect branch control extension <https://www.amd.com/content/dam/amd/en/documents/processor-tech-docs/white-papers/111006-architecture-guidelines-update-amd64-technology-indirect-branch-control-extension.pdf>`_.
.. _spec_ref6:
[6] `Software techniques for managing speculation on AMD processors <https://developer.amd.com/wp-content/resources/Managing-Speculation-on-AMD-Processors.pdf>`_.
ARM white papers:
.. _spec_ref7:
[7] `Cache speculation side-channels <https://developer.arm.com/support/arm-security-updates/speculative-processor-vulnerability/download-the-whitepaper>`_.
.. _spec_ref8:
[8] `Cache speculation issues update <https://developer.arm.com/support/arm-security-updates/speculative-processor-vulnerability/latest-updates/cache-speculation-issues-update>`_.
Google white paper:
.. _spec_ref9:
[9] `Retpoline: a software construct for preventing branch-target-injection <https://support.google.com/faqs/answer/7625886>`_.
MIPS white paper:
.. _spec_ref10:
[10] `MIPS: response on speculative execution and side channel vulnerabilities <https://web.archive.org/web/20220512003005if_/https://www.mips.com/blog/mips-response-on-speculative-execution-and-side-channel-vulnerabilities/>`_.
Academic papers:
.. _spec_ref11:
[11] `Spectre Attacks: Exploiting Speculative Execution <https://spectreattack.com/spectre.pdf>`_.
.. _spec_ref12:
[12] `NetSpectre: Read Arbitrary Memory over Network <https://arxiv.org/abs/1807.10535>`_.
.. _spec_ref13:
[13] `Spectre Returns! Speculation Attacks using the Return Stack Buffer <https://www.usenix.org/system/files/conference/woot18/woot18-paper-koruyeh.pdf>`_.
3. 한국어 전문 번역
영어 원문의 문단 순서와 의미를 유지한 전체 번역입니다. 코드, 함수명, symbol과 URL은 원문 표기를 유지합니다.
Spectre 개요와 영향받는 프로세서
1-38이 문서는 `GPL-2.0` SPDX 라이선스로 제공됩니다.
Spectre는 현대 CPU의 분기 예측과 추측 실행을 악용하여 메모리를 읽고, 경우에 따라 접근 제어를 우회하는 부채널 공격 계열입니다. 추측 실행 부채널 공격은 메모리를 변경하지 않으며, 메모리에 있는 권한 데이터의 값을 추론하려고 시도합니다.
이 문서는 Spectre 변종 1과 Spectre 변종 2를 다룹니다.
영향받는 프로세서
대부분의 현대 고속 프로세서는 분기 예측과 추측 실행을 사용하므로, 추측 실행 부채널 기법은 광범위한 현대 고성능 프로세서에 영향을 줍니다.
다음 CPU가 취약합니다.
- Intel Core, Atom, Pentium 및 Xeon 프로세서
- AMD Phenom, EPYC 및 Zen 프로세서
- IBM POWER 및 zSeries 프로세서
- 고급 ARM 프로세서
- Apple CPU
- 고급 MIPS CPU
- 그 밖의 대부분 고성능 CPU도 영향을 받을 가능성이 큽니다. 자세한 내용은 CPU 공급업체에 문의하십시오.
프로세서가 영향을 받는지는 sysfs의 Spectre 취약점 파일에서 확인할 수 있습니다. 아래의 `Spectre 시스템 정보` 절을 참조하십시오.
관련 CVE와 문제의 원리
39-64관련 CVE
다음 CVE 항목이 Spectre 변종을 설명합니다.
| CVE | 공격 유형 | Spectre 변종 |
|---|---|---|
| CVE-2017-5753 | Bounds check bypass | Spectre variant 1 |
| CVE-2017-5715 | Branch target injection | Spectre variant 2 |
| CVE-2019-1125 | Spectre v1 swapgs | Spectre variant 1 (swapgs) |
문제
CPU는 성능을 높이기 위해 추측 연산을 사용합니다. 이 과정은 프로세서의 캐시, 버퍼, 분기 예측기에 메모리 접근이나 계산의 흔적을 남길 수 있습니다. 악성 소프트웨어는 추측 실행 경로에 영향을 준 다음, CPU 캐시와 버퍼에 남은 부작용을 이용하여 추측 실행 중 접근한 권한 데이터를 추론할 수 있습니다.
Spectre 변종 1은 조건부 분기의 추측 실행을 이용하고, Spectre 변종 2는 간접 분기의 추측 실행을 이용해 권한 메모리를 유출합니다. 참고문헌 `[1]`, `[5]`, `[6]`, `[7]`, `[10]`, `[11]`을 참조하십시오.
Spectre 변종 1과 변종 2
65-145Spectre 변종 1: Bounds Check Bypass
경계 검사 우회 공격 `[2]`는 메모리 접근의 경계를 검사하는 조건부 분기 명령을 우회하는 추측 실행을 이용합니다. 예를 들어 배열 인덱스가 유효 범위 안의 메모리를 가리키는지 검사하는 분기가 실제로 해결되기 전에, 범위를 벗어난 인덱스를 통한 잘못된 메모리 접근이 추측적으로 수행될 수 있습니다. 이러한 추측 메모리 접근은 부작용을 남겨 공격자에게 정보를 유출하는 부채널을 만듭니다.
네트워크를 통해 데이터를 읽는 Spectre 변종 1의 확장 공격도 있으며 `[12]`를 참조할 수 있습니다. 그러나 이런 공격은 어렵고 대역폭이 낮으며 불안정하므로 위험도가 낮다고 평가됩니다.
`Bounds Check Bypass`라는 이름과 달리 Spectre 변종 1은 사용자가 제어하는 배열 경계 검사에만 국한되지 않습니다. 모든 조건부 검사에 영향을 줄 수 있습니다. 커널 진입 코드의 인터럽트, 예외, NMI 처리기에는 모두 조건부 `swapgs` 검사가 있습니다. 커널 코드가 사용자 GS로 추측 실행될 수 있으므로 이러한 검사는 Spectre v1 관점에서 문제가 될 수 있습니다.
Spectre 변종 2: Branch Target Injection
분기 대상 주입 공격은 간접 분기의 추측 실행을 이용합니다 `[3]`. 프로세서 내부에서 간접 분기 대상을 추측하는 예측기는 공격자의 영향을 받을 수 있습니다. 그 결과 가젯 코드가 추측 실행되고, 피해자가 접근한 민감한 데이터가 노출될 수 있습니다. 추측 실행 중 CPU 캐시에 남은 부작용을 측정하면 데이터 값을 추론할 수 있습니다.
Spectre 변종 2에서 공격자는 간접 분기 주소를 예측하는 CPU의 Branch Target Buffer(BTB)를 오염시켜 피해자의 추측 간접 분기가 가젯 코드로 향하게 할 수 있습니다. 공격자가 주소 오프셋을 제어하면서 기존 코드 안으로 간접 분기하면 이러한 오염을 만들 수 있습니다. 영향을 받는 하드웨어의 분기 예측은 분기 주소를 완전히 구분하지 못하고 오프셋을 예측에 사용하므로, 권한 코드의 간접 분기가 같은 오프셋의 가젯 코드로 이동할 수 있습니다.
가장 유용한 가젯은 레지스터 값과 같이 공격자가 제어하는 입력 매개변수를 받아 읽을 메모리를 제어할 수 있게 합니다. 입력 매개변수가 없는 가젯도 가능할 수 있지만 공격자가 읽을 메모리를 거의 제어하지 못하므로 유용한 데이터가 노출될 위험은 줄어듭니다.
또 다른 변종 2 공격 벡터는 공격자가 Return Stack Buffer(RSB)를 오염시켜 추측적 서브루틴 반환 명령이 가젯으로 향하게 하는 것입니다 `[13]`. 균형이 맞지 않는 공격자의 서브루틴 호출은 RSB 항목을 오염시킬 수 있고, 이 항목은 나중에 피해자의 반환 명령이 소비합니다. 문맥 전환이나 가상 머신(VM) 종료 시 RSB를 비우면 이 공격을 완화할 수 있습니다.
Simultaneous Multi-Threading(SMT) 시스템에서는 CPU 코어의 하드웨어 스레드가 L1 캐시와 BTB를 공유할 수 있으므로 형제 스레드에서 공격할 수 있습니다. 형제 스레드의 악성 프로그램이 상대 스레드의 BTB에 영향을 주어 간접 분기 추측을 가젯 코드로 유도하고, L1 캐시에 남은 추측 실행 부작용을 측정하여 피해자 데이터를 추론할 수 있습니다.
다른 변종 2 벡터로 공격자는 Branch History Buffer(BHB)를 오염시켜 간접 분기를 특정 BTB 항목으로 추측 유도할 수 있습니다. 그 항목이 간접 분기의 원본 주소와 연관되지 않아도 가능합니다. 특히 Enhanced IBRS가 있어도 BHB는 권한 수준 사이에서 공유될 수 있습니다.
과거에 알려진 실제 BHB 공격 벡터는 비권한 eBPF를 통한 방식뿐이었지만, 추가 연구에서 비권한 eBPF가 필요 없는 공격도 발견되었습니다. BHB 공격을 완전히 완화하려면 `BHI_DIS_S`를 설정하거나 BHB 초기화 시퀀스를 사용하는 것이 권장됩니다.
공격 시나리오 1: 사용자 프로세스가 커널 공격
146-228다음 공격 시나리오가 예상되지만, 가능한 모든 공격 벡터를 포괄하지는 않을 수 있습니다.
1. 사용자 프로세스가 커널을 공격
Spectre 변종 1
공격자는 시스템 호출 중 레지스터 또는 알려진 메모리 주소를 통해 커널에 매개변수를 전달합니다. 커널은 나중에 이 값을 배열 인덱스로 사용하거나 Spectre 변종 1 공격에 쓸 포인터를 유도할 수 있습니다. 인덱스나 포인터가 잘못되었어도 추측 실행이 선택한 코드 분기에서는 경계 검사가 우회될 수 있으며, 이로 인해 권한 메모리에 접근하여 데이터가 유출될 수 있습니다.
Spectre 공격에서 데이터 포인터가 영향을 받을 수 있다고 식별된 커널 코드에는 추측적 데이터 로드를 막는 새로운 `nospec` 접근자 매크로를 사용합니다.
Spectre 변종 1: swapgs
공격자는 인터럽트나 예외 처리에서 `swapgs` 경로를 추측적으로 건너뛰도록 분기 예측기를 훈련할 수 있습니다. GS 레지스터를 사용자 공간 값으로 초기화한 뒤 `swapgs`가 추측적으로 생략되면, 추측 실행 구간의 후속 GS 기반 percpu 접근은 공격자가 제어하는 GS 값을 사용합니다. 이로 인해 권한 메모리에 접근하여 데이터가 유출될 수 있습니다.
예를 들면 다음과 같습니다.
if (coming from user space)
swapgs
mov %gs:<percpu_offset>, %reg
mov (%reg), %reg1
사용자 공간에서 진입할 때 CPU는 `swapgs`를 추측적으로 건너뛴 뒤 사용자 GS 값으로 percpu 로드를 수행할 수 있습니다. 따라서 사용자는 임의의 커널 값을 추측적으로 읽게 만들 수 있습니다. percpu 값을 다른 load/store의 주소로 사용하는 가젯이 있다면, 커널 값의 내용이 L1 부채널 공격으로 드러날 수 있습니다.
커널 공간에서 진입할 때도 비슷한 공격이 존재합니다. CPU가 `swapgs`를 추측 실행하여 추측 구간의 나머지 부분에서 사용자 GS를 사용하게 만들 수 있습니다.
Spectre 변종 2
Spectre 변종 2 공격자는 시스템 호출로 공격을 시작하기 전에 BTB를 오염시킬 수 있습니다. 커널 진입 후 간접 점프가 오염된 BTB를 소비하면 추측 실행에서 가젯 코드로 점프할 수 있습니다.
공격자가 추측 실행 중 유출되는 메모리 주소를 제어하려면 레지스터나 알려진 메모리 주소를 통해 가젯에 매개변수도 전달해야 합니다. 가젯이 실행된 뒤 공격자는 그 부작용을 측정할 수 있습니다.
커널은 모든 간접 분기에 반환 트램펄린, 즉 `retpoline`을 사용하여 오염된 BTB 항목의 소비를 막을 수 있습니다 `[3]`, `[9]`. 반환 트램펄린은 추측 실행 경로를 가두어 추측 실행 중 가젯 코드로 점프하지 못하게 합니다. 하드웨어 Enhanced Indirect Branch Restricted Speculation(Enhanced IBRS)을 제공하는 x86 CPU는 retpoline 대신 이 기능으로 Spectre 변종 2를 완화해야 하며, Enhanced IBRS가 더 효율적입니다.
악성 사용자 프로세스가 Spectre 변종 2로 악용할 수 있는 가젯 코드가 펌웨어에 존재할 수 있습니다. x86에서는 커널이 펌웨어 코드를 호출하기 전에 Indirect Branch Restricted Speculation(IBRS)을 켜서 이러한 공격을 완화합니다.
공격 시나리오 2~4: 프로세스와 가상 머신
229-3232. 사용자 프로세스가 다른 사용자 프로세스를 공격
악성 사용자 프로세스는 같은 하드웨어 스레드에서 문맥 전환을 거치거나, SMT 시스템에서 물리 코어를 공유하는 형제 하이퍼스레드로부터 다른 사용자 프로세스를 공격할 수 있습니다.
Spectre 변종 1 공격은 일반적으로 프로세스 사이에 매개변수를 전달해야 하므로 Remote Procedure Call(RPC) 같은 데이터 전달 관계가 필요합니다. 공격받는 프로세스의 가젯 코드는 이 매개변수로 권한 메모리에 접근하는 잘못된 데이터 포인터를 유도합니다.
악성 프로세스는 BTB를 오염시켜 Spectre 변종 2 공격을 시작할 수 있습니다. 이는 같은 하드웨어 스레드에서 나중에 실행되는 피해 프로세스나, 같은 물리 코어를 공유하는 형제 하드웨어 스레드에서 동시에 실행되는 피해 프로세스의 간접 분기 대상에 영향을 줄 수 있습니다.
사용자 프로세스는 `prctl()` 시스템 호출로 자신의 간접 분기 추측을 비활성화하여 Spectre 변종 2 공격으로부터 자신을 보호할 수 있습니다. 관리자는 안전하지 않은 프로세스의 간접 분기 추측을 비활성화하여 BTB 오염을 차단할 수도 있습니다. 간접 분기 추측을 사용하지 않고 BTB를 지우므로 성능 비용이 발생합니다.
x86에서 SMT가 활성화된 경우 간접 분기 추측이 비활성화된 프로세스가 실행될 때 Single Threaded Indirect Branch Predictors(STIBP) `[4]`를 켜서 형제 스레드가 BTB를 제어하지 못하게 합니다. 또한 그러한 프로세스로 전환하거나 그 프로세스에서 빠져나올 때 Indirect Branch Prediction Barrier(IBPB)를 실행하여 BTB를 지웁니다.
x86에서는 문맥 전환 시 RSB를 채웁니다. 더 깊은 호출 스택으로 전환할 때 RSB가 언더플로되어 BTB가 반환 예측에 사용되는 일을 막고, 이전 프로세스가 남긴 오염된 RSB 항목도 지웁니다.
사용자 프로그램은 공격을 어렵게 만들기 위해 주소 공간 무작위화를 사용해야 합니다. `/proc/sys/kernel/randomize_va_space`를 `1` 또는 `2`로 설정하십시오.
3. 가상화 게스트가 호스트를 공격
공격 메커니즘은 사용자 프로세스가 커널을 공격하는 방식과 비슷합니다. 하이퍼콜 또는 다른 가상화 종료 경로를 통해 커널로 진입합니다.
Spectre 변종 1에서 악성 게스트는 하이퍼콜을 통해 레지스터 등에 매개변수를 전달하고, 커널 진입 후 잘못된 포인터를 유도하여 권한 메모리로 추측 실행할 수 있습니다. 이러한 커널 코드가 식별된 위치에는 `nospec` 접근자 매크로를 사용하여 추측 메모리 접근을 막습니다.
Spectre 변종 2에서 악성 게스트는 BTB 또는 RSB를 오염시켜 커널의 추측 실행 경로가 가젯 코드로 점프하게 만들 수 있습니다.
호스트 커널은 간접 분기에 반환 트램펄린을 사용해 오염된 BTB를 우회하고, VM 종료 시 RSB를 비워 변종 2를 완화할 수 있습니다. 이를 통해 악성 게스트가 호스트 커널의 간접 분기에 영향을 주지 못하게 합니다.
호스트 프로세스를 악성 게스트로부터 보호하려면 `prctl()`로 호스트 프로세스의 간접 분기 추측을 비활성화할 수 있습니다. 이러한 프로세스로 문맥 전환하기 전에 BTB를 지웁니다.
4. 가상화 게스트가 다른 게스트를 공격
악성 게스트는 다른 게스트가 접근할 수 있는 데이터를 얻기 위해 그 게스트를 공격할 수 있습니다.
게스트 간에 매개변수를 전달할 수 있다면 Spectre 변종 1 공격이 가능합니다. 공유 메모리나 메시지 전달 같은 방식으로 매개변수를 전달하고, 피해 게스트의 가젯 코드가 이 값으로 권한 데이터 포인터를 유도하여 추측 경로에서 접근할 수 있습니다.
악성 게스트는 BTB나 RSB를 오염시켜 Spectre 변종 2 공격을 시작할 수 있습니다. 오염된 항목은 피해 게스트의 추측 실행 경로에 영향을 줄 수 있습니다.
Linux 커널은 VM 종료 시 RSB를 비우고 새 게스트로 전환하기 전에 BTB를 지워 같은 CPU 하드웨어 스레드에서 실행되는 다른 게스트에 대한 공격을 완화합니다.
SMT를 사용한다면 관리자가 `prctl()`로 형제 하이퍼스레드의 신뢰할 수 없는 게스트에서 간접 분기 추측을 끌 수 있습니다. 게스트 자체도 내부에서 IBPB나 STIBP 같은 마이크로코드 기반 완화를 켜 자신을 보호할 수 있습니다.
Spectre 시스템 정보와 sysfs 상태
324-451원문의 `spectre_sys_info` 앵커는 이 절을 가리킵니다.
Linux 커널은 시스템이 Spectre에 취약한지와 어떤 완화가 활성화되었는지를 열거하는 sysfs 인터페이스를 제공합니다.
Spectre 변종 1 완화 상태를 표시하는 sysfs 파일은 다음과 같습니다.
/sys/devices/system/cpu/vulnerabilities/spectre_v1
이 파일에 가능한 값은 다음과 같습니다.
| 상태 | 의미 |
|---|---|
| Not affected | 프로세서가 취약하지 않습니다. |
| Vulnerable: __user pointer sanitization and usercopy barriers only; no swapgs barriers | `swapgs` 보호가 비활성화되어 있습니다. 그 밖의 부분은 명시적 포인터 정화와 usercopy `LFENCE` 장벽을 사례별로 적용해 커널을 보호합니다. |
| Mitigation: usercopy/swapgs barriers and __user pointer sanitization | 명시적 포인터 정화, usercopy `LFENCE` 장벽, `swapgs` `LFENCE` 장벽을 사례별로 적용해 커널을 보호합니다. |
그러나 이 보호는 사례별로 적용되므로 Spectre 변종 1의 가능한 모든 공격 벡터를 다룬다고 보장할 수 없습니다.
`spectre_v2` 커널 파일은 커널이 retpoline 완화로 컴파일되었는지, CPU에 하드웨어 완화가 있는지, CPU가 프로세스별 추가 완화를 지원하는지를 보고합니다.
이 파일은 사용자 프로세스 간 공격을 완화하도록 마이크로코드로 활성화된 다음 CPU 기능도 보고합니다.
- Indirect Branch Prediction Barrier(IBPB): 서로 다른 사용자의 프로세스 사이에 추가 격리를 제공합니다.
- Single Thread Indirect Branch Predictors(STIBP): 같은 코어에서 실행되는 CPU 스레드 사이에 추가 격리를 제공합니다.
이 CPU 기능은 사용할 때 성능에 영향을 줄 수 있으며 프로세스별로 선택하여 활성화할 수 있습니다.
Spectre 변종 2 완화 상태를 표시하는 sysfs 파일은 다음과 같습니다.
/sys/devices/system/cpu/vulnerabilities/spectre_v2
이 파일에 가능한 값은 다음과 같습니다.
커널 상태
| 상태 | 의미 |
|---|---|
| Not affected | 프로세서가 취약하지 않습니다. |
| Mitigation: None | 취약하며 완화가 없습니다. |
| Mitigation: Retpolines | Retpoline thunk를 사용합니다. |
| Mitigation: LFENCE | `LFENCE` 명령을 사용합니다. |
| Mitigation: Enhanced IBRS | 하드웨어 중심 완화를 사용합니다. |
| Mitigation: Enhanced IBRS + Retpolines | 하드웨어 중심 완화와 Retpoline을 함께 사용합니다. |
| Mitigation: Enhanced IBRS + LFENCE | 하드웨어 중심 완화와 `LFENCE`를 함께 사용합니다. |
펌웨어 상태
펌웨어를 호출할 때 Spectre 변종 2 공격을 막기 위해 IBRS를 사용하는지 표시합니다. x86 전용입니다.
| 상태 | 의미 |
|---|---|
| IBRS_FW | 펌웨어 호출 시 사용자 프로그램의 공격으로부터 보호합니다. |
프로세스 간 IBPB 상태
서로 다른 사용자의 프로세스 사이를 보호하는 IBPB 상태입니다. 프로세스별 `prctl()` 또는 커널 명령줄 옵션으로 제어하며 x86 전용입니다.
| 상태 | 의미 |
|---|---|
| IBPB: disabled | IBPB를 사용하지 않습니다. |
| IBPB: always-on | 모든 태스크에 IBPB를 사용합니다. |
| IBPB: conditional | SECCOMP 또는 간접 분기가 제한된 태스크에 IBPB를 사용합니다. |
하이퍼스레드 간 STIBP 상태
서로 다른 하이퍼스레드 사이를 보호하는 STIBP 상태입니다. 프로세스별 `prctl` 또는 커널 명령줄 옵션으로 제어하며 x86 전용입니다.
| 상태 | 의미 |
|---|---|
| STIBP: disabled | STIBP를 사용하지 않습니다. |
| STIBP: forced | 모든 태스크에 STIBP를 사용합니다. |
| STIBP: conditional | SECCOMP 또는 간접 분기가 제한된 태스크에 STIBP를 사용합니다. |
Return Stack Buffer(RSB) 보호 상태
| 상태 | 의미 |
|---|---|
| RSB filling | 문맥 전환 시 RSB 보호가 활성화되어 있습니다. |
eIBRS 이후 PBRSB 보호 상태
| 상태 | 의미 |
|---|---|
| PBRSB-eIBRS: SW sequence | CPU가 영향을 받으며 VMEXIT 시 RSB 보호가 활성화되어 있습니다. |
| PBRSB-eIBRS: Vulnerable | CPU가 취약합니다. |
| PBRSB-eIBRS: Not affected | CPU가 PBRSB의 영향을 받지 않습니다. |
Branch History Injection(BHI) 보호 상태
| 상태 | 의미 |
|---|---|
| BHI: Not affected | 시스템이 영향을 받지 않습니다. |
| BHI: Retpoline | 시스템이 retpoline으로 보호됩니다. |
| BHI: BHI_DIS_S | 시스템이 `BHI_DIS_S`로 보호됩니다. |
| BHI: SW loop, KVM SW loop | 시스템이 소프트웨어 초기화 시퀀스로 보호됩니다. |
| BHI: Vulnerable | 시스템이 BHI에 취약합니다. |
| BHI: Vulnerable, KVM: SW loop | 시스템은 취약하지만 KVM은 소프트웨어 초기화 시퀀스로 보호됩니다. |
완전한 완화에는 CPU 공급업체의 마이크로코드 업데이트가 필요할 수 있습니다. 필요한 마이크로코드가 없으면 커널은 취약 상태를 보고합니다.
커널의 Spectre 변종 1·2 완화
452-5281. 커널 완화
Spectre 변종 1
코드 감사나 검사 도구로 식별한 Spectre 변종 1 취약 커널 코드는 유용한 유출 가젯을 피하도록 사례별로 경계 클리핑용 `nospec` 접근자 매크로를 사용합니다 `[2]`. 그러나 Spectre 변종 1의 모든 공격 벡터를 다루지 못할 수 있습니다.
사용자 공간에서 복사하는 코드에는 `access_ok()` 검사가 잘못 추측되지 않도록 `LFENCE` 장벽이 있습니다. 이 장벽은 `barrier_nospec()` 매크로가 구현합니다.
Spectre 변종 1의 `swapgs` 변종을 위해 필요한 인터럽트, 예외, NMI 진입 지점에 `LFENCE` 장벽을 추가합니다. 장벽은 `FENCE_SWAPGS_KERNEL_ENTRY`와 `FENCE_SWAPGS_USER_ENTRY` 매크로가 구현합니다.
Spectre 변종 2
컴파일러는 커널의 간접 호출이나 점프를 같은 대상 주소로 가는 반환 트램펄린, 즉 retpoline으로 바꿉니다 `[3]`, `[9]`. Retpoline 아래의 추측 실행 경로를 무한 루프에 가두어 추측 실행이 가젯으로 점프하지 못하게 합니다.
취약한 CPU에서 retpoline 완화를 켜려면 커널을 `-mindirect-branch=thunk-extern -mindirect-branch-register` 옵션을 지원하는 GCC로 컴파일해야 합니다. Clang을 사용한다면 `-mretpoline-external-thunk`를 지원해야 합니다. 커널 설정 `CONFIG_MITIGATION_RETPOLINE`을 켜고 CPU에서 최신 마이크로코드를 실행해야 합니다.
Intel Skylake 세대 시스템에서 이 완화는 대부분의 경우를 다루지만 전부를 다루지는 않습니다. 자세한 내용은 `[3]`을 참조하십시오.
x86의 IBRS나 Enhanced IBRS처럼 Spectre 변종 2 하드웨어 완화가 있는 CPU에서는 런타임에 retpoline을 자동으로 비활성화합니다.
Enhanced IBRS(eIBRS)를 지원하는 시스템은 부팅할 때 IBRS 비트를 한 번 설정하여 보호를 활성화하고 일부 Spectre v2 변종 공격으로부터 자동 보호됩니다. 그러나 BHB는 여전히 간접 분기 예측기 항목 선택에 영향을 줄 수 있습니다. eIBRS가 모드 사이에서 분기 예측기 항목을 격리하더라도 BHB 자체는 모드 사이에서 격리되지 않습니다. `BHI_DIS_S`를 지원하는 시스템은 이를 설정해 BHI 공격을 막습니다.
Intel Enhanced IBRS 시스템에서는 SMT 시스템의 스레드 간 분기 대상 주입도 이 보호에 포함됩니다. 다시 말해 Intel eIBRS는 STIBP도 활성화합니다.
AMD Automatic IBRS는 사용자 공간을 보호하지 않고, Legacy IBRS 시스템은 사용자 공간으로 나갈 때 IBRS 비트를 지우므로 두 경우 모두 STIBP를 명시적으로 활성화합니다.
취약한 CPU에서는 retpoline 완화가 기본으로 켜집니다. 관리자는 커널 명령줄과 sysfs 제어 파일로 이를 강제로 켜거나 끌 수 있습니다. 아래의 `커널 명령줄 완화 제어` 절을 참조하십시오.
x86에서는 펌웨어를 이용한 Spectre 변종 2 악용을 막기 위해 펌웨어 코드를 호출하기 전에 기본적으로 간접 분기 제한 추측을 켭니다.
커널 설정에서 `CONFIG_RANDOMIZE_BASE=y`와 `CONFIG_SLAB_FREELIST_RANDOM=y`를 사용하는 커널 주소 공간 무작위화는 일반적으로 커널 공격을 더 어렵게 합니다.
사용자 프로그램과 VM 완화
529-5892. 사용자 프로그램 완화
사용자 프로그램은 `LFENCE` 또는 경계 클리핑으로 Spectre 변종 1을 완화할 수 있습니다. 자세한 내용은 `[2]`를 참조하십시오.
Spectre 변종 2를 완화하려면 개별 사용자 프로그램의 간접 분기를 반환 트램펄린으로 컴파일할 수 있습니다. 이렇게 하면 악성 소프트웨어가 BTB에 남긴 오염된 항목을 프로그램이 소비하지 않게 됩니다.
Legacy IBRS 시스템에서는 커널이 IBRS 비트를 지우므로 사용자 공간으로 돌아갈 때 암시적 STIBP가 비활성화됩니다. 이 경우 사용자 프로그램은 `prctl()`로 간접 분기 추측을 비활성화할 수 있습니다. `Documentation/userspace-api/spec_ctrl.rst`의 `set_spec_ctrl`을 참조하십시오.
x86에서는 이 설정이 프로그램 실행 중 형제 스레드 공격을 막도록 STIBP를 켜고, 프로그램으로 전환하거나 프로그램에서 빠져나올 때 IBPB로 BTB를 비웁니다.
사용자 프로그램의 간접 분기 추측을 제한하면 그 프로그램이 x86에서 변종 2 공격을 시작하는 것도 막습니다. 관리자는 커널 명령줄과 sysfs 제어 파일로 이 동작을 변경할 수 있습니다. 아래의 `커널 명령줄 완화 제어` 절을 참조하십시오.
간접 분기 추측을 비활성화한 프로그램은 오버헤드가 늘어 더 느리게 실행됩니다.
사용자 프로그램은 공격을 어렵게 만들기 위해 `/proc/sys/kernel/randomize_va_space`를 `1` 또는 `2`로 설정하여 주소 공간 무작위화를 사용해야 합니다.
3. VM 완화
커널 안에서는 VM 종료 경로의 악성 게스트에 의한 Spectre 변종 1 공격을 사례별로 완화합니다. 취약 코드는 경계 클리핑용 `nospec` 접근자 매크로로 유용한 유출 가젯을 피합니다. 그러나 변종 1의 모든 공격 벡터를 다루지 못할 수 있습니다.
악성 게스트가 커널에 가하는 Spectre 변종 2 공격을 막기 위해 Linux 커널은 retpoline 또는 Enhanced IBRS를 사용하여 게스트가 BTB에 남긴 오염된 항목을 소비하지 않습니다. 또한 VM이 종료될 때마다 RSB를 비워 RSB 언더플로로 오염된 BTB가 사용되거나 공격자 게스트가 RSB에 오염된 항목을 남기는 일을 막습니다.
같은 CPU 하드웨어 스레드의 게스트 간 공격을 완화하기 위해 새 게스트로 전환하기 전에 BTB를 비워 정화합니다.
취약한 CPU에서는 위 완화가 기본으로 켜집니다.
SMT 사용 중 형제 스레드에서 발생하는 게스트 간 공격을 완화하려면 관리자가 `prctl()`로 형제 스레드에서 실행되는 신뢰할 수 없는 게스트의 간접 분기 추측을 비활성화할 수 있습니다.
커널은 게스트가 스스로를 보호하기 위해 선택한 마이크로코드 기반 완화도 사용할 수 있게 합니다. x86의 IBPB와 STIBP가 예입니다.
커널 명령줄 제어와 완화 선택 가이드
590-658원문의 `spectre_mitigation_control_command_line` 앵커는 이 절을 가리킵니다.
커널 명령줄의 완화 제어
일반적으로 커널은 현재 CPU에 합리적인 기본 완화를 선택합니다.
다음 커널 명령줄 옵션으로 Spectre 기본 완화를 비활성화하거나 변경할 수 있습니다.
- nospectre_v1
- nospectre_v2
- spectre_v2={option}
- spectre_v2_user={option}
- spectre_bhi={option}
사용 가능한 옵션의 자세한 내용은 `Documentation/admin-guide/kernel-parameters.txt`를 참조하십시오.
완화 선택 가이드
1. 신뢰할 수 있는 사용자 공간
모든 사용자 공간 응용 프로그램이 신뢰할 수 있는 출처에서 왔고 외부에서 제공된 신뢰할 수 없는 코드를 실행하지 않는다면 완화를 비활성화할 수 있습니다.
2. 민감한 프로그램 보호
암호화 키 같은 비밀을 가진 보안 민감 프로그램은 실행 중 간접 분기 추측을 비활성화하여 Spectre 변종 2 보호를 적용할 수 있습니다. `Documentation/userspace-api/spec_ctrl.rst`의 `set_spec_ctrl`을 참조하십시오.
3. 신뢰할 수 없는 프로그램 샌드박스
공격의 출발점이 될 수 있는 신뢰할 수 없는 프로그램은 실행할 때 간접 분기 추측을 비활성화하여 격리할 수 있습니다. `Documentation/userspace-api/spec_ctrl.rst`의 `set_spec_ctrl`을 참조하십시오.
이 설정은 신뢰할 수 없는 프로그램이 BTB를 오염시키지 못하게 합니다. 커널 명령줄과 sysfs 제어 파일로 동작을 변경할 수 있습니다. 위의 `커널 명령줄 완화 제어`를 참조하십시오.
3. 고보안 모드
부팅할 때 모든 프로그램에 Spectre 변종 2 완화를 강제로 켤 수 있습니다. `커널 명령줄 완화 제어`의 `on` 옵션을 사용합니다. 모든 프로그램의 간접 분기 추측을 제한하므로 오버헤드가 추가됩니다. 원문은 이 항목 번호를 앞 항목과 동일한 `3`으로 표기합니다.
x86에서는 새 프로그램으로 전환할 때 IBPB로 BTB를 비웁니다. 형제 스레드에서 실행되는 프로그램이 시작하는 변종 2 공격으로부터 프로그램을 보호하도록 STIBP를 계속 켜 둡니다.
대안으로 간접 분기 추측을 명시적으로 비활성화한 프로그램을 실행할 때만 STIBP를 사용하고, 새 프로그램으로 전환할 때는 항상 IBPB로 BTB를 지울 수 있습니다. `커널 명령줄 완화 제어`의 `ibpb` 옵션입니다. STIBP를 항상 켜 두는 `on` 옵션보다 성능 비용이 낮습니다.
Spectre 참고문헌
659-725Intel 백서
- [1] Intel analysis of speculative execution side channels
https://www.intel.com/content/dam/www/public/us/en/documents/white-papers/analysis-of-speculative-execution-side-channels-white-paper.pdf - [2] Bounds check bypass
https://software.intel.com/security-software-guidance/software-guidance/bounds-check-bypass - [3] Deep dive: Retpoline: A branch target injection mitigation
https://software.intel.com/security-software-guidance/insights/deep-dive-retpoline-branch-target-injection-mitigation - [4] Deep Dive: Single Thread Indirect Branch Predictors
https://software.intel.com/security-software-guidance/insights/deep-dive-single-thread-indirect-branch-predictors
AMD 백서
- [5] AMD64 technology indirect branch control extension
https://www.amd.com/content/dam/amd/en/documents/processor-tech-docs/white-papers/111006-architecture-guidelines-update-amd64-technology-indirect-branch-control-extension.pdf - [6] Software techniques for managing speculation on AMD processors
https://developer.amd.com/wp-content/resources/Managing-Speculation-on-AMD-Processors.pdf
ARM 백서
- [7] Cache speculation side-channels
https://developer.arm.com/support/arm-security-updates/speculative-processor-vulnerability/download-the-whitepaper - [8] Cache speculation issues update
https://developer.arm.com/support/arm-security-updates/speculative-processor-vulnerability/latest-updates/cache-speculation-issues-update
Google 백서
MIPS 백서
학술 논문
- [11] Spectre Attacks: Exploiting Speculative Execution
https://spectreattack.com/spectre.pdf - [12] NetSpectre: Read Arbitrary Memory over Network
https://arxiv.org/abs/1807.10535 - [13] Spectre Returns! Speculation Attacks using the Return Stack Buffer
https://www.usenix.org/system/files/conference/woot18/woot18-paper-koruyeh.pdf
공격 모델과 영향 범위
spectre.rst:1-145영향받는 CPU, 관련 CVE, Bounds Check Bypass와 Branch Target Injection의 작동 원리를 정리합니다.