1 From 0166a51ed62581489aec1656d359a7e0e4da8c41 Mon Sep 17 00:00:00 2001
2 From: hmvp <github@hmvp.nl>
3 Date: Wed, 19 Apr 2017 10:50:31 +0200
4 Subject: [PATCH] Fix use after free
6 PyUnicode_AsUTF8String creates a new copy of the data and thus needs a Py_CLEAR (free)
7 PyBytes_AsString does not make a new copy of the data and thus does not need a free
9 However you cannot use the result of PyBytes_AsString after you Py_CLEARed the argument
11 lib/tdbus/_tdbus.c | 46 ++++++++++++++++++++++++++++++----------------
12 1 file changed, 30 insertions(+), 16 deletions(-)
14 diff --git a/lib/tdbus/_tdbus.c b/lib/tdbus/_tdbus.c
15 index 314ea65..46ec3db 100644
16 --- a/lib/tdbus/_tdbus.c
17 +++ b/lib/tdbus/_tdbus.c
18 @@ -1056,28 +1056,42 @@ _tdbus_message_append_arg(DBusMessageIter *iter, char *format,
19 CHECK_PYTHON_ERROR(Putf8 == NULL);
20 subtype = strdup(PyBytes_AsString(Putf8));
24 RETURN_ERROR("expecting str for `%c' format", *format);
26 CHECK_MEMORY_ERROR(subtype == NULL);
27 - if (!_tdbus_check_signature(subtype, 0, 0))
29 + if (!_tdbus_check_signature(subtype, 0, 0)) {
30 RETURN_ERROR("invalid signature");
35 if (!dbus_message_iter_append_basic(iter, *format, &value))
36 RETURN_MEMORY_ERROR();
38 free(subtype); subtype = NULL;
40 case DBUS_TYPE_STRING:
41 if (PyUnicode_Check(arg)) {
42 Putf8 = PyUnicode_AsUTF8String(arg);
43 CHECK_PYTHON_ERROR(Putf8 == NULL);
44 + // PyBytes_AsString does not create a new string but uses a pointer into its argument
45 + // Make sure to make a copy before clearing its argument
46 value.str = PyBytes_AsString(Putf8);
47 + if (!dbus_message_iter_append_basic(iter, *format, &value))
48 + RETURN_MEMORY_ERROR();
51 } else if (PyBytes_Check(arg)) {
52 value.str = PyBytes_AsString(arg);
55 + if (!dbus_message_iter_append_basic(iter, *format, &value))
56 + RETURN_MEMORY_ERROR();
58 RETURN_ERROR("expecting str or unicode for '%c' format", *format);
59 - if (!dbus_message_iter_append_basic(iter, *format, &value))
60 - RETURN_MEMORY_ERROR();
64 case DBUS_STRUCT_BEGIN_CHAR:
65 if (!dbus_message_iter_open_container(iter, DBUS_TYPE_STRUCT,
66 @@ -1379,11 +1393,11 @@ _tdbus_connection_open(const char *address)
67 if (connection == NULL)
68 RETURN_DBUS_ERROR(error);
69 } else if (!strcmp(address, "<STARTER>")) {
70 - Py_BEGIN_ALLOW_THREADS
71 - connection = dbus_bus_get_private(DBUS_BUS_STARTER, &error);
72 - Py_END_ALLOW_THREADS
73 - if (connection == NULL)
74 - RETURN_DBUS_ERROR(error);
75 + Py_BEGIN_ALLOW_THREADS
76 + connection = dbus_bus_get_private(DBUS_BUS_STARTER, &error);
77 + Py_END_ALLOW_THREADS
78 + if (connection == NULL)
79 + RETURN_DBUS_ERROR(error);
81 Py_BEGIN_ALLOW_THREADS
82 connection = dbus_connection_open_private(address, &error);
83 @@ -1932,12 +1946,12 @@ void init_tdbus(void) {
84 EXPORT_STRING(DBUS_BUS_SESSION, "<SESSION>");
85 EXPORT_STRING(DBUS_BUS_STARTER, "<STARTER>");
87 - #define EXPORT_INT_SYMBOL(name) \
89 - if ((Pint = PyInt_FromLong(name)) == NULL) INITERROR; \
90 - PyDict_SetItemString(Pdict, #name, Pint); \
93 + #define EXPORT_INT_SYMBOL(name) \
95 + if ((Pint = PyInt_FromLong(name)) == NULL) INITERROR; \
96 + PyDict_SetItemString(Pdict, #name, Pint); \
100 #define EXPORT_STRING_SYMBOL(name) \