1diff --git a/include/iprt/mangling.h b/include/iprt/mangling.h 2index c1daa8f..8618371 100644 3--- a/include/iprt/mangling.h 4+++ b/include/iprt/mangling.h 5@@ -1440,6 +1440,7 @@ 6 # define RTPathStripSuffix RT_MANGLER(RTPathStripSuffix) 7 # define RTPathStripFilename RT_MANGLER(RTPathStripFilename) 8 # define RTPathStripTrailingSlash RT_MANGLER(RTPathStripTrailingSlash) 9+# define RTPathSuidDir RT_MANGLER(RTPathSuidDir) 10 # define RTPathTemp RT_MANGLER(RTPathTemp) 11 # define RTPathTraverseList RT_MANGLER(RTPathTraverseList) 12 # define RTPathUnlink RT_MANGLER(RTPathUnlink) 13@@ -1478,6 +1479,7 @@ 14 # define RTProcGetAffinityMask RT_MANGLER(RTProcGetAffinityMask) 15 # define RTProcGetExecutablePath RT_MANGLER(RTProcGetExecutablePath) 16 # define RTProcGetPriority RT_MANGLER(RTProcGetPriority) 17+# define RTProcGetSuidPath RT_MANGLER(RTProcGetSuidPath) 18 # define RTProcIsRunningByName RT_MANGLER(RTProcIsRunningByName) 19 # define RTProcQueryParent RT_MANGLER(RTProcQueryParent) 20 # define RTProcQueryUsername RT_MANGLER(RTProcQueryUsername) 21diff --git a/include/iprt/path.h b/include/iprt/path.h 22index 8bd42bc..2c23d3e 100644 23--- a/include/iprt/path.h 24+++ b/include/iprt/path.h 25@@ -1064,6 +1064,15 @@ RTDECL(int) RTPathCalcRelative(char *pszPathDst, size_t cbPathDst, 26 RTDECL(int) RTPathExecDir(char *pszPath, size_t cchPath); 27 28 /** 29+ * Gets the path to the NixOS setuid wrappers directory. 30+ * 31+ * @returns iprt status code. 32+ * @param pszPath Buffer where to store the path. 33+ * @param cchPath Buffer size in bytes. 34+ */ 35+RTDECL(int) RTPathSuidDir(char *pszPath, size_t cchPath); 36+ 37+/** 38 * Gets the user home directory. 39 * 40 * @returns iprt status code. 41diff --git a/include/iprt/process.h b/include/iprt/process.h 42index 043653e..1070280 100644 43--- a/include/iprt/process.h 44+++ b/include/iprt/process.h 45@@ -327,6 +327,16 @@ RTR3DECL(const char *) RTProcShortName(void); 46 RTR3DECL(char *) RTProcGetExecutablePath(char *pszExecPath, size_t cbExecPath); 47 48 /** 49+ * Gets the path to the NixOS setuid wrappers directory. 50+ * 51+ * @returns pszExecPath on success. NULL on buffer overflow or other errors. 52+ * 53+ * @param pszExecPath Where to store the path. 54+ * @param cbExecPath The size of the buffer. 55+ */ 56+RTR3DECL(char *) RTProcGetSuidPath(char *pszExecPath, size_t cbExecPath); 57+ 58+/** 59 * Daemonize the current process, making it a background process. 60 * 61 * The way this work is that it will spawn a detached / backgrounded / 62diff --git a/src/VBox/HostDrivers/Support/SUPR3HardenedVerify.cpp b/src/VBox/HostDrivers/Support/SUPR3HardenedVerify.cpp 63index ce0f288..6193108 100644 64--- a/src/VBox/HostDrivers/Support/SUPR3HardenedVerify.cpp 65+++ b/src/VBox/HostDrivers/Support/SUPR3HardenedVerify.cpp 66@@ -1502,9 +1502,9 @@ static int supR3HardenedVerifyFsObject(PCSUPR3HARDENEDFSOBJSTATE pFsObjState, bo 67 bool fBad = !fRelaxed || pFsObjState->Stat.st_gid != 2 /*bin*/ || suplibHardenedStrCmp(pszPath, "/usr/lib/iconv"); 68 # else 69 NOREF(fRelaxed); 70- bool fBad = true; 71+ bool fBad = !(fDir && pFsObjState->Stat.st_mode & S_ISVTX && !suplibHardenedStrCmp(pszPath, "/nix/store")); 72 # endif 73- if (fBad) 74+ if (fBad && suplibHardenedStrCmp(pszPath, "/nix/store")) 75 return supR3HardenedSetError3(VERR_SUPLIB_WRITE_NON_SYS_GROUP, pErrInfo, 76 "An unknown (and thus untrusted) group has write access to '", pszPath, 77 "' and we therefore cannot trust the directory content or that of any subdirectory"); 78diff --git a/src/VBox/Main/src-server/MachineImpl.cpp b/src/VBox/Main/src-server/MachineImpl.cpp 79index 320c569..9bfe41f 100644 80--- a/src/VBox/Main/src-server/MachineImpl.cpp 81+++ b/src/VBox/Main/src-server/MachineImpl.cpp 82@@ -7543,7 +7543,7 @@ HRESULT Machine::i_launchVMProcess(IInternalSessionControl *aControl, 83 84 /* get the path to the executable */ 85 char szPath[RTPATH_MAX]; 86- RTPathAppPrivateArch(szPath, sizeof(szPath) - 1); 87+ RTStrCopy(szPath, sizeof(szPath) - 1, "/run/wrappers/bin"); 88 size_t cchBufLeft = strlen(szPath); 89 szPath[cchBufLeft++] = RTPATH_DELIMITER; 90 szPath[cchBufLeft] = 0; 91diff --git a/src/VBox/Main/src-server/NetworkServiceRunner.cpp b/src/VBox/Main/src-server/NetworkServiceRunner.cpp 92index 1e38d99..5e43dda 100644 93--- a/src/VBox/Main/src-server/NetworkServiceRunner.cpp 94+++ b/src/VBox/Main/src-server/NetworkServiceRunner.cpp 95@@ -85,7 +85,7 @@ int NetworkServiceRunner::start(bool aKillProcOnStop) 96 97 /* get the path to the executable */ 98 char exePathBuf[RTPATH_MAX]; 99- const char *exePath = RTProcGetExecutablePath(exePathBuf, RTPATH_MAX); 100+ const char *exePath = RTProcGetSuidPath(exePathBuf, RTPATH_MAX); 101 char *substrSl = strrchr(exePathBuf, '/'); 102 char *substrBs = strrchr(exePathBuf, '\\'); 103 char *suffix = substrSl ? substrSl : substrBs; 104diff --git a/src/VBox/Main/src-server/generic/NetIf-generic.cpp b/src/VBox/Main/src-server/generic/NetIf-generic.cpp 105index 98dc91a..43a819f 100644 106--- a/src/VBox/Main/src-server/generic/NetIf-generic.cpp 107+++ b/src/VBox/Main/src-server/generic/NetIf-generic.cpp 108@@ -47,7 +47,7 @@ static int NetIfAdpCtl(const char * pcszIfName, const char *pszAddr, const char 109 const char *args[] = { NULL, pcszIfName, pszAddr, pszOption, pszMask, NULL }; 110 111 char szAdpCtl[RTPATH_MAX]; 112- int rc = RTPathExecDir(szAdpCtl, sizeof(szAdpCtl) - sizeof("/" VBOXNETADPCTL_NAME)); 113+ int rc = RTPathSuidDir(szAdpCtl, sizeof(szAdpCtl) - sizeof("/" VBOXNETADPCTL_NAME)); 114 if (RT_FAILURE(rc)) 115 { 116 LogRel(("NetIfAdpCtl: failed to get program path, rc=%Rrc.\n", rc)); 117@@ -89,7 +89,7 @@ static int NetIfAdpCtl(HostNetworkInterface * pIf, const char *pszAddr, const ch 118 int NetIfAdpCtlOut(const char * pcszName, const char * pcszCmd, char *pszBuffer, size_t cBufSize) 119 { 120 char szAdpCtl[RTPATH_MAX]; 121- int rc = RTPathExecDir(szAdpCtl, sizeof(szAdpCtl) - sizeof("/" VBOXNETADPCTL_NAME " ") - strlen(pcszCmd)); 122+ int rc = RTPathSuidDir(szAdpCtl, sizeof(szAdpCtl) - sizeof("/" VBOXNETADPCTL_NAME " ") - strlen(pcszCmd)); 123 if (RT_FAILURE(rc)) 124 { 125 LogRel(("NetIfAdpCtlOut: Failed to get program path, rc=%Rrc\n", rc)); 126@@ -201,7 +201,7 @@ int NetIfCreateHostOnlyNetworkInterface(VirtualBox *pVirtualBox, 127 progress.queryInterfaceTo(aProgress); 128 129 char szAdpCtl[RTPATH_MAX]; 130- int rc = RTPathExecDir(szAdpCtl, sizeof(szAdpCtl) - sizeof("/" VBOXNETADPCTL_NAME " add")); 131+ int rc = RTPathSuidDir(szAdpCtl, sizeof(szAdpCtl) - sizeof("/" VBOXNETADPCTL_NAME " add")); 132 if (RT_FAILURE(rc)) 133 { 134 progress->i_notifyComplete(E_FAIL, 135diff --git a/src/VBox/Runtime/r3/path.cpp b/src/VBox/Runtime/r3/path.cpp 136index 944848e..744a261 100644 137--- a/src/VBox/Runtime/r3/path.cpp 138+++ b/src/VBox/Runtime/r3/path.cpp 139@@ -81,6 +81,12 @@ RTDECL(int) RTPathExecDir(char *pszPath, size_t cchPath) 140 } 141 142 143+RTDECL(int) RTPathSuidDir(char *pszPath, size_t cchPath) 144+{ 145+ return RTStrCopy(pszPath, cchPath, "/run/wrappers/bin"); 146+} 147+ 148+ 149 RTDECL(int) RTPathAppPrivateNoArch(char *pszPath, size_t cchPath) 150 { 151 #if !defined(RT_OS_WINDOWS) && defined(RTPATH_APP_PRIVATE) 152diff --git a/src/VBox/Runtime/r3/process.cpp b/src/VBox/Runtime/r3/process.cpp 153index 2aab645..9795f21 100644 154--- a/src/VBox/Runtime/r3/process.cpp 155+++ b/src/VBox/Runtime/r3/process.cpp 156@@ -111,6 +111,26 @@ RTR3DECL(char *) RTProcGetExecutablePath(char *pszExecPath, size_t cbExecPath) 157 return NULL; 158 } 159 160+/* 161+ * Note the / at the end! This is important, because the functions using this 162+ * will cut off everything after the rightmost / as this function is analogous 163+ * to RTProcGetExecutablePath(). 164+ */ 165+#define SUIDDIR "/run/wrappers/bin/" 166+ 167+RTR3DECL(char *) RTProcGetSuidPath(char *pszExecPath, size_t cbExecPath) 168+{ 169+ if (cbExecPath >= sizeof(SUIDDIR)) 170+ { 171+ memcpy(pszExecPath, SUIDDIR, sizeof(SUIDDIR)); 172+ pszExecPath[sizeof(SUIDDIR)] = '\0'; 173+ return pszExecPath; 174+ } 175+ 176+ AssertMsgFailed(("Buffer too small (%zu <= %zu)\n", cbExecPath, sizeof(SUIDDIR))); 177+ return NULL; 178+} 179+ 180 181 RTR3DECL(const char *) RTProcShortName(void) 182 {