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 {