Bug 1420124 - Verify dbus interface/path strings at DBus remote service, r?jhorak draft
authorMartin Stransky <stransky@redhat.com>
Thu, 23 Nov 2017 12:27:38 +0100
changeset 702511 bbde5fa6e95ea2ff6b10f7a6ef5f26b2620e105d
parent 701872 5378dcb45044a160fad93b02eed0c617f3324dbc
child 702512 7f45990fdb47a328e82e79084b4253d2d864dc4f
push id90544
push userstransky@redhat.com
push dateThu, 23 Nov 2017 11:33:08 +0000
reviewersjhorak
bugs1420124, 1418985
milestone59.0a1
Bug 1420124 - Verify dbus interface/path strings at DBus remote service, r?jhorak Check DBus arguments by "dbus_validate_*" routines before pass them to DBus interface. If the name is invalid try to create a fallback and eventually give up to avoid crashes (Bug 1418985). Also remove DBusError where it's not useful. MozReview-Commit-ID: DWnzFGUYybp
toolkit/components/remote/nsDBusRemoteService.cpp
--- a/toolkit/components/remote/nsDBusRemoteService.cpp
+++ b/toolkit/components/remote/nsDBusRemoteService.cpp
@@ -21,16 +21,18 @@
 
 #include "nsCOMPtr.h"
 
 #include "nsGTKToolkit.h"
 
 #include <dbus/dbus.h>
 #include <dbus/dbus-glib-lowlevel.h>
 
+#define FALLBACK_NAME "default"
+
 NS_IMPL_ISUPPORTS(nsDBusRemoteService,
                   nsIRemoteService)
 
 NS_IMETHODIMP
 nsDBusRemoteService::RegisterWindow(mozIDOMWindow* aWindow)
 {
   // We don't listen for property change events on DBus remote
   return NS_ERROR_NOT_IMPLEMENTED;
@@ -146,57 +148,66 @@ unregister(DBusConnection *conn, void *u
 static DBusObjectPathVTable remoteHandlersTable = {
   .unregister_function  = unregister,
   .message_function = message_handler,
 };
 
 NS_IMETHODIMP
 nsDBusRemoteService::Startup(const char* aAppName, const char* aProfileName)
 {
-  if (!aAppName || !aProfileName)
-    return NS_ERROR_INVALID_ARG;
-
   if (mConnection && dbus_connection_get_is_connected(mConnection)) {
     // We're already connected so we don't need to reconnect
     return NS_ERROR_ALREADY_INITIALIZED;
   }
 
-  mAppName = aAppName;
-  ToLowerCase(mAppName);
+  if (!aAppName || !aProfileName)
+    return NS_ERROR_INVALID_ARG;
+
+  nsAutoCString busName;
+  busName = nsPrintfCString("org.mozilla.%s.%s", aAppName, aProfileName);
+
+  // Profile name can contains various characters which break
+  // DBus interface (Bug 1418985)
+  if (!dbus_validate_bus_name(busName.get(), nullptr)) {
+    busName = nsPrintfCString("org.mozilla.%s.%s", aAppName, FALLBACK_NAME);
+    if (!dbus_validate_bus_name(busName.get(), nullptr)) {
+      // When both aAppName and aProfileName are rotten just give up here,
+      // caller does not deserve our service.
+      return NS_ERROR_INVALID_ARG;
+    }
+  }
+
+  mConnection = already_AddRefed<DBusConnection>(
+    dbus_bus_get(DBUS_BUS_SESSION, nullptr));
+  if (!mConnection) {
+    return NS_ERROR_FAILURE;
+  }
+  dbus_connection_set_exit_on_disconnect(mConnection, false);
 
   DBusError err;
   dbus_error_init(&err);
-  mConnection = already_AddRefed<DBusConnection>(
-    dbus_bus_get(DBUS_BUS_SESSION, &err));
-  if (dbus_error_is_set(&err)) {
-    dbus_error_free(&err);
-    return NS_ERROR_FAILURE;
-  }
-
-  dbus_connection_set_exit_on_disconnect(mConnection, false);
-
-  nsAutoCString interfaceName;
-  interfaceName = nsPrintfCString("org.mozilla.%s.%s", aAppName, aProfileName);
-
-  dbus_error_init(&err);
-  dbus_bus_request_name(mConnection, interfaceName.get(),
+  dbus_bus_request_name(mConnection, busName.get(),
                        DBUS_NAME_FLAG_DO_NOT_QUEUE, &err);
   // The interface is already owned - there is another application/profile
   // instance already running.
   if (dbus_error_is_set(&err)) {
     dbus_error_free(&err);
     mConnection = nullptr;
     return NS_ERROR_FAILURE;
   }
 
-  nsAutoCString objectName;
-  objectName = nsPrintfCString("/org/mozilla/%s/Remote", aAppName);
+  mAppName = aAppName;
+  ToLowerCase(mAppName);
 
-  if (!dbus_connection_register_object_path(mConnection, objectName.get(),
-                                           &remoteHandlersTable, this)) {
+  nsAutoCString pathName;
+  pathName = nsPrintfCString("/org/mozilla/%s/Remote", mAppName.get());
+  if (!dbus_validate_path(pathName.get(), nullptr) ||
+      !dbus_connection_register_object_path(mConnection, pathName.get(),
+                                            &remoteHandlersTable, this)) {
+    // We failed - just clean up and go away.
     mConnection = nullptr;
     return NS_ERROR_FAILURE;
   }
 
   return NS_OK;
 }
 
 NS_IMETHODIMP