Status: New
Owner: ----
Labels: Type-Defect Priority-Medium

New issue 948 by [email protected]: ibus_connection_call() returns FALSE without creating an error object, that can cause a crash
http://code.google.com/p/ibus/issues/detail?id=948

IBus version: efad0c3e731da7a3ca46a68d04ffb60614752fa5 in the master branch

As shown below, ibus_connection_call_with_reply_valist() returns FALSE without creating an error object by g_return_val_if_fail (ibus_connection_is_connected (connection), FALSE). BTW, as the return value is a pointer, this should be NULL.

http://github.com/phuang/ibus/blob/d91324c034e83e17715cfa5aa9f8434aacd05a23/src/ibusconnection.c

static IBusMessage *
ibus_connection_call_with_reply_valist (IBusConnection     *connection,
                                        const gchar        *name,
                                        const gchar        *path,
                                        const gchar        *interface,
                                        const gchar        *member,
                                        IBusError          **error,
                                        GType              first_arg_type,
                                        va_list            va_args) {
    g_assert (IBUS_IS_CONNECTION (connection));
    g_assert (name != NULL);
    g_assert (path != NULL);
    g_assert (interface != NULL);
    g_assert (member != NULL);
    g_return_val_if_fail (ibus_connection_is_connected (connection), FALSE);


The function is used for implementing a public function ibus_connection_call() like this:

gboolean
ibus_connection_call (IBusConnection     *connection,
                      const gchar        *name,
                      const gchar        *path,
                      const gchar        *interface,
                      const gchar        *member,
                      IBusError          **error,
                      GType              first_arg_type,
                      ...)
{
    IBusMessage *reply;
    va_list va_args;

    va_start (va_args, first_arg_type);
    reply = ibus_connection_call_with_reply_valist (
        connection, name, path, interface, member, error,
        first_arg_type, va_args);
    va_end (va_args);




I think the code can cause a crash, if callers of ibus_connection_call() expect that an error object is created and returned via
|**error|.

For instance, ibusproxy.cc calls ibus_connection_call() like this:

static GObject *
ibus_proxy_constructor (GType           type,
                        guint           n_construct_params,
                        GObjectConstructParam *construct_params)
{
    ....
    if (priv->name != NULL) {
        IBusError *error;
        ....
        if (!ibus_connection_call (priv->connection,
                                   DBUS_SERVICE_DBUS,
                                   DBUS_PATH_DBUS,
                                   DBUS_INTERFACE_DBUS,
                                   "AddMatch",
                                   &error,
                                   G_TYPE_STRING, &rule,
                                   G_TYPE_INVALID)) {
            g_warning ("%s: %s", error->name, error->message);


As shown, the code assumes that |error| is properly created in ibus_connection_call(), but it's possible that |error| remains uninitialized thus |error->name| points to a random address, if ibus_connection_call_with_reply_valist() returns FALSE by the
g_return_val_if_fail() clause.

FWIW, the issue was found while investigating a crash bug in Chromium OS: crosbug.com/3767


--
You received this message because you are subscribed to the Google
Groups "ibus-devel" group.
iBus project web page: http://code.google.com/p/ibus/
iBus dev group: http://groups.google.com/group/ibus-devel?hl=en

回复