at v192 9.0 kB view raw
1diff --git a/include/iprt/mangling.h b/include/iprt/mangling.h 2index 70c596a..78972ed 100644 3--- a/include/iprt/mangling.h 4+++ b/include/iprt/mangling.h 5@@ -1068,6 +1068,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@@ -1105,6 +1106,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 7e42754..b4de4c8 100644 23--- a/include/iprt/path.h 24+++ b/include/iprt/path.h 25@@ -1049,6 +1049,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 2760306..0ce6c92 100644 43--- a/include/iprt/process.h 44+++ b/include/iprt/process.h 45@@ -313,6 +313,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 c39d2f7..896b352 100644 64--- a/src/VBox/HostDrivers/Support/SUPR3HardenedVerify.cpp 65+++ b/src/VBox/HostDrivers/Support/SUPR3HardenedVerify.cpp 66@@ -1415,18 +1415,19 @@ static int supR3HardenedVerifyFsObject(PCSUPR3HARDENEDFSOBJSTATE pFsObjState, bo 67 NOREF(fRelaxed); 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"); 78 } 79 80 /* 81- * World must not have write access. There is no relaxing this rule. 82+ * World must not have write access. 83+ * There is no relaxing this rule, except when it comes to the Nix store. 84 */ 85- if (pFsObjState->Stat.st_mode & S_IWOTH) 86+ if (pFsObjState->Stat.st_mode & S_IWOTH && suplibHardenedStrCmp(pszPath, "/nix/store")) 87 return supR3HardenedSetError3(VERR_SUPLIB_WORLD_WRITABLE, pErrInfo, 88 "World writable: '", pszPath, "'"); 89 90diff --git a/src/VBox/Main/src-server/MachineImpl.cpp b/src/VBox/Main/src-server/MachineImpl.cpp 91index 95dc9a7..39170bc 100644 92--- a/src/VBox/Main/src-server/MachineImpl.cpp 93+++ b/src/VBox/Main/src-server/MachineImpl.cpp 94@@ -7326,7 +7326,7 @@ HRESULT Machine::i_launchVMProcess(IInternalSessionControl *aControl, 95 96 /* get the path to the executable */ 97 char szPath[RTPATH_MAX]; 98- RTPathAppPrivateArch(szPath, sizeof(szPath) - 1); 99+ RTStrCopy(szPath, sizeof(szPath) - 1, "/var/setuid-wrappers"); 100 size_t cchBufLeft = strlen(szPath); 101 szPath[cchBufLeft++] = RTPATH_DELIMITER; 102 szPath[cchBufLeft] = 0; 103diff --git a/src/VBox/Main/src-server/NetworkServiceRunner.cpp b/src/VBox/Main/src-server/NetworkServiceRunner.cpp 104index e9e1ba62..4d1c1e1 100644 105--- a/src/VBox/Main/src-server/NetworkServiceRunner.cpp 106+++ b/src/VBox/Main/src-server/NetworkServiceRunner.cpp 107@@ -79,7 +79,7 @@ int NetworkServiceRunner::start() 108 109 /* get the path to the executable */ 110 char exePathBuf[RTPATH_MAX]; 111- const char *exePath = RTProcGetExecutablePath(exePathBuf, RTPATH_MAX); 112+ const char *exePath = RTProcGetSuidPath(exePathBuf, RTPATH_MAX); 113 char *substrSl = strrchr(exePathBuf, '/'); 114 char *substrBs = strrchr(exePathBuf, '\\'); 115 char *suffix = substrSl ? substrSl : substrBs; 116diff --git a/src/VBox/Main/src-server/generic/NetIf-generic.cpp b/src/VBox/Main/src-server/generic/NetIf-generic.cpp 117index 8559d2a..2177f27 100644 118--- a/src/VBox/Main/src-server/generic/NetIf-generic.cpp 119+++ b/src/VBox/Main/src-server/generic/NetIf-generic.cpp 120@@ -47,7 +47,7 @@ static int NetIfAdpCtl(const char * pcszIfName, const char *pszAddr, const char 121 const char *args[] = { NULL, pcszIfName, pszAddr, pszOption, pszMask, NULL }; 122 123 char szAdpCtl[RTPATH_MAX]; 124- int rc = RTPathExecDir(szAdpCtl, sizeof(szAdpCtl) - sizeof("/" VBOXNETADPCTL_NAME)); 125+ int rc = RTPathSuidDir(szAdpCtl, sizeof(szAdpCtl) - sizeof("/" VBOXNETADPCTL_NAME)); 126 if (RT_FAILURE(rc)) 127 { 128 LogRel(("NetIfAdpCtl: failed to get program path, rc=%Rrc.\n", rc)); 129@@ -90,7 +90,7 @@ static int NetIfAdpCtl(HostNetworkInterface * pIf, const char *pszAddr, const ch 130 int NetIfAdpCtlOut(const char * pcszName, const char * pcszCmd, char *pszBuffer, size_t cBufSize) 131 { 132 char szAdpCtl[RTPATH_MAX]; 133- int rc = RTPathExecDir(szAdpCtl, sizeof(szAdpCtl) - sizeof("/" VBOXNETADPCTL_NAME " ") - strlen(pcszCmd)); 134+ int rc = RTPathSuidDir(szAdpCtl, sizeof(szAdpCtl) - sizeof("/" VBOXNETADPCTL_NAME " ") - strlen(pcszCmd)); 135 if (RT_FAILURE(rc)) 136 { 137 LogRel(("NetIfAdpCtlOut: Failed to get program path, rc=%Rrc\n", rc)); 138@@ -202,7 +202,7 @@ int NetIfCreateHostOnlyNetworkInterface(VirtualBox *pVirtualBox, 139 progress.queryInterfaceTo(aProgress); 140 141 char szAdpCtl[RTPATH_MAX]; 142- int rc = RTPathExecDir(szAdpCtl, sizeof(szAdpCtl) - sizeof("/" VBOXNETADPCTL_NAME " add")); 143+ int rc = RTPathSuidDir(szAdpCtl, sizeof(szAdpCtl) - sizeof("/" VBOXNETADPCTL_NAME " add")); 144 if (RT_FAILURE(rc)) 145 { 146 progress->i_notifyComplete(E_FAIL, 147diff --git a/src/VBox/Runtime/r3/path.cpp b/src/VBox/Runtime/r3/path.cpp 148index be2ad8f..7ddf105 100644 149--- a/src/VBox/Runtime/r3/path.cpp 150+++ b/src/VBox/Runtime/r3/path.cpp 151@@ -81,6 +81,12 @@ RTDECL(int) RTPathExecDir(char *pszPath, size_t cchPath) 152 } 153 154 155+RTDECL(int) RTPathSuidDir(char *pszPath, size_t cchPath) 156+{ 157+ return RTStrCopy(pszPath, cchPath, "/var/setuid-wrappers"); 158+} 159+ 160+ 161 RTDECL(int) RTPathAppPrivateNoArch(char *pszPath, size_t cchPath) 162 { 163 #if !defined(RT_OS_WINDOWS) && defined(RTPATH_APP_PRIVATE) 164diff --git a/src/VBox/Runtime/r3/process.cpp b/src/VBox/Runtime/r3/process.cpp 165index 7bde6af..2656cae 100644 166--- a/src/VBox/Runtime/r3/process.cpp 167+++ b/src/VBox/Runtime/r3/process.cpp 168@@ -111,6 +111,26 @@ RTR3DECL(char *) RTProcGetExecutablePath(char *pszExecPath, size_t cbExecPath) 169 return NULL; 170 } 171 172+/* 173+ * Note the / at the end! This is important, because the functions using this 174+ * will cut off everything after the rightmost / as this function is analogous 175+ * to RTProcGetExecutablePath(). 176+ */ 177+#define SUIDDIR "/var/setuid-wrappers/" 178+ 179+RTR3DECL(char *) RTProcGetSuidPath(char *pszExecPath, size_t cbExecPath) 180+{ 181+ if (cbExecPath >= sizeof(SUIDDIR)) 182+ { 183+ memcpy(pszExecPath, SUIDDIR, sizeof(SUIDDIR)); 184+ pszExecPath[sizeof(SUIDDIR)] = '\0'; 185+ return pszExecPath; 186+ } 187+ 188+ AssertMsgFailed(("Buffer too small (%zu <= %zu)\n", cbExecPath, sizeof(SUIDDIR))); 189+ return NULL; 190+} 191+ 192 193 RTR3DECL(const char *) RTProcShortName(void) 194 {