nixpkgs/pkgs/applications/virtualization/virtualbox/hardened.patch

183 lines
8.6 KiB
Diff
Raw Normal View History

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);
2017-11-15 16:03:44 +01:00
/**
+ * 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);
2017-11-15 16:03:44 +01:00
/**
+ * 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
2017-11-15 16:03:44 +01:00
@@ -1502,9 +1502,9 @@ static int supR3HardenedVerifyFsObject(PCSUPR3HARDENEDFSOBJSTATE pFsObjState, bo
bool fBad = !fRelaxed || pFsObjState->Stat.st_gid != 2 /*bin*/ || suplibHardenedStrCmp(pszPath, "/usr/lib/iconv");
2017-11-15 16:03:44 +01:00
# else
NOREF(fRelaxed);
- bool fBad = true;
+ bool fBad = !(fDir && pFsObjState->Stat.st_mode & S_ISVTX && !suplibHardenedStrCmp(pszPath, "/nix/store"));
2017-11-15 16:03:44 +01:00
# 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/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 };
2017-11-15 16:03:44 +01:00
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);
2017-11-15 16:03:44 +01:00
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)
}
2017-11-15 16:03:44 +01:00
+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;
}
2017-11-15 16:03:44 +01:00
+/*
+ * 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;
+}
+
2017-11-15 16:03:44 +01:00
RTR3DECL(const char *) RTProcShortName(void)
{
diff --git a/src/VBox/Main/src-server/NetworkServiceRunner.cpp b/src/VBox/Main/src-server/NetworkServiceRunner.cpp
index 2e57690..3272c84 100644
--- a/src/VBox/Main/src-server/NetworkServiceRunner.cpp
+++ b/src/VBox/Main/src-server/NetworkServiceRunner.cpp
@@ -188,7 +188,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-all/MachineLaunchVMCommonWorker.cpp b/src/VBox/Main/src-all/MachineLaunchVMCommonWorker.cpp
index 2991d3a7..d042a08b 100644
--- a/src/VBox/Main/src-all/MachineLaunchVMCommonWorker.cpp
+++ b/src/VBox/Main/src-all/MachineLaunchVMCommonWorker.cpp
@@ -90,7 +90,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);