SUPR3HardenedVerify.cpp revision f5eadb22976c1f9813300e4042b8255cfaef7e19
5f9dfb422a6ed57822f9c0cb94fa7df8d24acc9bvboxsync * VirtualBox Support Library - Verification of Hardened Installation.
5f9dfb422a6ed57822f9c0cb94fa7df8d24acc9bvboxsync * Copyright (C) 2006-2010 Oracle Corporation
5f9dfb422a6ed57822f9c0cb94fa7df8d24acc9bvboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
5f9dfb422a6ed57822f9c0cb94fa7df8d24acc9bvboxsync * available from http://www.virtualbox.org. This file is free software;
5f9dfb422a6ed57822f9c0cb94fa7df8d24acc9bvboxsync * you can redistribute it and/or modify it under the terms of the GNU
5f9dfb422a6ed57822f9c0cb94fa7df8d24acc9bvboxsync * General Public License (GPL) as published by the Free Software
5f9dfb422a6ed57822f9c0cb94fa7df8d24acc9bvboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
5f9dfb422a6ed57822f9c0cb94fa7df8d24acc9bvboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
5f9dfb422a6ed57822f9c0cb94fa7df8d24acc9bvboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
5f9dfb422a6ed57822f9c0cb94fa7df8d24acc9bvboxsync * The contents of this file may alternatively be used under the terms
5f9dfb422a6ed57822f9c0cb94fa7df8d24acc9bvboxsync * of the Common Development and Distribution License Version 1.0
5f9dfb422a6ed57822f9c0cb94fa7df8d24acc9bvboxsync * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
5f9dfb422a6ed57822f9c0cb94fa7df8d24acc9bvboxsync * VirtualBox OSE distribution, in which case the provisions of the
5f9dfb422a6ed57822f9c0cb94fa7df8d24acc9bvboxsync * CDDL are applicable instead of those of the GPL.
5f9dfb422a6ed57822f9c0cb94fa7df8d24acc9bvboxsync * You may elect to license modified versions of this file under the
5f9dfb422a6ed57822f9c0cb94fa7df8d24acc9bvboxsync * terms and conditions of either the GPL or the CDDL or both.
5f9dfb422a6ed57822f9c0cb94fa7df8d24acc9bvboxsync/*******************************************************************************
5f9dfb422a6ed57822f9c0cb94fa7df8d24acc9bvboxsync* Header Files *
5f9dfb422a6ed57822f9c0cb94fa7df8d24acc9bvboxsync*******************************************************************************/
5f9dfb422a6ed57822f9c0cb94fa7df8d24acc9bvboxsync#else /* UNIXes */
5f9dfb422a6ed57822f9c0cb94fa7df8d24acc9bvboxsync/*******************************************************************************
5f9dfb422a6ed57822f9c0cb94fa7df8d24acc9bvboxsync* Defined Constants And Macros *
5f9dfb422a6ed57822f9c0cb94fa7df8d24acc9bvboxsync*******************************************************************************/
5f9dfb422a6ed57822f9c0cb94fa7df8d24acc9bvboxsync/** The max path length acceptable for a trusted path. */
5f9dfb422a6ed57822f9c0cb94fa7df8d24acc9bvboxsync/*******************************************************************************
5f9dfb422a6ed57822f9c0cb94fa7df8d24acc9bvboxsync* Global Variables *
5f9dfb422a6ed57822f9c0cb94fa7df8d24acc9bvboxsync*******************************************************************************/
5f9dfb422a6ed57822f9c0cb94fa7df8d24acc9bvboxsync * The files that gets verified.
5f9dfb422a6ed57822f9c0cb94fa7df8d24acc9bvboxsync * @todo This needs reviewing against the linux packages.
5f9dfb422a6ed57822f9c0cb94fa7df8d24acc9bvboxsync * @todo The excessive use of kSupID_SharedLib needs to be reviewed at some point. For
5f9dfb422a6ed57822f9c0cb94fa7df8d24acc9bvboxsync * the time being we're building the linux packages with SharedLib pointing to
c6adb272ec43d5eaadb1493cb2bf45f2f8adf588vboxsync * AppPrivArch (lazy bird).
1d17a5f9688f3622ffe088b664588629b1e95801vboxsync /* type, dir, fOpt, "pszFile" */
c48c4d769ded37e2496f97dddbbd36dc62f244b1vboxsync /* ---------------------------------------------------------------------- */
c48c4d769ded37e2496f97dddbbd36dc62f244b1vboxsync { kSupIFT_Dll, kSupID_AppPrivArch, false, "VMMR0.r0" },
c48c4d769ded37e2496f97dddbbd36dc62f244b1vboxsync { kSupIFT_Dll, kSupID_AppPrivArch, false, "VBoxDDR0.r0" },
c48c4d769ded37e2496f97dddbbd36dc62f244b1vboxsync { kSupIFT_Dll, kSupID_AppPrivArch, false, "VBoxDD2R0.r0" },
e00d701bbdc8f27f25cc232d9e507622a731b390vboxsync { kSupIFT_Dll, kSupID_AppPrivArch, false, "VMMGC.gc" },
5f9dfb422a6ed57822f9c0cb94fa7df8d24acc9bvboxsync { kSupIFT_Dll, kSupID_AppPrivArch, false, "VBoxDDGC.gc" },
e00d701bbdc8f27f25cc232d9e507622a731b390vboxsync { kSupIFT_Dll, kSupID_AppPrivArch, false, "VBoxDD2GC.gc" },
5f9dfb422a6ed57822f9c0cb94fa7df8d24acc9bvboxsync { kSupIFT_Dll, kSupID_SharedLib, false, "VBoxRT" SUPLIB_DLL_SUFF },
5f9dfb422a6ed57822f9c0cb94fa7df8d24acc9bvboxsync { kSupIFT_Dll, kSupID_SharedLib, false, "VBoxVMM" SUPLIB_DLL_SUFF },
5f9dfb422a6ed57822f9c0cb94fa7df8d24acc9bvboxsync { kSupIFT_Dll, kSupID_SharedLib, false, "VBoxREM" SUPLIB_DLL_SUFF },
254365851c06fac7efeae0a0bf727ed6c6940611vboxsync { kSupIFT_Dll, kSupID_SharedLib, true, "VBoxREM32" SUPLIB_DLL_SUFF },
5f9dfb422a6ed57822f9c0cb94fa7df8d24acc9bvboxsync { kSupIFT_Dll, kSupID_SharedLib, true, "VBoxREM64" SUPLIB_DLL_SUFF },
5f9dfb422a6ed57822f9c0cb94fa7df8d24acc9bvboxsync { kSupIFT_Dll, kSupID_SharedLib, false, "VBoxDD" SUPLIB_DLL_SUFF },
254365851c06fac7efeae0a0bf727ed6c6940611vboxsync { kSupIFT_Dll, kSupID_SharedLib, false, "VBoxDD2" SUPLIB_DLL_SUFF },
5f9dfb422a6ed57822f9c0cb94fa7df8d24acc9bvboxsync { kSupIFT_Dll, kSupID_SharedLib, false, "VBoxDDU" SUPLIB_DLL_SUFF },
5f9dfb422a6ed57822f9c0cb94fa7df8d24acc9bvboxsync//#ifdef VBOX_WITH_DEBUGGER_GUI
254365851c06fac7efeae0a0bf727ed6c6940611vboxsync { kSupIFT_Dll, kSupID_SharedLib, true, "VBoxDbg" SUPLIB_DLL_SUFF },
5f9dfb422a6ed57822f9c0cb94fa7df8d24acc9bvboxsync { kSupIFT_Dll, kSupID_SharedLib, true, "VBoxDbg3" SUPLIB_DLL_SUFF },
5f9dfb422a6ed57822f9c0cb94fa7df8d24acc9bvboxsync//#ifdef VBOX_WITH_SHARED_CLIPBOARD
5f9dfb422a6ed57822f9c0cb94fa7df8d24acc9bvboxsync { kSupIFT_Dll, kSupID_AppPrivArch, true, "VBoxSharedClipboard" SUPLIB_DLL_SUFF },
5f9dfb422a6ed57822f9c0cb94fa7df8d24acc9bvboxsync//#ifdef VBOX_WITH_SHARED_FOLDERS
5f9dfb422a6ed57822f9c0cb94fa7df8d24acc9bvboxsync { kSupIFT_Dll, kSupID_AppPrivArch, true, "VBoxSharedFolders" SUPLIB_DLL_SUFF },
5f9dfb422a6ed57822f9c0cb94fa7df8d24acc9bvboxsync//#ifdef VBOX_WITH_GUEST_PROPS
5f9dfb422a6ed57822f9c0cb94fa7df8d24acc9bvboxsync { kSupIFT_Dll, kSupID_AppPrivArch, true, "VBoxGuestPropSvc" SUPLIB_DLL_SUFF },
5f9dfb422a6ed57822f9c0cb94fa7df8d24acc9bvboxsync//#ifdef VBOX_WITH_GUEST_CONTROL
5f9dfb422a6ed57822f9c0cb94fa7df8d24acc9bvboxsync { kSupIFT_Dll, kSupID_AppPrivArch, true, "VBoxGuestControlSvc" SUPLIB_DLL_SUFF },
5f9dfb422a6ed57822f9c0cb94fa7df8d24acc9bvboxsync { kSupIFT_Dll, kSupID_AppPrivArch, true, "VBoxSharedCrOpenGL" SUPLIB_DLL_SUFF },
5f9dfb422a6ed57822f9c0cb94fa7df8d24acc9bvboxsync { kSupIFT_Dll, kSupID_AppPrivArch, true, "VBoxOGLhostcrutil" SUPLIB_DLL_SUFF },
5f9dfb422a6ed57822f9c0cb94fa7df8d24acc9bvboxsync { kSupIFT_Dll, kSupID_AppPrivArch, true, "VBoxOGLhosterrorspu" SUPLIB_DLL_SUFF },
5f9dfb422a6ed57822f9c0cb94fa7df8d24acc9bvboxsync { kSupIFT_Dll, kSupID_AppPrivArch, true, "VBoxOGLrenderspu" SUPLIB_DLL_SUFF },
5f9dfb422a6ed57822f9c0cb94fa7df8d24acc9bvboxsync { kSupIFT_Exe, kSupID_AppBin, true, "VBoxManage" SUPLIB_EXE_SUFF },
58b7773f17a933ab8d53f450bed0afcf2f003508vboxsync { kSupIFT_Exe, kSupID_AppBin, false, "VBoxSVC" SUPLIB_EXE_SUFF },
58b7773f17a933ab8d53f450bed0afcf2f003508vboxsync { kSupIFT_Dll, kSupID_AppPrivArchComp, false, "VBoxC" SUPLIB_DLL_SUFF },
5f9dfb422a6ed57822f9c0cb94fa7df8d24acc9bvboxsync { kSupIFT_Exe, kSupID_AppPrivArch, false, "VBoxXPCOMIPCD" SUPLIB_EXE_SUFF },
58b7773f17a933ab8d53f450bed0afcf2f003508vboxsync { kSupIFT_Dll, kSupID_SharedLib, false, "VBoxXPCOM" SUPLIB_DLL_SUFF },
5f9dfb422a6ed57822f9c0cb94fa7df8d24acc9bvboxsync { kSupIFT_Dll, kSupID_AppPrivArchComp, false, "VBoxXPCOMIPCC" SUPLIB_DLL_SUFF },
7eaaa8a4480370b82ef3735994f986f338fb4df2vboxsync { kSupIFT_Dll, kSupID_AppPrivArchComp, false, "VBoxC" SUPLIB_DLL_SUFF },
5f9dfb422a6ed57822f9c0cb94fa7df8d24acc9bvboxsync { kSupIFT_Dll, kSupID_AppPrivArchComp, false, "VBoxSVCM" SUPLIB_DLL_SUFF },
5f9dfb422a6ed57822f9c0cb94fa7df8d24acc9bvboxsync { kSupIFT_Data, kSupID_AppPrivArchComp, false, "VBoxXPCOMBase.xpt" },
5f9dfb422a6ed57822f9c0cb94fa7df8d24acc9bvboxsync { kSupIFT_Dll, kSupID_SharedLib, true, "VRDPAuth" SUPLIB_DLL_SUFF },
5f9dfb422a6ed57822f9c0cb94fa7df8d24acc9bvboxsync { kSupIFT_Dll, kSupID_SharedLib, true, "VBoxAuth" SUPLIB_DLL_SUFF },
5f9dfb422a6ed57822f9c0cb94fa7df8d24acc9bvboxsync { kSupIFT_Dll, kSupID_SharedLib, true, "VBoxVRDP" SUPLIB_DLL_SUFF },
cf5af7fccfec4bef83f4ec21662d6a6e6cbe3835vboxsync//#ifdef VBOX_WITH_HEADLESS
cf5af7fccfec4bef83f4ec21662d6a6e6cbe3835vboxsync { kSupIFT_Exe, kSupID_AppBin, true, "VBoxHeadless" SUPLIB_EXE_SUFF },
0c587d7af645db20acefebcfc15b6f46c440ba4avboxsync { kSupIFT_Dll, kSupID_AppPrivArch, true, "VBoxHeadless" SUPLIB_DLL_SUFF },
0c587d7af645db20acefebcfc15b6f46c440ba4avboxsync { kSupIFT_Dll, kSupID_AppPrivArch, true, "VBoxFFmpegFB" SUPLIB_DLL_SUFF },
0c587d7af645db20acefebcfc15b6f46c440ba4avboxsync//#ifdef VBOX_WITH_QTGUI
0c587d7af645db20acefebcfc15b6f46c440ba4avboxsync { kSupIFT_Exe, kSupID_AppBin, true, "VirtualBox" SUPLIB_EXE_SUFF },
0c587d7af645db20acefebcfc15b6f46c440ba4avboxsync { kSupIFT_Dll, kSupID_AppPrivArch, true, "VirtualBox" SUPLIB_DLL_SUFF },
cf5af7fccfec4bef83f4ec21662d6a6e6cbe3835vboxsync# if !defined(RT_OS_DARWIN) && !defined(RT_OS_WINDOWS) && !defined(RT_OS_OS2)
cf5af7fccfec4bef83f4ec21662d6a6e6cbe3835vboxsync { kSupIFT_Dll, kSupID_SharedLib, true, "VBoxKeyboard" SUPLIB_DLL_SUFF },
cf5af7fccfec4bef83f4ec21662d6a6e6cbe3835vboxsync//#ifdef VBOX_WITH_VBOXSDL
cf5af7fccfec4bef83f4ec21662d6a6e6cbe3835vboxsync { kSupIFT_Exe, kSupID_AppBin, true, "VBoxSDL" SUPLIB_EXE_SUFF },
5f9dfb422a6ed57822f9c0cb94fa7df8d24acc9bvboxsync { kSupIFT_Dll, kSupID_AppPrivArch, true, "VBoxSDL" SUPLIB_DLL_SUFF },
5f9dfb422a6ed57822f9c0cb94fa7df8d24acc9bvboxsync//#ifdef VBOX_WITH_VBOXBFE
5f9dfb422a6ed57822f9c0cb94fa7df8d24acc9bvboxsync { kSupIFT_Exe, kSupID_AppBin, true, "VBoxBFE" SUPLIB_EXE_SUFF },
5f9dfb422a6ed57822f9c0cb94fa7df8d24acc9bvboxsync { kSupIFT_Dll, kSupID_AppPrivArch, true, "VBoxBFE" SUPLIB_DLL_SUFF },
5f9dfb422a6ed57822f9c0cb94fa7df8d24acc9bvboxsync//#ifdef VBOX_WITH_WEBSERVICES
5f9dfb422a6ed57822f9c0cb94fa7df8d24acc9bvboxsync { kSupIFT_Exe, kSupID_AppBin, true, "vboxwebsrv" SUPLIB_EXE_SUFF },
5f9dfb422a6ed57822f9c0cb94fa7df8d24acc9bvboxsync { kSupIFT_Exe, kSupID_AppBin, true, "VBoxTunctl" SUPLIB_EXE_SUFF },
5f9dfb422a6ed57822f9c0cb94fa7df8d24acc9bvboxsync//#ifdef VBOX_WITH_NETFLT
5f9dfb422a6ed57822f9c0cb94fa7df8d24acc9bvboxsync { kSupIFT_Exe, kSupID_AppBin, true, "VBoxNetDHCP" SUPLIB_EXE_SUFF },
5f9dfb422a6ed57822f9c0cb94fa7df8d24acc9bvboxsync { kSupIFT_Dll, kSupID_AppPrivArch, true, "VBoxNetDHCP" SUPLIB_DLL_SUFF },
5f9dfb422a6ed57822f9c0cb94fa7df8d24acc9bvboxsync/** Array parallel to g_aSupInstallFiles containing per-file status info. */
5f9dfb422a6ed57822f9c0cb94fa7df8d24acc9bvboxsyncstatic SUPVERIFIEDFILE g_aSupVerifiedFiles[RT_ELEMENTS(g_aSupInstallFiles)];
5f9dfb422a6ed57822f9c0cb94fa7df8d24acc9bvboxsync/** Array index by install directory specifier containing info about verified directories. */
5f9dfb422a6ed57822f9c0cb94fa7df8d24acc9bvboxsyncstatic SUPVERIFIEDDIR g_aSupVerifiedDirs[kSupID_End];
5f9dfb422a6ed57822f9c0cb94fa7df8d24acc9bvboxsync * Assembles the path to a directory.
5f9dfb422a6ed57822f9c0cb94fa7df8d24acc9bvboxsync * @returns VINF_SUCCESS on success, some error code on failure (fFatal
5f9dfb422a6ed57822f9c0cb94fa7df8d24acc9bvboxsync * decides whether it returns or not).
5f9dfb422a6ed57822f9c0cb94fa7df8d24acc9bvboxsync * @param enmDir The directory.
5f9dfb422a6ed57822f9c0cb94fa7df8d24acc9bvboxsync * @param pszDst Where to assemble the path.
5f9dfb422a6ed57822f9c0cb94fa7df8d24acc9bvboxsync * @param cchDst The size of the buffer.
5f9dfb422a6ed57822f9c0cb94fa7df8d24acc9bvboxsync * @param fFatal Whether failures should be treated as fatal (true) or not (false).
5f9dfb422a6ed57822f9c0cb94fa7df8d24acc9bvboxsyncstatic int supR3HardenedMakePath(SUPINSTDIR enmDir, char *pszDst, size_t cchDst, bool fFatal)
5f9dfb422a6ed57822f9c0cb94fa7df8d24acc9bvboxsync case kSupID_AppBin: /** @todo fix this AppBin crap (uncertain wtf some binaries actually are installed). */
5f9dfb422a6ed57822f9c0cb94fa7df8d24acc9bvboxsync rc = supR3HardenedPathAppPrivateArch(pszDst, cchDst);
5f9dfb422a6ed57822f9c0cb94fa7df8d24acc9bvboxsync rc = supR3HardenedPathAppPrivateArch(pszDst, cchDst);
c6adb272ec43d5eaadb1493cb2bf45f2f8adf588vboxsync memcpy(&pszDst[off], "/components", sizeof("/components"));
c6adb272ec43d5eaadb1493cb2bf45f2f8adf588vboxsync rc = supR3HardenedPathAppPrivateNoArch(pszDst, cchDst);
5f9dfb422a6ed57822f9c0cb94fa7df8d24acc9bvboxsync return supR3HardenedError(VERR_INTERNAL_ERROR, fFatal,
c6adb272ec43d5eaadb1493cb2bf45f2f8adf588vboxsync "supR3HardenedMakePath: enmDir=%d rc=%d\n", enmDir, rc);
c6adb272ec43d5eaadb1493cb2bf45f2f8adf588vboxsync * Assembles the path to a file table entry, with or without the actual filename.
5f9dfb422a6ed57822f9c0cb94fa7df8d24acc9bvboxsync * @returns VINF_SUCCESS on success, some error code on failure (fFatal
5f9dfb422a6ed57822f9c0cb94fa7df8d24acc9bvboxsync * decides whether it returns or not).
5f9dfb422a6ed57822f9c0cb94fa7df8d24acc9bvboxsync * @param pFile The file table entry.
5f9dfb422a6ed57822f9c0cb94fa7df8d24acc9bvboxsync * @param pszDst Where to assemble the path.
5f9dfb422a6ed57822f9c0cb94fa7df8d24acc9bvboxsync * @param cchDst The size of the buffer.
b8908d384db2324f04a2f68a13e67ea32ebf609avboxsync * @param fWithFilename If set, the filename is included, otherwise it is omitted (no trailing slash).
5f9dfb422a6ed57822f9c0cb94fa7df8d24acc9bvboxsync * @param fFatal Whether failures should be treated as fatal (true) or not (false).
5f9dfb422a6ed57822f9c0cb94fa7df8d24acc9bvboxsyncstatic int supR3HardenedMakeFilePath(PCSUPINSTFILE pFile, char *pszDst, size_t cchDst, bool fWithFilename, bool fFatal)
5f9dfb422a6ed57822f9c0cb94fa7df8d24acc9bvboxsync * Combine supR3HardenedMakePath and the filename.
5f9dfb422a6ed57822f9c0cb94fa7df8d24acc9bvboxsync int rc = supR3HardenedMakePath(pFile->enmDir, pszDst, cchDst, fFatal);
5f9dfb422a6ed57822f9c0cb94fa7df8d24acc9bvboxsync rc = supR3HardenedError(VERR_BUFFER_OVERFLOW, fFatal,
5f9dfb422a6ed57822f9c0cb94fa7df8d24acc9bvboxsync "supR3HardenedMakeFilePath: pszFile=%s off=%lu\n",
5f9dfb422a6ed57822f9c0cb94fa7df8d24acc9bvboxsync * Verifies a directory.
c48c4d769ded37e2496f97dddbbd36dc62f244b1vboxsync * @returns VINF_SUCCESS on success. On failure, an error code is returned if
47eb60db91f50291b3bd9b72b64d36341972a155vboxsync * fFatal is clear and if it's set the function wont return.
c48c4d769ded37e2496f97dddbbd36dc62f244b1vboxsync * @param enmDir The directory specifier.
c48c4d769ded37e2496f97dddbbd36dc62f244b1vboxsync * @param fFatal Whether validation failures should be treated as
5f9dfb422a6ed57822f9c0cb94fa7df8d24acc9bvboxsync * fatal (true) or not (false).
7eaaa8a4480370b82ef3735994f986f338fb4df2vboxsyncDECLHIDDEN(int) supR3HardenedVerifyFixedDir(SUPINSTDIR enmDir, bool fFatal)
f5ab5688c35373443d953e2a9fa8a054defdece8vboxsync * Validate the index just to be on the safe side...
f5ab5688c35373443d953e2a9fa8a054defdece8vboxsync if (enmDir <= kSupID_Invalid || enmDir >= kSupID_End)
f5ab5688c35373443d953e2a9fa8a054defdece8vboxsync return supR3HardenedError(VERR_INTERNAL_ERROR, fFatal,
5f9dfb422a6ed57822f9c0cb94fa7df8d24acc9bvboxsync * Already validated?
5f9dfb422a6ed57822f9c0cb94fa7df8d24acc9bvboxsync /* initialize the entry. */
5f9dfb422a6ed57822f9c0cb94fa7df8d24acc9bvboxsync "supR3HardenedVerifyDir: hDir=%p enmDir=%d\n",
0c587d7af645db20acefebcfc15b6f46c440ba4avboxsync * Make the path and open the directory.
f5ab5688c35373443d953e2a9fa8a054defdece8vboxsync int rc = supR3HardenedMakePath(enmDir, szPath, sizeof(szPath), fFatal);
5f9dfb422a6ed57822f9c0cb94fa7df8d24acc9bvboxsync FILE_SHARE_READ | FILE_SHARE_DELETE | FILE_SHARE_WRITE,
5f9dfb422a6ed57822f9c0cb94fa7df8d24acc9bvboxsync FILE_ATTRIBUTE_NORMAL | FILE_FLAG_BACKUP_SEMANTICS,
0c587d7af645db20acefebcfc15b6f46c440ba4avboxsync /** @todo check the type */
aca7a56d52c58d8b388343450503c22822fd6620vboxsync /* That's all on windows, for now at least... */
aca7a56d52c58d8b388343450503c22822fd6620vboxsync rc = supR3HardenedError(VERR_PATH_NOT_FOUND, fFatal,
aca7a56d52c58d8b388343450503c22822fd6620vboxsync "supR3HardenedVerifyDir: Failed to open \"%s\": err=%d\n",
aca7a56d52c58d8b388343450503c22822fd6620vboxsync#else /* UNIXY */
0c587d7af645db20acefebcfc15b6f46c440ba4avboxsync * On unixy systems we'll make sure the directory is owned by root
0c587d7af645db20acefebcfc15b6f46c440ba4avboxsync * and not writable by the group and user.
5f9dfb422a6ed57822f9c0cb94fa7df8d24acc9bvboxsync rc = supR3HardenedError(VERR_NOT_A_DIRECTORY, fFatal,
5f9dfb422a6ed57822f9c0cb94fa7df8d24acc9bvboxsync "supR3HardenedVerifyDir: \"%s\" is not a directory\n",
5f9dfb422a6ed57822f9c0cb94fa7df8d24acc9bvboxsync rc = supR3HardenedError(VERR_ACCESS_DENIED, fFatal,
5f9dfb422a6ed57822f9c0cb94fa7df8d24acc9bvboxsync "supR3HardenedVerifyDir: Cannot trust the directory \"%s\": not owned by root (st_uid=%ld)\n",
60b3bb99d58c291474ef79573ae7738ce769fdbbvboxsync rc = supR3HardenedError(VERR_ACCESS_DENIED, fFatal,
60b3bb99d58c291474ef79573ae7738ce769fdbbvboxsync "supR3HardenedVerifyDir: Cannot trust the directory \"%s\": group and/or other writable (st_mode=0%lo)\n",
5f9dfb422a6ed57822f9c0cb94fa7df8d24acc9bvboxsync rc = supR3HardenedError(VERR_ACCESS_DENIED, fFatal,
5f9dfb422a6ed57822f9c0cb94fa7df8d24acc9bvboxsync "supR3HardenedVerifyDir: Failed to fstat \"%s\": %s (%d)\n",
5f9dfb422a6ed57822f9c0cb94fa7df8d24acc9bvboxsync rc = supR3HardenedError(VERR_PATH_NOT_FOUND, fFatal,
5f9dfb422a6ed57822f9c0cb94fa7df8d24acc9bvboxsync "supR3HardenedVerifyDir: Failed to open \"%s\": %s (%d)\n",
5f9dfb422a6ed57822f9c0cb94fa7df8d24acc9bvboxsync#endif /* UNIXY */
5f9dfb422a6ed57822f9c0cb94fa7df8d24acc9bvboxsync * Verifies a file entry.
5f9dfb422a6ed57822f9c0cb94fa7df8d24acc9bvboxsync * @returns VINF_SUCCESS on success. On failure, an error code is returned if
5f9dfb422a6ed57822f9c0cb94fa7df8d24acc9bvboxsync * fFatal is clear and if it's set the function wont return.
5f9dfb422a6ed57822f9c0cb94fa7df8d24acc9bvboxsync * @param iFile The file table index of the file to be verified.
5f9dfb422a6ed57822f9c0cb94fa7df8d24acc9bvboxsync * @param fFatal Whether validation failures should be treated as
5f9dfb422a6ed57822f9c0cb94fa7df8d24acc9bvboxsync * fatal (true) or not (false).
5f9dfb422a6ed57822f9c0cb94fa7df8d24acc9bvboxsync * @param fLeaveFileOpen Whether the file should be left open.
5f9dfb422a6ed57822f9c0cb94fa7df8d24acc9bvboxsyncstatic int supR3HardenedVerifyFileInternal(int iFile, bool fFatal, bool fLeaveFileOpen)
5f9dfb422a6ed57822f9c0cb94fa7df8d24acc9bvboxsync PSUPVERIFIEDFILE pVerified = &g_aSupVerifiedFiles[iFile];
5f9dfb422a6ed57822f9c0cb94fa7df8d24acc9bvboxsync * Already done?
5f9dfb422a6ed57822f9c0cb94fa7df8d24acc9bvboxsync /* initialize the entry. */
5f9dfb422a6ed57822f9c0cb94fa7df8d24acc9bvboxsync "supR3HardenedVerifyFileInternal: hFile=%p (%s)\n",
#if defined(RT_OS_WINDOWS)
NULL,
NULL);
if (fLeaveFileOpen)
if (fd >= 0)
if (fLeaveFileOpen)
"supR3HardenedVerifyFileInternal: Cannot trust the file \"%s\": group and/or other writable (st_mode=0%lo)\n",
return rc;
return rc;
#if defined(RT_OS_WINDOWS)
return VINF_SUCCESS;
return rc;
return VERR_NOT_FOUND;
bool fExe = false;
bool fDll = false;
if (fDll)
fDll = true;
if (fExe)
fExe = true;
int rc2 = supR3HardenedPathExecDir(szFilename, sizeof(szFilename) - cchProgName - sizeof(SUPLIB_EXE_SUFF));
else if (!fExe)
else if (!fDll)
return rc;
if (pszProgName)
return rc;
if (pErrInfo)
return rc;
const char *pszMsg2)
typedef struct SUPR3HARDENEDPATHINFO
bool fDirSlash;
static int supR3HardenedVerifyPathSanity(const char *pszPath, PRTERRINFO pErrInfo, PSUPR3HARDENEDPATHINFO pInfo)
return supR3HardenedSetError3(VERR_SUPLIB_PATH_NOT_ABSOLUTE, pErrInfo, "The path is not absolute: '", pszPath, "'");
return supR3HardenedSetError3(VERR_SUPLIB_PATH_NOT_ABSOLUTE, pErrInfo, "The path is not absolute: '", pszPath, "'");
return supR3HardenedSetError3(VERR_SUPLIB_PATH_IS_ROOT, pErrInfo, "The path is root: '", pszPath, "'");
return supR3HardenedSetError3(VERR_SUPLIB_PATH_TOO_SHORT, pErrInfo, "The path is too short: '", pszPath, "'");
while (pszSrc[0])
while (pszSrc[0])
pszSrc++;
if (*pszSrc)
return VINF_SUCCESS;
typedef struct SUPR3HARDENEDFSOBJSTATE
#ifdef RT_OS_WINDOWS
char chTodo;
static int supR3HardenedQueryFsObjectByPath(char const *pszPath, PSUPR3HARDENEDFSOBJSTATE pFsObjState, PRTERRINFO pErrInfo)
#if defined(RT_OS_WINDOWS)
return VINF_SUCCESS;
return VINF_SUCCESS;
static int supR3HardenedQueryFsObjectByHandle(RTHCUINTPTR hNative, PSUPR3HARDENEDFSOBJSTATE pFsObjState,
#if defined(RT_OS_WINDOWS)
return VINF_SUCCESS;
return VINF_SUCCESS;
* @param pFsObjState1 File system object information/state by path.
* @param pFsObjState2 File system object information/state by handle.
static int supR3HardenedIsSameFsObject(PCSUPR3HARDENEDFSOBJSTATE pFsObjState1, PCSUPR3HARDENEDFSOBJSTATE pFsObjState2,
#if defined(RT_OS_WINDOWS)
return VINF_SUCCESS;
return VINF_SUCCESS;
return VINF_SUCCESS;
* @param pFsObjState The file system object information/state to be
static int supR3HardenedVerifyFsObject(PCSUPR3HARDENEDFSOBJSTATE pFsObjState, bool fDir, bool fRelaxed,
#if defined(RT_OS_WINDOWS)
return VINF_SUCCESS;
return VINF_SUCCESS;
return supR3HardenedSetError3(VERR_SUPLIB_OWNER_NOT_ROOT, pErrInfo, "The owner is not root: '", pszPath, "'");
#ifdef RT_OS_DARWIN
if (!fRelaxed || pFsObjState->Stat.st_gid != 80 /*admin*/) /** @todo dynamically resolve the admin group? */
return VINF_SUCCESS;
* @param pFsObjState The information/state returned by a previous
static int supR3HardenedVerifySameFsObject(RTHCUINTPTR hNative, PCSUPR3HARDENEDFSOBJSTATE pFsObjState,
return rc;
static int supR3HardenedVerifyDirRecursive(char *pszDirPath, size_t cchDirPath, PSUPR3HARDENEDFSOBJSTATE pFsObjState,
#if defined(RT_OS_WINDOWS)
return VINF_SUCCESS;
return VINF_SUCCESS;
if (!pDir)
return VINF_SUCCESS;
return rc;
if (iErr)
if (!pEntry)
rc = supR3HardenedVerifyFsObject(pFsObjState, S_ISDIR(pFsObjState->Stat.st_mode), false /*fRelaxed*/,
if ( fRecursive
return VINF_SUCCESS;
DECLHIDDEN(int) supR3HardenedVerifyDir(const char *pszDirPath, bool fRecursive, bool fCheckFiles, PRTERRINFO pErrInfo)
return rc;
return rc;
Info.szPath[Info.aoffComponents[iComponent + 1] - 1] = iComponent + 1 != cComponents ? RTPATH_SLASH : '\0';
return VINF_SUCCESS;
DECLHIDDEN(int) supR3HardenedVerifyFile(const char *pszFilename, RTHCUINTPTR hNativeFile, PRTERRINFO pErrInfo)
return rc;
return rc;
return VINF_SUCCESS;
return VERR_VERSION_MISMATCH;
return VERR_VERSION_MISMATCH;
return VERR_WRONG_ORDER;
return VINF_SUCCESS;