[HN Gopher] Why you can't trust CPUID
___________________________________________________________________
Why you can't trust CPUID
Author : rbanffy
Score : 56 points
Date : 2022-10-28 11:12 UTC (11 hours ago)
(HTM) web link (chipsandcheese.com)
(TXT) w3m dump (chipsandcheese.com)
| bravetraveler wrote:
| This was reaffirmed however long ago virtualization came about
| q-big wrote:
| Don't forget that the likely reason why the capability to change
| the CPUID was introduced by AMD in its processors is that Intel
| (mis)used the CPUID feature via its compiler making the compiled
| program run faster if it runs on an Intel CPU (detected via
| whether CPUID is GenuineIntel, not by checking for CPU features):
|
| > https://www.agner.org/optimize/blog/read.php?i=73
| theamk wrote:
| I don't understand why this matters.. if journalists are trusting
| random screenshot (or database entry) it could obviously be
| faked! Forget advanced MSR manipulation, one can just photoshop
| the screenshot, or open in debugger and edit window elements, or
| binary-patch the executable. Same goes with database entry - I
| bet the result submission is some HTTPs call which can be
| mitmproxy-ed and edited.
|
| So the real title should have been: "You thought there are 5 ways
| to fake test results? Nope, there are 6." Not nearly as exciting.
| rbanffy wrote:
| CPUID is not designed to be secure, but, if every CPU model had
| a (directly inaccessible) unique key, it could be used to sign
| a challenge and prove that CPU is what it's telling the program
| it is.
| ilyt wrote:
| Yeah we don't want that. Faking the feature list is quite
| useful for VMs, if say you have Zen 2 and Zen 3 CPUs in your
| cluster but still want VMs to be live-migrable between the
| two
| josefx wrote:
| Which leads back to the issue that the current top comment
| mentions. Intel has been caught using vendor Id checks to
| undermine performance on competing CPUs. Hence keeping the
| identity mutable may be necessary to protect against very
| real and very well known bad actors.
| mindslight wrote:
| The same functionality could and would be abused to make sure
| you were running a specific version of Internet Explorer on a
| certain version of Microsoft Windows (or equivalent locked
| down system) to get access to a website. Freedom relies on
| the the authority boundaries created by open protocols, and
| such "remote attestation" schemes would be the death of it.
| theamk wrote:
| I suppose, but what would be the use case of this? It
| definitely won't in the "reliable benchmark" case, as the
| check could be just patched out.
| [deleted]
| TillE wrote:
| I'm not sure why anyone would trust random Geekbench database
| entries in any case, there's no way to authenticate anything. I
| suspect you can just edit the process memory after running a
| benchmark and before submitting the results, to save yourself the
| trouble of reverse engineering their web API.
| yellow_lead wrote:
| Yeah why do you even need to change the CPU ID, this would be
| much easier.
| blueflow wrote:
| This already has been a problem in the 80ies when Intel VM86 mode
| came into use - real mode programs tested the unused bits in the
| status register and then made assumptions about the CPU (as
| recommended by Intel in the programming manuals). When the
| program was running inside a VM86 environment (virtual real mode
| inside of protected mode), the instruction for this triggered an
| protection fault, and the "hypervisor" filled in the results as
| if it got executed correctly, potentially confusing programs
| about which CPU they were running on.
| nixcraft wrote:
| For those who are not using Windows as the main daily driver: On
| Linux, you can just run the `lscpu` command, which reads info
| from the /proc/cpuinfo file, but there is a CPU-X[1] GUI app too.
| Free software gathers information on the CPU, motherboard and
| more. Similar to CPU-Z for Windows but works on Linux and
| FreeBSD. It isn't possible to trick /proc/cpuinfo on Linux, it
| always gave me the correct info.
|
| [1] https://x0rg.github.io/CPU-X/
| Liquid_Fire wrote:
| > It isn't possible to trick /proc/cpuinfo on Linux, it always
| gave me the correct info.
|
| Is this because Linux reads this once at boot time, before you
| have a chance to modify it? If so, I assume you could still
| modify the string from the firmware, bootloader, or simply by
| modifying the kernel.
| bravetraveler wrote:
| I don't know exactly how it's maintained, but you're 100%
| right -- it can be modified elsewhere
|
| For example, on my AMD Threadripper system I can make a VM
| that pretends to be essentially any Xeon
|
| It may perform horribly where features/extensions don't line
| up, but it'll report whatever.
|
| For physical devices it's possible too, just not nearly as
| common
| ilyt wrote:
| It's because hypervisor intercepts the call for CPUID and
| returns what you told you to.
|
| It's usually used to downgrade a set of features if you
| want VM to be able to be live-migrated between machines
| with different CPUs, we migrated a bunch of stuff off Intel
| to AMD that way. There is a performance hit on that as
| you're basically making virtual "lowest common denominator"
| CPU
| bravetraveler wrote:
| Thank you! I was aware of the downgrading for live-
| migration, but not that there was a particular call for
| it
| pjc50 wrote:
| That's a VM. It will be trapping CPUID at the instruction
| level and returning whatever the VM is set up as.
| nixcraft wrote:
| Here is what: ls -l /proc/cpuinfo
|
| It says (basically it is a pseudo-filesystem with read-only
| permission, so I don't think so it is possible without
| making any changes at the Linux kernel/driver level):
| -r--r--r-- 1 root root 0 Oct 28 09:38 /proc/cpuinfo
| dezgeg wrote:
| I wonder if one could bind-mount some other proc file
| (say /proc/$EVIL_PID/cmdline) over cpuinfo to fake
| content. Would meet root and be visible in mount output
| though.
| stormbrew wrote:
| You definitely can and things like that are precisely why
| bind mounts (usually) require root, because POSIX is
| built very much on the premise of one filesystem tree
| seen by both privileged and unprivileged users.
|
| Other systems do better by not depending on that.
| raimue wrote:
| It would be easier to intercept the open() for the
| /proc/cpuinfo file with a LD_PRELOAD library. Of course
| that would still be detectable by the benchmark. You
| could also use a modified libc to spoof it. Then their
| only way out would be static linking.
|
| You could even just modify the kernel to report arbitrary
| strings in /proc/cpuinfo.
|
| So they use the CPUID instruction instead. The CPUID
| instruction can be trapped to throw a SIGSEGV instead of
| returning real values on x86 with
| arch_prctl(ARCH_SET_CPUID, 0). So an injected SIGSEGV
| handler could then spoof it.
|
| But even then, you could also trap the CPUID instruction
| in the kernel, and spoof it from there, which would be
| even harder to detect from user space.
|
| In the end, the benchmark program always needs to trust
| the kernel. Is it really worth trying to detect spoofing?
| bravetraveler wrote:
| Indeed, the proc filesystem is well maintained by the
| kernel. I understand that part, less so if it's properly
| immutable/irreplaceable
|
| The thing is, it has to get the information from
| somewhere -- and depending on the age/type of the
| hardware (physical or virtualized), masking this is
| either easy or nearly impossible
|
| I remember changing this information (DMI?) was more
| common back in the like Pentium 3 era, for example.
| bravetraveler wrote:
| Others have helped me understand this is part of the
| CPUID thing -- you know, the core of the topic for the
| overall post!
|
| I appreciate it everyone, save your fingers :)
|
| I've seen this done for physical chips before too, but I
| can't recall anything - hence vagueness
___________________________________________________________________
(page generated 2022-10-28 23:02 UTC)