diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 16:49:04 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 16:49:04 +0000 |
commit | 16f504a9dca3fe3b70568f67b7d41241ae485288 (patch) | |
tree | c60f36ada0496ba928b7161059ba5ab1ab224f9d /src/VBox/VMM/tools/VBoxVMMPreload.cpp | |
parent | Initial commit. (diff) | |
download | virtualbox-16f504a9dca3fe3b70568f67b7d41241ae485288.tar.xz virtualbox-16f504a9dca3fe3b70568f67b7d41241ae485288.zip |
Adding upstream version 7.0.6-dfsg.upstream/7.0.6-dfsgupstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/VBox/VMM/tools/VBoxVMMPreload.cpp')
-rw-r--r-- | src/VBox/VMM/tools/VBoxVMMPreload.cpp | 233 |
1 files changed, 233 insertions, 0 deletions
diff --git a/src/VBox/VMM/tools/VBoxVMMPreload.cpp b/src/VBox/VMM/tools/VBoxVMMPreload.cpp new file mode 100644 index 00000000..50f5d0d6 --- /dev/null +++ b/src/VBox/VMM/tools/VBoxVMMPreload.cpp @@ -0,0 +1,233 @@ +/* $Id: VBoxVMMPreload.cpp $ */ +/** @file + * VBoxVMMPreload - Preload VBox the ring-0 modules. + */ + +/* + * Copyright (C) 2012-2022 Oracle and/or its affiliates. + * + * This file is part of VirtualBox base platform packages, as + * available from https://www.virtualbox.org. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation, in version 3 of the + * License. + * + * This program 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 + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <https://www.gnu.org/licenses>. + * + * SPDX-License-Identifier: GPL-3.0-only + */ + + +/********************************************************************************************************************************* +* Header Files * +*********************************************************************************************************************************/ +#include <iprt/buildconfig.h> +#include <iprt/getopt.h> +#include <iprt/initterm.h> +#include <iprt/message.h> +#include <iprt/path.h> +#include <iprt/stream.h> +#include <iprt/string.h> +#include <iprt/thread.h> + +#include <VBox/sup.h> +#include <VBox/version.h> + + +/********************************************************************************************************************************* +* Global Variables * +*********************************************************************************************************************************/ +/** + * Known modules and their associated data (there are only known modules!). + */ +static struct +{ + const char *pszName; + bool fPreload; + void *pvImageBase; +} g_aModules[] = +{ + { "VMMR0.r0", true, NULL }, + { "VBoxDDR0.r0", true, NULL }, +}; + +static uint32_t g_cVerbose = 1; +static bool g_fLockDown = false; + + +/** + * Parses the options. + * + * @returns RTEXITCODE_SUCCESS on success. + * @param argc Argument count . + * @param argv Argument vector. + * @param pfExit Set to @c true if we should exit. + */ +static RTEXITCODE ParseOptions(int argc, char **argv, bool *pfExit) +{ + /* + * Parse arguments. + */ + static const RTGETOPTDEF s_aOptions[] = + { + { "--only", 'o', RTGETOPT_REQ_STRING }, + { "--quiet", 'q', RTGETOPT_REQ_NOTHING }, + { "--lock" , 'l', RTGETOPT_REQ_NOTHING }, + { "--verbose", 'v', RTGETOPT_REQ_NOTHING }, + }; + + bool fAll = true; + + int ch; + RTGETOPTUNION ValueUnion; + RTGETOPTSTATE GetState; + RTGetOptInit(&GetState, argc, argv, s_aOptions, RT_ELEMENTS(s_aOptions), 1, 0 /* fFlags */); + while ((ch = RTGetOpt(&GetState, &ValueUnion))) + { + switch(ch) + { + case 'o': + { + uint32_t i; + + if (fAll) + { + fAll = false; + for (i = 0; i < RT_ELEMENTS(g_aModules); i++) + g_aModules[i].fPreload = false; + } + + i = RT_ELEMENTS(g_aModules); + while (i-- > 0) + if (!strcmp(ValueUnion.psz, g_aModules[i].pszName)) + { + g_aModules[i].fPreload = true; + break; + } + if (i > RT_ELEMENTS(g_aModules)) + return RTMsgErrorExit(RTEXITCODE_FAILURE, "No known module '%s'", ValueUnion.psz); + break; + } + + case 'v': + g_cVerbose++; + break; + + case 'q': + g_cVerbose = 0; + break; + + case 'l': + g_fLockDown = true; + break; + + case 'h': + RTPrintf(VBOX_PRODUCT " VMM ring-0 Module Preloader Version " VBOX_VERSION_STRING + "Copyright (C) 2005-" VBOX_C_YEAR " " VBOX_VENDOR "\n" + "\n" + "Usage: VBoxVMMPreload [-hlqvV] [-o|--only <mod>]\n" + "\n"); + *pfExit = true; + return RTEXITCODE_SUCCESS; + + case 'V': + RTPrintf("%sr%s\n", RTBldCfgVersion(), RTBldCfgRevisionStr()); + *pfExit = true; + return RTEXITCODE_SUCCESS; + + default: + return RTGetOptPrintError(ch, &ValueUnion); + } + } + return RTEXITCODE_SUCCESS; +} + + +/** + * Loads the modules. + * + * @returns RTEXITCODE_SUCCESS on success. + */ +static RTEXITCODE LoadModules(void) +{ + RTERRINFOSTATIC ErrInfo; + + for (uint32_t i = 0; i < RT_ELEMENTS(g_aModules); i++) + { + if (g_aModules[i].fPreload) + { + char szPath[RTPATH_MAX]; + int rc = RTPathAppPrivateArch(szPath, sizeof(szPath)); + if (RT_SUCCESS(rc)) + rc = RTPathAppend(szPath, sizeof(szPath), g_aModules[i].pszName); + if (RT_FAILURE(rc)) + return RTMsgErrorExit(RTEXITCODE_FAILURE, "RTPathAppPrivateArch or RTPathAppend returned %Rrc", rc); + + RTErrInfoInitStatic(&ErrInfo); + rc = SUPR3LoadModule(szPath, g_aModules[i].pszName, &g_aModules[i].pvImageBase, &ErrInfo.Core); + if (RT_FAILURE(rc)) + return RTMsgErrorExit(RTEXITCODE_FAILURE, "SUPR3LoadModule failed for %s (%s): %s (rc=%Rrc)", + g_aModules[i].pszName, szPath, ErrInfo.Core.pszMsg, rc); + if (g_cVerbose >= 1) + RTMsgInfo("Loaded '%s' ('%s') at %p\n", szPath, g_aModules[i].pszName, g_aModules[i].pvImageBase); + } + } + + if (g_fLockDown) + { + RTErrInfoInitStatic(&ErrInfo); + int rc = SUPR3LockDownLoader(&ErrInfo.Core); + if (RT_FAILURE(rc)) + return RTMsgErrorExit(RTEXITCODE_FAILURE, "SUPR3LockDownLoader failed: %s (rc=%Rrc)", + ErrInfo.Core.pszMsg, rc); + if (g_cVerbose >= 1) + RTMsgInfo("Locked down module loader interface!\n"); + } + + RTStrmFlush(g_pStdOut); + return RTEXITCODE_SUCCESS; +} + + +/** + * Entry point. + */ +extern "C" DECLEXPORT(int) TrustedMain(int argc, char **argv, char **envp) +{ + RT_NOREF1(envp); + bool fExit = false; + RTEXITCODE rcExit = ParseOptions(argc, argv, &fExit); + if (rcExit == RTEXITCODE_SUCCESS && !fExit) + { + rcExit = LoadModules(); + if (rcExit == RTEXITCODE_SUCCESS) + { + for (;;) + RTThreadSleep(RT_INDEFINITE_WAIT); + } + } + return rcExit; +} + + +#ifndef VBOX_WITH_HARDENING +/** + * Main entry point. + */ +int main(int argc, char **argv, char **envp) +{ + int rc = RTR3InitExe(argc, &argv, RTR3INIT_FLAGS_SUPLIB); + if (RT_SUCCESS(rc)) + return TrustedMain(argc, argv, envp); + return RTMsgInitFailure(rc); +} +#endif /* !VBOX_WITH_HARDENING */ + |