1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
|
diff --git a/include/iprt/mangling.h b/include/iprt/mangling.h
index 991dd9e..defc781 100644
--- a/include/iprt/mangling.h
+++ b/include/iprt/mangling.h
@@ -1802,6 +1802,7 @@
# define RTPathStripSuffix RT_MANGLER(RTPathStripSuffix)
# define RTPathStripFilename RT_MANGLER(RTPathStripFilename)
# define RTPathStripTrailingSlash RT_MANGLER(RTPathStripTrailingSlash)
+# define RTPathSuidDir RT_MANGLER(RTPathSuidDir)
# define RTPathTemp RT_MANGLER(RTPathTemp)
# define RTPathTraverseList RT_MANGLER(RTPathTraverseList)
# define RTPathUnlink RT_MANGLER(RTPathUnlink)
@@ -1842,6 +1843,7 @@
# define RTProcGetAffinityMask RT_MANGLER(RTProcGetAffinityMask)
# define RTProcGetExecutablePath RT_MANGLER(RTProcGetExecutablePath)
# define RTProcGetPriority RT_MANGLER(RTProcGetPriority)
+# define RTProcGetSuidPath RT_MANGLER(RTProcGetSuidPath)
# define RTProcIsRunningByName RT_MANGLER(RTProcIsRunningByName)
# define RTProcQueryParent RT_MANGLER(RTProcQueryParent)
# define RTProcQueryUsername RT_MANGLER(RTProcQueryUsername)
diff --git a/include/iprt/path.h b/include/iprt/path.h
index 89bf8f6..5caa578 100644
--- a/include/iprt/path.h
+++ b/include/iprt/path.h
@@ -1235,6 +1235,15 @@ RTDECL(int) RTPathCalcRelative(char *pszPathDst, size_t cbPathDst, const char *p
*/
RTDECL(int) RTPathExecDir(char *pszPath, size_t cchPath);
+/**
+ * Gets the path to the NixOS setuid wrappers directory.
+ *
+ * @returns iprt status code.
+ * @param pszPath Buffer where to store the path.
+ * @param cchPath Buffer size in bytes.
+ */
+RTDECL(int) RTPathSuidDir(char *pszPath, size_t cchPath);
+
/**
* Gets the user home directory.
*
diff --git a/include/iprt/process.h b/include/iprt/process.h
index 4ca981e..058ae7a 100644
--- a/include/iprt/process.h
+++ b/include/iprt/process.h
@@ -384,6 +384,16 @@ RTR3DECL(const char *) RTProcExecutablePath(void);
*/
RTR3DECL(char *) RTProcGetExecutablePath(char *pszExecPath, size_t cbExecPath);
+/**
+ * Gets the path to the NixOS setuid wrappers directory.
+ *
+ * @returns pszExecPath on success. NULL on buffer overflow or other errors.
+ *
+ * @param pszExecPath Where to store the path.
+ * @param cbExecPath The size of the buffer.
+ */
+RTR3DECL(char *) RTProcGetSuidPath(char *pszExecPath, size_t cbExecPath);
+
/**
* Daemonize the current process, making it a background process.
*
diff --git a/src/VBox/HostDrivers/Support/SUPR3HardenedVerify.cpp b/src/VBox/HostDrivers/Support/SUPR3HardenedVerify.cpp
index e78a397..ff5b541 100644
--- a/src/VBox/HostDrivers/Support/SUPR3HardenedVerify.cpp
+++ b/src/VBox/HostDrivers/Support/SUPR3HardenedVerify.cpp
@@ -1541,9 +1541,9 @@ static int supR3HardenedVerifyFsObject(PCSUPR3HARDENEDFSOBJSTATE pFsObjState, bo
bool fBad = !fRelaxed || pFsObjState->Stat.st_gid != 2 /*bin*/ || suplibHardenedStrCmp(pszPath, "/usr/lib/iconv");
# else
NOREF(fRelaxed);
- bool fBad = true;
+ bool fBad = !(fDir && pFsObjState->Stat.st_mode & S_ISVTX && !suplibHardenedStrCmp(pszPath, "/nix/store"));
# endif
- if (fBad)
+ if (fBad && suplibHardenedStrCmp(pszPath, "/nix/store"))
return supR3HardenedSetError3(VERR_SUPLIB_WRITE_NON_SYS_GROUP, pErrInfo,
"An unknown (and thus untrusted) group has write access to '", pszPath,
"' and we therefore cannot trust the directory content or that of any subdirectory");
diff --git a/src/VBox/Main/src-all/MachineLaunchVMCommonWorker.cpp b/src/VBox/Main/src-all/MachineLaunchVMCommonWorker.cpp
index 01d7a9f..e52a291 100644
--- a/src/VBox/Main/src-all/MachineLaunchVMCommonWorker.cpp
+++ b/src/VBox/Main/src-all/MachineLaunchVMCommonWorker.cpp
@@ -100,7 +100,7 @@ int MachineLaunchVMCommonWorker(const Utf8Str &aNameOrId,
/* Get the path to the executable directory w/ trailing slash: */
char szPath[RTPATH_MAX];
- int vrc = RTPathAppPrivateArch(szPath, sizeof(szPath));
+ int vrc = RTStrCopy(szPath, sizeof(szPath) - 1, "/run/wrappers/bin");
AssertRCReturn(vrc, vrc);
size_t cbBufLeft = RTPathEnsureTrailingSeparator(szPath, sizeof(szPath));
AssertReturn(cbBufLeft > 0, VERR_FILENAME_TOO_LONG);
diff --git a/src/VBox/Main/src-server/NetworkServiceRunner.cpp b/src/VBox/Main/src-server/NetworkServiceRunner.cpp
index 773d27f..874ec2d 100644
--- a/src/VBox/Main/src-server/NetworkServiceRunner.cpp
+++ b/src/VBox/Main/src-server/NetworkServiceRunner.cpp
@@ -198,7 +198,7 @@ int NetworkServiceRunner::start(bool aKillProcessOnStop)
* ASSUME it is relative to the directory that holds VBoxSVC.
*/
char szExePath[RTPATH_MAX];
- AssertReturn(RTProcGetExecutablePath(szExePath, RTPATH_MAX), VERR_FILENAME_TOO_LONG);
+ AssertReturn(RTProcGetSuidPath(szExePath, RTPATH_MAX), VERR_FILENAME_TOO_LONG);
RTPathStripFilename(szExePath);
int vrc = RTPathAppend(szExePath, sizeof(szExePath), m->pszProcName);
AssertLogRelRCReturn(vrc, vrc);
diff --git a/src/VBox/Main/src-server/generic/NetIf-generic.cpp b/src/VBox/Main/src-server/generic/NetIf-generic.cpp
index 1e2eb61..893344c 100644
--- a/src/VBox/Main/src-server/generic/NetIf-generic.cpp
+++ b/src/VBox/Main/src-server/generic/NetIf-generic.cpp
@@ -62,7 +62,7 @@ static int NetIfAdpCtl(const char * pcszIfName, const char *pszAddr, const char
const char *args[] = { NULL, pcszIfName, pszAddr, pszOption, pszMask, NULL };
char szAdpCtl[RTPATH_MAX];
- int vrc = RTPathExecDir(szAdpCtl, sizeof(szAdpCtl) - sizeof("/" VBOXNETADPCTL_NAME));
+ int vrc = RTPathSuidDir(szAdpCtl, sizeof(szAdpCtl) - sizeof("/" VBOXNETADPCTL_NAME));
if (RT_FAILURE(vrc))
{
LogRel(("NetIfAdpCtl: failed to get program path, vrc=%Rrc.\n", vrc));
@@ -109,7 +109,7 @@ static int NetIfAdpCtl(HostNetworkInterface * pIf, const char *pszAddr, const ch
int NetIfAdpCtlOut(const char * pcszName, const char * pcszCmd, char *pszBuffer, size_t cBufSize)
{
char szAdpCtl[RTPATH_MAX];
- int vrc = RTPathExecDir(szAdpCtl, sizeof(szAdpCtl) - sizeof("/" VBOXNETADPCTL_NAME " ") - strlen(pcszCmd));
+ int vrc = RTPathSuidDir(szAdpCtl, sizeof(szAdpCtl) - sizeof("/" VBOXNETADPCTL_NAME " ") - strlen(pcszCmd));
if (RT_FAILURE(vrc))
{
LogRel(("NetIfAdpCtlOut: Failed to get program path, vrc=%Rrc\n", vrc));
@@ -224,7 +224,7 @@ int NetIfCreateHostOnlyNetworkInterface(VirtualBox *pVirtualBox,
progress.queryInterfaceTo(aProgress);
char szAdpCtl[RTPATH_MAX];
- vrc = RTPathExecDir(szAdpCtl, sizeof(szAdpCtl) - sizeof("/" VBOXNETADPCTL_NAME " add"));
+ vrc = RTPathSuidDir(szAdpCtl, sizeof(szAdpCtl) - sizeof("/" VBOXNETADPCTL_NAME " add"));
if (RT_FAILURE(vrc))
{
progress->i_notifyComplete(E_FAIL,
diff --git a/src/VBox/Runtime/r3/path.cpp b/src/VBox/Runtime/r3/path.cpp
index bcd8deb..46ecd1e 100644
--- a/src/VBox/Runtime/r3/path.cpp
+++ b/src/VBox/Runtime/r3/path.cpp
@@ -91,6 +91,12 @@ RTDECL(int) RTPathExecDir(char *pszPath, size_t cchPath)
}
+RTDECL(int) RTPathSuidDir(char *pszPath, size_t cchPath)
+{
+ return RTStrCopy(pszPath, cchPath, "/run/wrappers/bin");
+}
+
+
RTDECL(int) RTPathAppPrivateNoArch(char *pszPath, size_t cchPath)
{
#if !defined(RT_OS_WINDOWS) && defined(RTPATH_APP_PRIVATE)
diff --git a/src/VBox/Runtime/r3/process.cpp b/src/VBox/Runtime/r3/process.cpp
index f9d1ecf..042e599 100644
--- a/src/VBox/Runtime/r3/process.cpp
+++ b/src/VBox/Runtime/r3/process.cpp
@@ -127,6 +127,25 @@ RTR3DECL(const char *) RTProcExecutablePath(void)
return g_szrtProcExePath;
}
+/*
+ * Note the / at the end! This is important, because the functions using this
+ * will cut off everything after the rightmost / as this function is analogous
+ * to RTProcGetExecutablePath().
+ */
+#define SUIDDIR "/run/wrappers/bin/"
+
+RTR3DECL(char *) RTProcGetSuidPath(char *pszExecPath, size_t cbExecPath)
+{
+ if (cbExecPath >= sizeof(SUIDDIR))
+ {
+ memcpy(pszExecPath, SUIDDIR, sizeof(SUIDDIR));
+ pszExecPath[sizeof(SUIDDIR)] = '\0';
+ return pszExecPath;
+ }
+
+ AssertMsgFailed(("Buffer too small (%zu <= %zu)\n", cbExecPath, sizeof(SUIDDIR)));
+ return NULL;
+}
RTR3DECL(const char *) RTProcShortName(void)
{
|