summary refs log tree commit diff
path: root/pkgs/applications/virtualization/virtualbox/hardened.patch
blob: eb53e0d1421e6bd2f8440871534013d093cb0e24 (plain) (blame)
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)
 {