diff options
Diffstat (limited to 'tests/qemu.h')
-rw-r--r-- | tests/qemu.h | 98 |
1 files changed, 98 insertions, 0 deletions
diff --git a/tests/qemu.h b/tests/qemu.h new file mode 100644 index 00000000..a5ed16ab --- /dev/null +++ b/tests/qemu.h @@ -0,0 +1,98 @@ +/* Determine whether the current process is running under QEMU. + Copyright (C) 2021-2024 Free Software Foundation, Inc. + + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. + + This file is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see <https://www.gnu.org/licenses/>. */ + +/* Written by Bruno Haible <bruno@clisp.org>, 2021. */ + +#ifdef __linux__ +# include <fcntl.h> +# include <string.h> +# include <unistd.h> +#endif + +/* This function determines whether the current process is running under QEMU + (user-mode). + + It does so by looking at parts of the environment that QEMU does not emulate + 100% perfectly well. + + For comparison, the techniques given in the paper + Thomas Raffetseder, Christopher Kruegel, Engin Kirda + "Detecting System Emulators" + 2007 + https://publik.tuwien.ac.at/files/pub-inf_5317.pdf + apply to both the QEMU system mode and QEMU user mode. */ + +static bool +is_running_under_qemu_user (void) +{ +#ifdef __linux__ + char buf[4096 + 1]; + int fd; + +# if defined __m68k__ + fd = open ("/proc/hardware", O_RDONLY); + if (fd >= 0) + { + int n = read (fd, buf, sizeof (buf) - 1); + close (fd); + if (n > 0) + { + buf[n] = '\0'; + if (strstr (buf, "qemu") != NULL) + return true; + } + } +# endif + + fd = open ("/proc/cpuinfo", O_RDONLY); + if (fd >= 0) + { + int n = read (fd, buf, sizeof (buf) - 1); + close (fd); + if (n > 0) + { + buf[n] = '\0'; +# if defined __hppa__ + if (strstr (buf, "QEMU") != NULL) + return true; +# endif +# if !(defined __i386__ || defined __x86_64__) + if (strstr (buf, "AuthenticAMD") != NULL + || strstr (buf, "GenuineIntel") != NULL) + return true; +# endif +# if !(defined __arm__ || defined __aarch64__) + if (strstr (buf, "ARM") != NULL + || strcasestr (buf, "aarch64") != NULL) + return true; +# endif +# if !defined __sparc__ + if (strcasestr (buf, "SPARC") != NULL) + return true; +# endif +# if !defined __powerpc__ + if (strstr (buf, "POWER") != NULL) + return true; +# endif + } + } + + /* If you need more heuristics, look at system calls that are not perfectly + well emulated in qemu/linux-user/syscall.c. */ +#endif + + return false; +} |