diff options
author | Simon McVittie <simon.mcvittie@collabora.co.uk> | 2013-06-10 18:06:47 +0100 |
---|---|---|
committer | Simon McVittie <simon.mcvittie@collabora.co.uk> | 2013-06-12 13:55:53 +0100 |
commit | 954d75b2b64e4799f360d2a6bf9cff6d9fee37e7 (patch) | |
tree | b2ce9ace5bc08528c4c1df851147f865159ac056 | |
parent | 355b470da78e25cb451eab0c49f30437b2c5ccb9 (diff) |
CVE-2013-2168: _dbus_printf_string_upper_bound: copy the va_list for each use
Using a va_list more than once is non-portable: it happens to work
under the ABI of (for instance) x86 Linux, but not x86-64 Linux.
This led to _dbus_printf_string_upper_bound() crashing if it should
have returned exactly 1024 bytes. Many system services can be induced
to process a caller-controlled string in ways that
end up using _dbus_printf_string_upper_bound(), so this is a denial of
service.
Reviewed-by: Thiago Macieira <thiago@kde.org>
-rw-r--r-- | dbus/dbus-sysdeps-unix.c | 16 | ||||
-rw-r--r-- | dbus/dbus-sysdeps-win.c | 9 |
2 files changed, 20 insertions, 5 deletions
diff --git a/dbus/dbus-sysdeps-unix.c b/dbus/dbus-sysdeps-unix.c index fc677990..e31c7355 100644 --- a/dbus/dbus-sysdeps-unix.c +++ b/dbus/dbus-sysdeps-unix.c @@ -3123,4 +3123,7 @@ _dbus_printf_string_upper_bound (const char *format, int len; + va_list args_copy; - len = vsnprintf (static_buf, bufsize, format, args); + DBUS_VA_COPY (args_copy, args); + len = vsnprintf (static_buf, bufsize, format, args_copy); + va_end (args_copy); @@ -3140,4 +3143,8 @@ _dbus_printf_string_upper_bound (const char *format, * path. */ - if (vsnprintf (static_buf, 1, format, args) == 1) + DBUS_VA_COPY (args_copy, args); + + if (vsnprintf (static_buf, 1, format, args_copy) == 1) len = -1; + + va_end (args_copy); } @@ -3157,3 +3164,6 @@ _dbus_printf_string_upper_bound (const char *format, - len = vsnprintf (buf, bufsize, format, args); + DBUS_VA_COPY (args_copy, args); + len = vsnprintf (buf, bufsize, format, args_copy); + va_end (args_copy); + dbus_free (buf); diff --git a/dbus/dbus-sysdeps-win.c b/dbus/dbus-sysdeps-win.c index bc4951b5..c42316f1 100644 --- a/dbus/dbus-sysdeps-win.c +++ b/dbus/dbus-sysdeps-win.c @@ -540,5 +540,8 @@ int _dbus_printf_string_upper_bound (const char *format, int len; + va_list args_copy; bufsize = sizeof (buf); - len = _vsnprintf (buf, bufsize - 1, format, args); + DBUS_VA_COPY (args_copy, args); + len = _vsnprintf (buf, bufsize - 1, format, args_copy); + va_end (args_copy); @@ -555,3 +558,5 @@ int _dbus_printf_string_upper_bound (const char *format, - len = _vsnprintf (p, bufsize - 1, format, args); + DBUS_VA_COPY (args_copy, args); + len = _vsnprintf (p, bufsize - 1, format, args_copy); + va_end (args_copy); free (p); |