[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)