aboutsummaryrefslogtreecommitdiff
path: root/pkgs/applications/virtualization/virtualbox/hardened.patch
blob: 398100f3f3983aa97c0c3a7d9be5ee0823633374 (plain)
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
182
diff --git a/include/iprt/mangling.h b/include/iprt/mangling.h
index c1daa8f..8618371 100644
--- a/include/iprt/mangling.h
+++ b/include/iprt/mangling.h
@@ -1440,6 +1440,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)
@@ -1478,6 +1479,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 8bd42bc..2c23d3e 100644
--- a/include/iprt/path.h
+++ b/include/iprt/path.h
@@ -1064,6 +1064,15 @@ RTDECL(int) RTPathCalcRelative(char *pszPathDst, size_t cbPathDst,
 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.
  *
  * @returns iprt status code.
diff --git a/include/iprt/process.h b/include/iprt/process.h
index 043653e..1070280 100644
--- a/include/iprt/process.h
+++ b/include/iprt/process.h
@@ -327,6 +327,16 @@ RTR3DECL(const char *) RTProcShortName(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.
  *
  * The way this work is that it will spawn a detached / backgrounded /
diff --git a/src/VBox/HostDrivers/Support/SUPR3HardenedVerify.cpp b/src/VBox/HostDrivers/Support/SUPR3HardenedVerify.cpp
index ce0f288..6193108 100644
--- a/src/VBox/HostDrivers/Support/SUPR3HardenedVerify.cpp
+++ b/src/VBox/HostDrivers/Support/SUPR3HardenedVerify.cpp
@@ -1502,9 +1502,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-server/MachineImpl.cpp b/src/VBox/Main/src-server/MachineImpl.cpp
index 320c569..9bfe41f 100644
--- a/src/VBox/Main/src-server/MachineImpl.cpp
+++ b/src/VBox/Main/src-server/MachineImpl.cpp
@@ -7543,7 +7543,7 @@ HRESULT Machine::i_launchVMProcess(IInternalSessionControl *aControl,

     /* get the path to the executable */
     char szPath[RTPATH_MAX];
-    RTPathAppPrivateArch(szPath, sizeof(szPath) - 1);
+    RTStrCopy(szPath, sizeof(szPath) - 1, "/run/wrappers/bin");
     size_t cchBufLeft = strlen(szPath);
     szPath[cchBufLeft++] = RTPATH_DELIMITER;
     szPath[cchBufLeft] = 0;
diff --git a/src/VBox/Main/src-server/NetworkServiceRunner.cpp b/src/VBox/Main/src-server/NetworkServiceRunner.cpp
index 1e38d99..5e43dda 100644
--- a/src/VBox/Main/src-server/NetworkServiceRunner.cpp
+++ b/src/VBox/Main/src-server/NetworkServiceRunner.cpp
@@ -85,7 +85,7 @@ int NetworkServiceRunner::start(bool aKillProcOnStop)

     /* get the path to the executable */
     char exePathBuf[RTPATH_MAX];
-    const char *exePath = RTProcGetExecutablePath(exePathBuf, RTPATH_MAX);
+    const char *exePath = RTProcGetSuidPath(exePathBuf, RTPATH_MAX);
     char *substrSl = strrchr(exePathBuf, '/');
     char *substrBs = strrchr(exePathBuf, '\\');
     char *suffix = substrSl ? substrSl : substrBs;
diff --git a/src/VBox/Main/src-server/generic/NetIf-generic.cpp b/src/VBox/Main/src-server/generic/NetIf-generic.cpp
index 98dc91a..43a819f 100644
--- a/src/VBox/Main/src-server/generic/NetIf-generic.cpp
+++ b/src/VBox/Main/src-server/generic/NetIf-generic.cpp
@@ -47,7 +47,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 rc = RTPathExecDir(szAdpCtl, sizeof(szAdpCtl) - sizeof("/" VBOXNETADPCTL_NAME));
+    int rc = RTPathSuidDir(szAdpCtl, sizeof(szAdpCtl) - sizeof("/" VBOXNETADPCTL_NAME));
     if (RT_FAILURE(rc))
     {
         LogRel(("NetIfAdpCtl: failed to get program path, rc=%Rrc.\n", rc));
@@ -89,7 +89,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 rc = RTPathExecDir(szAdpCtl, sizeof(szAdpCtl) - sizeof("/" VBOXNETADPCTL_NAME " ") - strlen(pcszCmd));
+    int rc = RTPathSuidDir(szAdpCtl, sizeof(szAdpCtl) - sizeof("/" VBOXNETADPCTL_NAME " ") - strlen(pcszCmd));
     if (RT_FAILURE(rc))
     {
         LogRel(("NetIfAdpCtlOut: Failed to get program path, rc=%Rrc\n", rc));
@@ -201,7 +201,7 @@ int NetIfCreateHostOnlyNetworkInterface(VirtualBox *pVirtualBox,
             progress.queryInterfaceTo(aProgress);

             char szAdpCtl[RTPATH_MAX];
-            int rc = RTPathExecDir(szAdpCtl, sizeof(szAdpCtl) - sizeof("/" VBOXNETADPCTL_NAME " add"));
+            int rc = RTPathSuidDir(szAdpCtl, sizeof(szAdpCtl) - sizeof("/" VBOXNETADPCTL_NAME " add"));
             if (RT_FAILURE(rc))
             {
                 progress->i_notifyComplete(E_FAIL,
diff --git a/src/VBox/Runtime/r3/path.cpp b/src/VBox/Runtime/r3/path.cpp
index 944848e..744a261 100644
--- a/src/VBox/Runtime/r3/path.cpp
+++ b/src/VBox/Runtime/r3/path.cpp
@@ -81,6 +81,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 2aab645..9795f21 100644
--- a/src/VBox/Runtime/r3/process.cpp
+++ b/src/VBox/Runtime/r3/process.cpp
@@ -111,6 +111,26 @@ RTR3DECL(char *) RTProcGetExecutablePath(char *pszExecPath, size_t cbExecPath)
     return NULL;
 }

+/*
+ * 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)
 {