From b5a420cb113beeb84b4aa02fe5d22b49722d598a Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Fri, 13 Jul 2018 17:53:24 -0400 Subject: [PATCH] dbus: Deal with undefined behavior with va_args. Parse out a copy of the varargs ourselves to get to the reply portion, since the original passed to D-Bus might modify or not modify the caller's copy, depending on system ABI. --- src/core/linux/SDL_dbus.c | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/src/core/linux/SDL_dbus.c b/src/core/linux/SDL_dbus.c index ff4f0fe67..e0d99725d 100644 --- a/src/core/linux/SDL_dbus.c +++ b/src/core/linux/SDL_dbus.c @@ -173,17 +173,29 @@ SDL_DBus_CallMethodInternal(DBusConnection *conn, const char *node, const char * if (conn) { DBusMessage *msg = dbus.message_new_method_call(node, path, interface, method); if (msg) { - int firstarg = va_arg(ap, int); + int firstarg; + va_list ap_reply; + va_copy(ap_reply, ap); /* copy the arg list so we don't compete with D-Bus for it */ + firstarg = va_arg(ap, int); if ((firstarg == DBUS_TYPE_INVALID) || dbus.message_append_args_valist(msg, firstarg, ap)) { DBusMessage *reply = dbus.connection_send_with_reply_and_block(conn, msg, 300, NULL); if (reply) { - firstarg = va_arg(ap, int); - if ((firstarg == DBUS_TYPE_INVALID) || dbus.message_get_args_valist(reply, NULL, firstarg, ap)) { + /* skip any input args, get to output args. */ + while ((firstarg = va_arg(ap_reply, int)) != DBUS_TYPE_INVALID) { + /* we assume D-Bus already validated all this. */ + { void *dumpptr = va_arg(ap_reply, void*); (void) dumpptr; } + if (firstarg == DBUS_TYPE_ARRAY) { + { const int dumpint = va_arg(ap_reply, int); (void) dumpint; } + } + } + firstarg = va_arg(ap_reply, int); + if ((firstarg == DBUS_TYPE_INVALID) || dbus.message_get_args_valist(reply, NULL, firstarg, ap_reply)) { retval = SDL_TRUE; } dbus.message_unref(reply); } } + va_end(ap_reply); dbus.message_unref(msg); } }