Spectre is a class of side channel attacks that exploit branch predictionand speculative execution on modern CPUs to read memory, possiblybypassing access controls. Speculative execution side channel exploitsdo 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 modernhigh performance processors, since most modern high speed processorsuse branch prediction and speculative execution.
The following CPUs are vulnerable:
Spectre air filter products are designed to increase power and torque for your engine. Spectre offers multiple styles and sizes of air filters to fit almost any configuration and vehicle. Spectre HPR air filters feature a pre-oiled, synthetic filer media that provides exceptional airflow for increased performance without sacrificing engine. Spectre, set up to be the Daniel Craig finale as Bond, isn't a terrible installment in the franchise. It's the lightest of the Craig Bonds — no sin in that. But like the end of Connery, the exit of Roger Moore and the layoff notice given Pierce Brosnan, it's a tired, trite 'greatest hits'.
- 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 Spectrevulnerability files in sysfs. See Spectre system information.
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 leavetraces of memory accesses or computations in the processor's caches,buffers, and branch predictors. Malicious software may be able toinfluence the speculative execution paths, and then use the side effectsof the speculative execution in the CPUs' caches and buffers to inferprivileged data touched during the speculative execution.
Spectre variant 1 attacks take advantage of speculative execution ofconditional branches, while Spectre variant 2 attacks use speculativeexecution of indirect branches to leak privileged memory.See [1][5][7][10][11].
Spectre variant 1 (Bounds Check Bypass)¶
The bounds check bypass attack [2] takes advantageof speculative execution that bypasses conditional branch instructionsused for memory access bounds check (e.g. checking if the index of anarray results in memory access within a valid range). This results inmemory accesses to invalid memory (with out-of-bound index) that aredone speculatively before validation checks resolve. Such speculativememory accesses can leave side effects, creating side channels whichleak information to the attacker.
There are some extensions of Spectre variant 1 attacks for reading dataover the network, see [12]. However such attacksare difficult, low bandwidth, fragile, and are considered low risk.
Note that, despite 'Bounds Check Bypass' name, Spectre variant 1 is notonly about user-controlled array bounds checks. It can affect anyconditional checks. The kernel entry code interrupt, exception, and NMIhandlers all have conditional swapgs checks. Those may be problematicin the context of Spectre v1, as kernel code can speculatively run witha user GS.
Spectre variant 2 (Branch Target Injection)¶
The branch target injection attack takes advantage of speculativeexecution of indirect branches [3]. The indirectbranch predictors inside the processor used to guess the target ofindirect branches can be influenced by an attacker, causing gadget codeto be speculatively executed, thus exposing sensitive data touched bythe victim. The side effects left in the CPU's caches during speculativeexecution can be measured to infer data values.
In Spectre variant 2 attacks, the attacker can steer speculative indirectbranches in the victim to gadget code by poisoning the branch targetbuffer of a CPU used for predicting indirect branch addresses. Motion 5 4 2. Suchpoisoning could be done by indirect branching into existing code,with the address offset of the indirect branch under the attacker'scontrol. Since the branch prediction on impacted hardware does notfully disambiguate branch address and uses the offset for prediction,this could cause privileged code's indirect branch to jump to a gadgetcode with the same offset.
The most useful gadgets take an attacker-controlled input parameter (suchas a register value) so that the memory read can be controlled. Gadgetswithout input parameters might be possible, but the attacker would havevery little control over what memory can be read, reducing the risk ofthe attack revealing useful data.
One other variant 2 attack vector is for the attacker to poison thereturn stack buffer (RSB) [13] to cause speculativesubroutine return instruction execution to go to a gadget. An attacker'simbalanced subroutine call instructions might 'poison' entries in thereturn stack buffer which are later consumed by a victim's subroutinereturn instructions. This attack can be mitigated by flushing the returnstack buffer on context switch, or virtual machine (VM) exit.
On systems with simultaneous multi-threading (SMT), attacks are possiblefrom the sibling thread, as level 1 cache and branch target buffer(BTB) may be shared between hardware threads in a CPU core. A maliciousprogram running on the sibling thread may influence its peer's BTB tosteer its indirect branch speculations to gadget code, and measure thespeculative execution's side effects left in level 1 cache to infer thevictim's data.
Attack scenarios¶
The following list of attack scenarios have been anticipated, but maynot 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 orvia a known address in memory during a syscall. Such parameter maybe used later by the kernel as an index to an array or to derivea pointer for a Spectre variant 1 attack. The index or pointeris invalid, but bound checks are bypassed in the code branch takenfor speculative execution. This could cause privileged memory to beaccessed and leaked.
For kernel code that has been identified where data pointers couldpotentially be influenced for Spectre attacks, new 'nospec' accessormacros are used to prevent speculative loading of data.
Spectre variant 1 (swapgs)¶
An attacker can train the branch predictor to speculatively skip theswapgs path for an interrupt or exception. If they initializethe GS register to a user-space value, if the swapgs is speculativelyskipped, subsequent GS-related percpu accesses in the speculationwindow will be done with the attacker-controlled GS value. Thiscould cause privileged memory to be accessed and leaked.
Madmapper 2 0 1 download free. For example:
When coming from user space, the CPU can speculatively skip theswapgs, and then do a speculative percpu load using the user GSvalue. So the user can speculatively force a read of any kernelvalue. If a gadget exists which uses the percpu value as an addressin another load/store, then the contents of the kernel value maybecome visible via an L1 side channel attack.
A similar attack exists when coming from kernel space. The CPU canspeculatively do the swapgs, causing the user GS to get used for therest of the speculative window.
Spectre variant 2¶
A spectre variant 2 attacker can poison the branchtarget buffer (BTB) before issuing syscall to launch an attack.After entering the kernel, the kernel could use the poisoned branchtarget buffer on indirect jump and jump to gadget code in speculativeexecution.
If an attacker tries to control the memory addresses leaked duringspeculative execution, he would also need to pass a parameter to thegadget, either through a register or a known address in memory. Afterthe gadget has executed, he can measure the side effect.
The kernel can protect itself against consuming poisoned branchtarget buffer entries by using return trampolines (also known as'retpoline') [3][9] for allindirect branches. Return trampolines trap speculative execution pathsto 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 tomitigate Spectre variant 2 instead of retpoline. Enhanced IBRS ismore efficient than retpoline.
There may be gadget code in firmware which could be exploited withSpectre variant 2 attack by a rogue user process. To mitigate suchattacks on x86, Indirect Branch Restricted Speculation (IBRS) featureis 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 thesibling hyperthread sharing a physical processor core on simultaneousmulti-threading (SMT) system.
Spectre variant 1 attacks generally require passing parametersbetween the processes, which needs a data passing relationship, suchas remote procedure calls (RPC). Those parameters are used in gadgetcode to derive invalid data pointers accessing privileged memory inthe attacked process.
Spectre variant 2 attacks can be launched from a rogue process bypoisoning the branch target buffer. This caninfluence the indirect branch targets for a victim process that eitherruns later on the same hardware thread, or running concurrently ona sibling hardware thread sharing the same physical core.
A user process can protect itself against Spectre variant 2 attacksby using the prctl() syscall to disable indirect branch speculationfor itself. An administrator can also cordon off an unsafe processfrom polluting the branch target buffer by disabling the process'sindirect branch speculation. This comes with a performance costfrom not using indirect branch speculation and clearing the branchtarget buffer. When SMT is enabled on x86, for a process that hasindirect branch speculation disabled, Single Threaded Indirect BranchPredictors (STIBP) [4] are turned on to prevent thesibling thread from controlling branch target buffer. In addition,the Indirect Branch Prediction Barrier (IBPB) is issued to clear thebranch 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 branchprediction when the return stack buffer underflows while switching toa deeper call stack. Any poisoned entries in the return stack bufferleft by the previous process will also be cleared.
User programs should use address space randomization to make attacksmore 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 thekernel. The kernel is entered via hyper-calls or other virtualizationexit paths.
For Spectre variant 1 attacks, rogue guests can pass parameters(e.g. in registers) via hyper-calls to derive invalid pointers tospeculate into privileged memory after entering the kernel. For placeswhere such kernel code has been identified, nospec accessor macrosare used to stop speculative memory access.
For Spectre variant 2 attacks, rogue guests can poison the branch target buffer or return stack buffer, causingthe kernel to jump to gadget code in the speculative execution paths.
To mitigate variant 2, the host kernel can use return trampolinesfor indirect branches to bypass the poisoned branch target buffer,and flushing the return stack buffer on VM exit. This prevents rogueguests from affecting indirect branching in the host kernel.
To protect host processes from rogue guests, host processes can haveindirect branch speculation disabled via prctl(). The branch targetbuffer 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 theother guest.
Spectre variant 1 attacks are possible if parameters can be passedbetween guests. This may be done via mechanisms such as shared memoryor message passing. Such parameters could be used to derive datapointers to privileged data in guest. The privileged data could beaccessed by gadget code in the victim's speculation paths.
Spectre variant 2 attacks can be launched from a rogue guest bypoisoning the branch target buffer or the returnstack buffer. Such poisoned entries could be used to influencespeculation execution paths in the victim guest.
Linux kernel mitigates attacks to other guests running in the sameCPU 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 guestin the sibling hyperthread can be mitigated by the administrator,by turning off the unsafe guest's indirect branch speculation viaprctl(). A guest can also protect itself by turning on microcodebased mitigations (such as IBPB or STIBP on x86) within the guest.
Spectre system information¶
The Linux kernel provides a sysfs interface to enumerate the currentmitigation status of the system for Spectre: whether the system isvulnerable, and which mitigations are active.
The sysfs file showing Spectre variant 1 mitigation status is:
The possible values in this file are:
‘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 hasprotection in the kernel on a case by case base with explicitpointer sanitation and usercopy LFENCE barriers. |
‘Mitigation: usercopy/swapgs barriers and __user pointer sanitization' | Protection in the kernel on a case by case base with explicitpointer sanitation, usercopy LFENCE barriers, and swapgs LFENCEbarriers. |
However, the protections are put in place on a case by case basis,and there is no guarantee that all possible attack vectors for Spectrevariant 1 are covered.
The spectre_v2 kernel file reports if the kernel has been compiled withretpoline mitigation or if the CPU has hardware mitigation, and if theCPU has support for additional process-specific mitigation.
This file also reports CPU features enabled by microcode to mitigateattack between user processes:
- Indirect Branch Prediction Barrier (IBPB) to add additionalisolation between processes of different users.
- Single Thread Indirect Branch Predictors (STIBP) to add additionalisolation between CPU threads running on the same core.
These CPU features may impact performance when used and can be enabledper process on a case-by-case base.
The sysfs file showing Spectre variant 2 mitigation status is:
The possible values in this file are:
- Kernel status:
‘Not affected' | The processor is not vulnerable |
‘Vulnerable' | Vulnerable, no mitigation |
‘Mitigation: Full generic retpoline' | Software-focused mitigation |
‘Mitigation: Full AMD retpoline' | AMD-specific software mitigation |
‘Mitigation: Enhanced IBRS' | Hardware-focused mitigation |
- Firmware status: Show if Indirect Branch Restricted Speculation (IBRS) isused 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 betweenprocesses of different users. This feature can be controlled throughprctl() per process, or through kernel command line options. This isan 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 protectionbetween different hyper threads. This feature can be controlled throughprctl per process, or through kernel command line options. This is x86only 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 |
Full mitigation might require a microcode update from the CPUvendor. When the necessary microcode is not available, the kernel willreport 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 determinedby code audit or scanning tools) is annotated on a case by casebasis to use nospec accessor macros for bounds clipping [2] to avoid any usable disclosure gadgets. However, it maynot 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 thebarrier_nospec() macro.
For the swapgs variant of Spectre variant 1, LFENCE barriers areadded to interrupt, exception and NMI entry where needed. Thesebarriers are done by the FENCE_SWAPGS_KERNEL_ENTRY andFENCE_SWAPGS_USER_ENTRY macros.
Spectre variant 2¶
For Spectre variant 2 mitigation, the compiler turns indirect calls orjumps in the kernel into equivalent return trampolines (retpolines)[3][9] to go to the targetaddresses. Speculative execution paths under retpolines are trappedin an infinite loop to prevent any speculative execution jumping toa gadget.
To turn on retpoline mitigation on a vulnerable CPU, the kernelneeds 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 needsto support -mretpoline-external-thunk option. The kernel configCONFIG_RETPOLINE needs to be turned on, and the CPU needs to run withthe latest updated microcode.
On Intel Skylake-era systems the mitigation covers most, but not all,cases. See [3] for more details.
On CPUs with hardware mitigation for Spectre variant 2 (e.g. EnhancedIBRS on x86), retpoline is automatically disabled at run time.
The retpoline mitigation is turned on by default on vulnerableCPUs. It can be forced on or off by the administratorvia the kernel command line and sysfs control files. SeeMitigation control on the kernel command line.
On x86, indirect branch restricted speculation is turned on by defaultbefore invoking any firmware code to prevent Spectre variant 2 exploitsusing the firmware.
Using kernel address space randomization (CONFIG_RANDOMIZE_SLAB=yand CONFIG_SLAB_FREELIST_RANDOM=y in the kernel configuration) makesattacks on the kernel generally more difficult.
2. User program mitigation¶
User programs can mitigate Spectre variant 1 using LFENCE or 'boundsclipping'. For more details see [2].
For Spectre variant 2 mitigation, individual user programscan be compiled with return trampolines for indirect branches.This protects them from consuming poisoned entries in the branchtarget buffer left by malicious software. Alternatively, theprograms can disable their indirect branch speculation via prctl()(See Documentation/userspace-api/spec_ctrl.rst).On x86, this will turn on STIBP to guard against attacks from thesibling thread when the user program is running, and use IBPB toflush the branch target buffer when switching to/from the program.
Restricting indirect branch speculation on a user program willalso prevent the program from launching a variant 2 attackon x86. All sand-boxed SECCOMP programs have indirect branchspeculation restricted by default. Administrators can changethat behavior via the kernel command line and sysfs control files.See Mitigation control on the kernel command line.
Programs that disable their indirect branch speculation will havemore overhead and run slower.
User programs should use address space randomization(/proc/sys/kernel/randomize_va_space = 1 or 2) to make attacks moredifficult.
3. VM mitigation¶
Within the kernel, Spectre variant 1 attacks from rogue guests aremitigated on a case by case basis in VM exit paths. Vulnerable codeuses nospec accessor macros for 'bounds clipping', to avoid anyusable disclosure gadgets. However, this may not cover all variant1 attack vectors.
For Spectre variant 2 attacks from rogue guests to the kernel, theLinux kernel uses retpoline or Enhanced IBRS to prevent consumption ofpoisoned entries in branch target buffer left by rogue guests. It alsoflushes the return stack buffer on every VM exit to prevent a returnstack 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 switchingto 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 isin use, an untrusted guest running in the sibling thread can haveits indirect branch speculation disabled by administrator via prctl().
The kernel also allows guests to use any microcode based mitigationthey choose to use (such as IBPB or STIBP on x86) to protect themselves.
Mitigation control on the kernel command line¶
Spectre variant 2 mitigation can be disabled or force enabled at thekernel command line.
nospectre_v1
nospectre_v2
spectre_v2=
[X86] Control mitigation of Spectre variant 2(indirect branch speculation) vulnerability.The default operation protects the kernel fromuser space attacks.
- on
- unconditionally enable, impliesspectre_v2_user=on
- off
- unconditionally disable, impliesspectre_v2_user=off
- auto
- kernel detects whether your CPU model isvulnerable
Selecting ‘on' will, and ‘auto' may, choose amitigation method at run time according to theCPU, the available microcode, the setting of theCONFIG_RETPOLINE configuration option, and thecompiler with which the kernel was built.
Selecting ‘on' will also enable the mitigationagainst user space to user space task attacks.
Selecting ‘off' will disable both the kernel andthe user space protections.
Specific mitigations can also be selected manually:
- retpoline
- replace indirect branches
- retpoline,generic
- google's original retpoline
- retpoline,amd
- AMD-specific minimal thunk
Not specifying this option is equivalent tospectre_v2=auto.
For user space mitigation:
spectre_v2_user=
[X86] Control mitigation of Spectre variant 2(indirect branch speculation) vulnerability betweenuser space tasks
- on
- Unconditionally enable mitigations. Isenforced by spectre_v2=on
- off
- Unconditionally disable mitigations. Isenforced by spectre_v2=off
- prctl
- Indirect branch speculation is enabled,but mitigation can be enabled via prctlper thread. The mitigation control stateis inherited on fork.
- prctl,ibpb
- Like 'prctl' above, but only STIBP iscontrolled per thread. IBPB is issuedalways when switching between different userspace processes.
- seccomp
- Same as 'prctl' above, but all seccompthreads will enable the mitigation unlessthey explicitly opt out.
- seccomp,ibpb
- Like 'seccomp' above, but only STIBP iscontrolled per thread. IBPB is issuedalways when switching between differentuser space processes.
- auto
- Kernel selects the mitigation depending onthe available CPU features and vulnerability.
Default mitigation:If CONFIG_SECCOMP=y then 'seccomp', otherwise 'prctl'
Not specifying this option is equivalent tospectre_v2_user=auto.
In general the kernel by default selectsreasonable mitigations for the current CPU. Todisable Spectre variant 2 mitigations, boot withspectre_v2=off. Spectre variant 1 mitigationscannot be disabled.
Mitigation selection guide¶
1. Trusted userspace¶
2. Protect sensitive programs¶
3. Sandbox untrusted programs¶
3. High security mode¶
All Spectre variant 2 mitigations can be forced onat boot time for all programs (See the 'on' option inMitigation control on the kernel command line). This will addoverhead as indirect branch speculations for all programs will berestricted.
On x86, branch target buffer will be flushed with IBPB when switchingto a new program. STIBP is left on all the time to protect programsagainst variant 2 attacks originating from programs running onsibling threads.
Alternatively, STIBP can be used only when running programswhose indirect branch speculation is explicitly disabled,while IBPB is still used all the time when switching to a newprogram to clear the branch target buffer (See 'ibpb' option inMitigation control on the kernel command line). This 'ibpb' optionhas less performance cost than the 'on' option, which leaves STIBPon all the time.
References on Spectre¶
Intel white papers:
[1] Intel analysis of speculative execution side channels.
[2] Bounds check bypass.
[3] Deep dive: Retpoline: A branch target injection mitigation.
[4] Deep Dive: Single Thread Indirect Branch Predictors.
AMD white papers:
[5] AMD64 technology indirect branch control extension.
[6] Software techniques for managing speculation on AMD processors.
ARM white papers:
[7] Cache speculation side-channels.
[8] Cache speculation issues update.
Google white paper:
[9] Retpoline: a software construct for preventing branch-target-injection.
MIPS white paper:
[10] MIPS: response on speculative execution and side channel vulnerabilities.
Academic papers:
[11] Spectre Attacks: Exploiting Speculative Execution.
[12] NetSpectre: Read Arbitrary Memory over Network.
[13] Spectre Returns! Speculation Attacks using the Return Stack Buffer.
Prices, specifications, availability and terms of offers may change without notice. Price protection, price matching or price guarantees do not apply to Intra-day, Daily Deals or limited-time promotions. Quantity limits may apply to orders, including orders for discounted and promotional items. Despite our best efforts, a small number of items may contain pricing, typography, or photography errors. Correct prices and promotions are validated at the time your order is placed. These terms apply only to products sold by HP.com; reseller offers may vary. Items sold by HP.com are not for immediate resale. Orders that do not comply with HP.com terms, conditions, and limitations may be cancelled. Contract and volume customers not eligible.
HP's MSRP is subject to discount. HP's MSRP price is shown as either a stand-alone price or as a strike-through price with a discounted or promotional price also listed. Discounted or promotional pricing is indicated by the presence of an additional higher MSRP strike-through price
The following applies to HP systems with Intel 6th Gen and other future-generation processors on systems shipping with Windows 7, Windows 8, Windows 8.1 or Windows 10 Pro systems downgraded to Windows 7 Professional, Windows 8 Pro, or Windows 8.1: This version of Windows running with the processor or chipsets used in this system has limited support from Microsoft. For more information about Microsoft's support, please see Microsoft's Support Lifecycle FAQ at https://support.microsoft.com/lifecycle
Ultrabook, Celeron, Celeron Inside, Core Inside, Intel, Intel Logo, Intel Atom, Intel Atom Inside, Intel Core, Intel Inside, Intel Inside Logo, Intel vPro, Itanium, Itanium Inside, Pentium, Pentium Inside, vPro Inside, Xeon, Xeon Phi, Xeon Inside, and Intel Optane are trademarks of Intel Corporation or its subsidiaries in the U.S. and/or other countries.
In-home warranty is available only on select customizable HP desktop PCs. Need for in-home service is determined by HP support representative. Customer may be required to run system self-test programs or correct reported faults by following advice given over phone. On-site services provided only if issue can't be corrected remotely. Service not available holidays and weekends.
HP will transfer your name and address information, IP address, products ordered and associated costs and other personal information related to processing your application to Bill Me Later®. Bill Me Later will use that data under its privacy policy.
Microsoft Windows 10: Not all features are available in all editions or versions of Windows 10. Systems may require upgraded and/or separately purchased hardware, drivers, software or BIOS update to take full advantage of Windows 10 functionality. Windows 10 is automatically updated, which is always enabled. ISP fees may apply and additional requirements may apply over time for updates. See http://www.microsoft.com.
Spectre 1 9 45
'Best All In One Printer' and 'the easiest printer you've ever had to set up' from Wirecutter. ©2020 The Wirecutter, Inc. All rights reserved. Used under license. https://www.nytimes.com/wirecutter/reviews/best-all-in-one-printer/
NO ADDITIONAL PURCHASE NECESSARY TO ENTER OR WIN. ANY ADDITIONAL PURCHASE WILL NOT INCREASE YOUR CHANCES OF WINNING. Open only to legal residents of 50 US/DC, 18+. Void where prohibited. Multiple monthly entry periods apply. Ends 11:59:59pm PT on 4/30/20. Limit one entry per product review by email invitation only. Subject to Official Rules. Sponsor: HP Inc., 1501 Page Mill Road, Palo Alto, CA 94304-1185.
Spectre 1 9 42
The personal information you provide will be used according to the HP Privacy Statement (https://www8.hp.com/us/en/privacy/ww-privacy.html)