(root)/
findutils-4.9.0/
gnulib-tests/
qemu.h
       1  /* Determine whether the current process is running under QEMU.
       2     Copyright (C) 2021-2022 Free Software Foundation, Inc.
       3  
       4     This file is free software: you can redistribute it and/or modify
       5     it under the terms of the GNU Lesser General Public License as
       6     published by the Free Software Foundation; either version 2.1 of the
       7     License, or (at your option) any later version.
       8  
       9     This file is distributed in the hope that it will be useful,
      10     but WITHOUT ANY WARRANTY; without even the implied warranty of
      11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      12     GNU Lesser General Public License for more details.
      13  
      14     You should have received a copy of the GNU Lesser General Public License
      15     along with this program.  If not, see <https://www.gnu.org/licenses/>.  */
      16  
      17  /* Written by Bruno Haible <bruno@clisp.org>, 2021.  */
      18  
      19  #include <stdbool.h>
      20  #ifdef __linux__
      21  # include <fcntl.h>
      22  # include <string.h>
      23  # include <unistd.h>
      24  #endif
      25  
      26  /* This function determines whether the current process is running under QEMU
      27     (user-mode).
      28  
      29     It does so by looking at parts of the environment that QEMU does not emulate
      30     100% perfectly well.
      31  
      32     For comparison, the techniques given in the paper
      33       Thomas Raffetseder, Christopher Kruegel, Engin Kirda
      34       "Detecting System Emulators"
      35       2007
      36       https://publik.tuwien.ac.at/files/pub-inf_5317.pdf
      37     apply to both the QEMU system mode and QEMU user mode.  */
      38  
      39  static bool
      40  is_running_under_qemu_user (void)
      41  {
      42  #ifdef __linux__
      43    char buf[4096 + 1];
      44    int fd;
      45  
      46  # if defined __m68k__
      47    fd = open ("/proc/hardware", O_RDONLY);
      48    if (fd >= 0)
      49      {
      50        int n = read (fd, buf, sizeof (buf) - 1);
      51        close (fd);
      52        if (n > 0)
      53          {
      54            buf[n] = '\0';
      55            if (strstr (buf, "qemu") != NULL)
      56              return true;
      57          }
      58      }
      59  # endif
      60  
      61    fd = open ("/proc/cpuinfo", O_RDONLY);
      62    if (fd >= 0)
      63      {
      64        int n = read (fd, buf, sizeof (buf) - 1);
      65        close (fd);
      66        if (n > 0)
      67          {
      68            buf[n] = '\0';
      69  # if defined __hppa__
      70            if (strstr (buf, "QEMU") != NULL)
      71              return true;
      72  # endif
      73  # if !(defined __i386__ || defined __x86_64__)
      74            if (strstr (buf, "AuthenticAMD") != NULL
      75                || strstr (buf, "GenuineIntel") != NULL)
      76              return true;
      77  # endif
      78  # if !(defined __arm__ || defined __aarch64__)
      79            if (strstr (buf, "ARM") != NULL
      80                || strcasestr (buf, "aarch64") != NULL)
      81              return true;
      82  # endif
      83  # if !defined __sparc__
      84            if (strcasestr (buf, "SPARC") != NULL)
      85              return true;
      86  # endif
      87  # if !defined __powerpc__
      88            if (strstr (buf, "POWER") != NULL)
      89              return true;
      90  # endif
      91          }
      92      }
      93  
      94    /* If you need more heuristics, look at system calls that are not perfectly
      95       well emulated in qemu/linux-user/syscall.c.  */
      96  #endif
      97  
      98    return false;
      99  }