Blob Blame History Raw
From 7aaac1dfba22d2e70b33b2cf856d7885944d4a6e Mon Sep 17 00:00:00 2001
From: Colin Snover <github.com@zetafleet.com>
Date: Thu, 14 Dec 2017 13:51:04 -0600
Subject: [PATCH 1/2] POSIX: Fix CVE-2017-17528

---
 backends/platform/sdl/posix/posix.cpp | 28 ++++++++++++++++++++--------
 1 file changed, 20 insertions(+), 8 deletions(-)

diff --git a/backends/platform/sdl/posix/posix.cpp b/backends/platform/sdl/posix/posix.cpp
index b805a452cf..60f85efc2f 100644
--- a/backends/platform/sdl/posix/posix.cpp
+++ b/backends/platform/sdl/posix/posix.cpp
@@ -49,6 +49,9 @@
 #include <sys/wait.h>
 #include <unistd.h>
 
+#include <spawn.h>
+extern char **environ;
+
 OSystem_POSIX::OSystem_POSIX(Common::String baseConfigName)
 	:
 	_baseConfigName(baseConfigName) {
@@ -279,7 +282,7 @@ bool OSystem_POSIX::openUrl(const Common::String &url) {
 	// try desktop environment specific tools
 	if (launchBrowser("gnome-open", url)) // gnome
 		return true;
-	if (launchBrowser("kfmclient openURL", url)) // kde
+	if (launchBrowser("kfmclient", url)) // kde
 		return true;
 	if (launchBrowser("exo-open", url)) // xfce
 		return true;
@@ -302,15 +305,24 @@ bool OSystem_POSIX::openUrl(const Common::String &url) {
 	return false;
 }
 
-bool OSystem_POSIX::launchBrowser(const Common::String& client, const Common::String &url) {
-	// FIXME: system's input must be heavily escaped
-	// well, when url's specified by user
-	// it's OK now (urls are hardcoded somewhere in GUI)
-	Common::String cmd = client + " " + url;
-	return (system(cmd.c_str()) != -1);
+bool OSystem_POSIX::launchBrowser(const Common::String &client, const Common::String &url) {
+	pid_t pid;
+	const char *argv[] = {
+		client.c_str(),
+		url.c_str(),
+		NULL,
+		NULL
+	};
+	if (client == "kfmclient") {
+		argv[2] = argv[1];
+		argv[1] = "openURL";
+	}
+	if (posix_spawnp(&pid, client.c_str(), NULL, NULL, const_cast<char **>(argv), environ) != 0) {
+		return false;
+	}
+	return (waitpid(pid, NULL, 0) != -1);
 }
 
-
 AudioCDManager *OSystem_POSIX::createAudioCDManager() {
 #ifdef USE_LINUXCD
 	return createLinuxAudioCDManager();
-- 
2.14.3