(root)/
gettext-0.22.4/
gettext-tools/
gnulib-tests/
qemu.h
       1  /* Determine whether the current process is running under QEMU.
       2     Copyright (C) 2021-2023 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  #ifdef __linux__
      20  # include <fcntl.h>
      21  # include <string.h>
      22  # include <unistd.h>
      23  #endif
      24  
      25  /* This function determines whether the current process is running under QEMU
      26     (user-mode).
      27  
      28     It does so by looking at parts of the environment that QEMU does not emulate
      29     100% perfectly well.
      30  
      31     For comparison, the techniques given in the paper
      32       Thomas Raffetseder, Christopher Kruegel, Engin Kirda
      33       "Detecting System Emulators"
      34       2007
      35       https://publik.tuwien.ac.at/files/pub-inf_5317.pdf
      36     apply to both the QEMU system mode and QEMU user mode.  */
      37  
      38  static bool
      39  is_running_under_qemu_user (void)
      40  {
      41  #ifdef __linux__
      42    char buf[4096 + 1];
      43    int fd;
      44  
      45  # if defined __m68k__
      46    fd = open ("/proc/hardware", O_RDONLY);
      47    if (fd >= 0)
      48      {
      49        int n = read (fd, buf, sizeof (buf) - 1);
      50        close (fd);
      51        if (n > 0)
      52          {
      53            buf[n] = '\0';
      54            if (strstr (buf, "qemu") != NULL)
      55              return true;
      56          }
      57      }
      58  # endif
      59  
      60    fd = open ("/proc/cpuinfo", O_RDONLY);
      61    if (fd >= 0)
      62      {
      63        int n = read (fd, buf, sizeof (buf) - 1);
      64        close (fd);
      65        if (n > 0)
      66          {
      67            buf[n] = '\0';
      68  # if defined __hppa__
      69            if (strstr (buf, "QEMU") != NULL)
      70              return true;
      71  # endif
      72  # if !(defined __i386__ || defined __x86_64__)
      73            if (strstr (buf, "AuthenticAMD") != NULL
      74                || strstr (buf, "GenuineIntel") != NULL)
      75              return true;
      76  # endif
      77  # if !(defined __arm__ || defined __aarch64__)
      78            if (strstr (buf, "ARM") != NULL
      79                || strcasestr (buf, "aarch64") != NULL)
      80              return true;
      81  # endif
      82  # if !defined __sparc__
      83            if (strcasestr (buf, "SPARC") != NULL)
      84              return true;
      85  # endif
      86  # if !defined __powerpc__
      87            if (strstr (buf, "POWER") != NULL)
      88              return true;
      89  # endif
      90          }
      91      }
      92  
      93    /* If you need more heuristics, look at system calls that are not perfectly
      94       well emulated in qemu/linux-user/syscall.c.  */
      95  #endif
      96  
      97    return false;
      98  }