From 1d1e90ae76af9651a562decb0f264a4a47e36ca5 Mon Sep 17 00:00:00 2001 From: Chengwei Yang Date: Tue, 9 Jul 2013 10:43:27 +0800 Subject: [PATCH 1/2] Fix: launch-helper voilate dbus spec In DBus Spec, there is no limit to name .service file after its bus name, for example. A.service is not limited to own Names=A. However, launch-helper does the above, so it will fail if the name A to be activated by it provided by B.service. Bug: https://bugs.freedesktop.org/show_bug.cgi?id=66608 Signed-off-by: Chengwei Yang --- bus/activation-helper.c | 146 +++++++++++++++++++++++++++++------------------ 1 file changed, 89 insertions(+), 57 deletions(-) diff --git a/bus/activation-helper.c b/bus/activation-helper.c index 8d7ae36..a1e7bd5 100644 --- a/bus/activation-helper.c +++ b/bus/activation-helper.c @@ -43,6 +43,11 @@ #include #include +static dbus_bool_t +check_service_name (BusDesktopFile *desktop_file, + const char *service_name, + DBusError *error); + static BusDesktopFile * desktop_file_for_name (BusConfigParser *parser, const char *name, @@ -54,11 +59,13 @@ desktop_file_for_name (BusConfigParser *parser, DBusError tmp_error; DBusString full_path; DBusString filename; - const char *dir; + DBusString dir; + DBusDirIter *iter; _DBUS_ASSERT_ERROR_IS_CLEAR (error); desktop_file = NULL; + iter = NULL; if (!_dbus_string_init (&filename)) { @@ -72,65 +79,92 @@ desktop_file_for_name (BusConfigParser *parser, goto out_filename; } - if (!_dbus_string_append (&filename, name) || - !_dbus_string_append (&filename, ".service")) - { - BUS_SET_OOM (error); - goto out; - } - service_dirs = bus_config_parser_get_service_dirs (parser); for (link = _dbus_list_get_first_link (service_dirs); link != NULL; link = _dbus_list_get_next_link (service_dirs, link)) { - dir = link->data; - _dbus_verbose ("Looking at '%s'\n", dir); - - dbus_error_init (&tmp_error); - - /* clear the path from last time */ - _dbus_string_set_length (&full_path, 0); + _dbus_verbose ("Looking at '%s'\n", (char *)link->data); + _dbus_string_init_const (&dir, link->data); - /* build the full path */ - if (!_dbus_string_append (&full_path, dir) || - !_dbus_concat_dir_and_file (&full_path, &filename)) + iter = _dbus_directory_open (&dir, error); + if (iter == NULL) { - BUS_SET_OOM (error); + _dbus_verbose ("Failed to open directory %s: %s\n", + (char *)link->data, + error ? error->message : "unknown"); goto out; } - _dbus_verbose ("Trying to load file '%s'\n", _dbus_string_get_data (&full_path)); - desktop_file = bus_desktop_file_load (&full_path, &tmp_error); - if (desktop_file == NULL) + dbus_error_init (&tmp_error); + while (_dbus_directory_get_next_file (iter, &filename, &tmp_error)) { - _DBUS_ASSERT_ERROR_IS_SET (&tmp_error); - _dbus_verbose ("Could not load %s: %s: %s\n", - _dbus_string_get_const_data (&full_path), - tmp_error.name, tmp_error.message); + _dbus_assert (!dbus_error_is_set (&tmp_error)); + _dbus_string_set_length (&full_path, 0); + if (!_dbus_string_ends_with_c_str (&filename, ".service")) + { + _dbus_verbose ("Skipping non-.service file %s\n", + _dbus_string_get_const_data (&filename)); + continue; + } - /* we may have failed if the file is not found; this is not fatal */ - if (dbus_error_has_name (&tmp_error, DBUS_ERROR_NO_MEMORY)) + /* build the full path */ + if (!_dbus_string_append (&full_path, link->data) || + !_dbus_concat_dir_and_file (&full_path, &filename)) { - dbus_move_error (&tmp_error, error); - /* we only bail out on OOM */ + BUS_SET_OOM (error); + _dbus_directory_close (iter); + goto out; + } + + _dbus_verbose ("Trying to load file '%s'\n", _dbus_string_get_data (&full_path)); + desktop_file = bus_desktop_file_load (&full_path, &tmp_error); + if (desktop_file == NULL) + { + _DBUS_ASSERT_ERROR_IS_SET (&tmp_error); + _dbus_verbose ("Could not load %s: %s: %s\n", + _dbus_string_get_const_data (&full_path), + tmp_error.name, tmp_error.message); + + if (dbus_error_has_name (&tmp_error, DBUS_ERROR_NO_MEMORY)) + { + /* we only bail out on OOM */ + dbus_move_error (&tmp_error, error); + dbus_error_free (&tmp_error); + _dbus_directory_close (iter); + goto out; + } + dbus_error_free (&tmp_error); + } + else if (check_service_name (desktop_file, name, error)) + { + if (dbus_error_is_set (error)) + { + bus_desktop_file_free (desktop_file); + desktop_file = NULL; + } + _dbus_directory_close (iter); goto out; } + else + { + bus_desktop_file_free (desktop_file); + desktop_file = NULL; + } + } + _dbus_directory_close (iter); + if (dbus_error_is_set (&tmp_error)) + { + dbus_move_error (&tmp_error, error); dbus_error_free (&tmp_error); + goto out; } - - /* did we find the desktop file we want? */ - if (desktop_file != NULL) - break; } /* Didn't find desktop file; set error */ - if (desktop_file == NULL) - { - dbus_set_error (error, DBUS_ERROR_SPAWN_SERVICE_NOT_FOUND, - "The name %s was not provided by any .service files", - name); - } + dbus_set_error (error, DBUS_ERROR_SPAWN_SERVICE_NOT_FOUND, + "The name %s was not provided by any .service files", + name); out: _dbus_string_free (&full_path); @@ -210,31 +244,33 @@ check_service_name (BusDesktopFile *desktop_file, { char *name_tmp; dbus_bool_t retval; + DBusError tmp_error; - retval = FALSE; - + dbus_error_init (&tmp_error); /* try to get Name */ if (!bus_desktop_file_get_string (desktop_file, DBUS_SERVICE_SECTION, DBUS_SERVICE_NAME, &name_tmp, - error)) - goto failed; - - /* verify that the name is the same as the file service name */ - if (strcmp (service_name, name_tmp) != 0) + &tmp_error)) { - dbus_set_error (error, DBUS_ERROR_SPAWN_FILE_INVALID, - "Service '%s' does not match expected value", name_tmp); - goto failed_free; + if (dbus_error_is_set (&tmp_error)) + { + if (dbus_error_has_name (&tmp_error, DBUS_ERROR_NO_MEMORY)) + { + dbus_move_error (&tmp_error, error); + dbus_error_free (&tmp_error); + return TRUE; + } + dbus_error_free (&tmp_error); + } + return FALSE; } - retval = TRUE; + retval = !strcmp (service_name, name_tmp); -failed_free: /* we don't return the name, so free it here */ dbus_free (name_tmp); -failed: return retval; } @@ -251,10 +287,6 @@ get_parameters_for_service (BusDesktopFile *desktop_file, exec_tmp = NULL; user_tmp = NULL; - /* check the name of the service */ - if (!check_service_name (desktop_file, service_name, error)) - goto failed; - /* get the complete path of the executable */ if (!bus_desktop_file_get_string (desktop_file, DBUS_SERVICE_SECTION, -- 1.7.9.5