From: Jacek Konieczny Date: Fri, 10 Nov 2017 08:10:58 +0000 (+0100) Subject: user-after-free fix added from upstream git X-Git-Tag: auto/th/python-tdbus-0.10-1~1 X-Git-Url: http://git.pld-linux.org/gitweb.cgi?a=commitdiff_plain;h=30215a094c456719891e8646ea8190e716123ceb;p=packages%2Fpython-tdbus.git user-after-free fix added from upstream git --- diff --git a/python-tdbus.spec b/python-tdbus.spec index 542ace0..7837c36 100644 --- a/python-tdbus.spec +++ b/python-tdbus.spec @@ -13,6 +13,7 @@ License: MIT Group: Libraries/Python Source0: https://github.com/hmvp/python-tdbus/archive/v0.10/%{name}-%{version}.tar.gz # Source0-md5: 6033776d458aae287d2f9d92a801a42d +Patch0: use_after_free.patch URL: https://github.com/hmvp/python-tdbus BuildRequires: rpm-pythonprov BuildRequires: rpmbuild(macros) >= 1.710 @@ -83,6 +84,7 @@ Dokumentacja API %{module}. %prep %setup -q +%patch0 -p1 %build %if %{with python2} diff --git a/use_after_free.patch b/use_after_free.patch new file mode 100644 index 0000000..1566dac --- /dev/null +++ b/use_after_free.patch @@ -0,0 +1,101 @@ +From 0166a51ed62581489aec1656d359a7e0e4da8c41 Mon Sep 17 00:00:00 2001 +From: hmvp +Date: Wed, 19 Apr 2017 10:50:31 +0200 +Subject: [PATCH] Fix use after free + +PyUnicode_AsUTF8String creates a new copy of the data and thus needs a Py_CLEAR (free) +PyBytes_AsString does not make a new copy of the data and thus does not need a free + +However you cannot use the result of PyBytes_AsString after you Py_CLEARed the argument +--- + lib/tdbus/_tdbus.c | 46 ++++++++++++++++++++++++++++++---------------- + 1 file changed, 30 insertions(+), 16 deletions(-) + +diff --git a/lib/tdbus/_tdbus.c b/lib/tdbus/_tdbus.c +index 314ea65..46ec3db 100644 +--- a/lib/tdbus/_tdbus.c ++++ b/lib/tdbus/_tdbus.c +@@ -1056,28 +1056,42 @@ _tdbus_message_append_arg(DBusMessageIter *iter, char *format, + CHECK_PYTHON_ERROR(Putf8 == NULL); + subtype = strdup(PyBytes_AsString(Putf8)); + Py_CLEAR(Putf8); +- } else ++ } else { + RETURN_ERROR("expecting str for `%c' format", *format); ++ } + CHECK_MEMORY_ERROR(subtype == NULL); +- if (!_tdbus_check_signature(subtype, 0, 0)) ++ ++ if (!_tdbus_check_signature(subtype, 0, 0)) { + RETURN_ERROR("invalid signature"); ++ } ++ + value.str = subtype; ++ + if (!dbus_message_iter_append_basic(iter, *format, &value)) + RETURN_MEMORY_ERROR(); ++ + free(subtype); subtype = NULL; + break; + case DBUS_TYPE_STRING: + if (PyUnicode_Check(arg)) { + Putf8 = PyUnicode_AsUTF8String(arg); + CHECK_PYTHON_ERROR(Putf8 == NULL); ++ // PyBytes_AsString does not create a new string but uses a pointer into its argument ++ // Make sure to make a copy before clearing its argument + value.str = PyBytes_AsString(Putf8); ++ if (!dbus_message_iter_append_basic(iter, *format, &value)) ++ RETURN_MEMORY_ERROR(); ++ + Py_CLEAR(Putf8); + } else if (PyBytes_Check(arg)) { + value.str = PyBytes_AsString(arg); +- } else ++ ++ if (!dbus_message_iter_append_basic(iter, *format, &value)) ++ RETURN_MEMORY_ERROR(); ++ } else { + RETURN_ERROR("expecting str or unicode for '%c' format", *format); +- if (!dbus_message_iter_append_basic(iter, *format, &value)) +- RETURN_MEMORY_ERROR(); ++ } ++ + break; + case DBUS_STRUCT_BEGIN_CHAR: + if (!dbus_message_iter_open_container(iter, DBUS_TYPE_STRUCT, +@@ -1379,11 +1393,11 @@ _tdbus_connection_open(const char *address) + if (connection == NULL) + RETURN_DBUS_ERROR(error); + } else if (!strcmp(address, "")) { +- Py_BEGIN_ALLOW_THREADS +- connection = dbus_bus_get_private(DBUS_BUS_STARTER, &error); +- Py_END_ALLOW_THREADS +- if (connection == NULL) +- RETURN_DBUS_ERROR(error); ++ Py_BEGIN_ALLOW_THREADS ++ connection = dbus_bus_get_private(DBUS_BUS_STARTER, &error); ++ Py_END_ALLOW_THREADS ++ if (connection == NULL) ++ RETURN_DBUS_ERROR(error); + } else { + Py_BEGIN_ALLOW_THREADS + connection = dbus_connection_open_private(address, &error); +@@ -1932,12 +1946,12 @@ void init_tdbus(void) { + EXPORT_STRING(DBUS_BUS_SESSION, ""); + EXPORT_STRING(DBUS_BUS_STARTER, ""); + +- #define EXPORT_INT_SYMBOL(name) \ +- do { \ +- if ((Pint = PyInt_FromLong(name)) == NULL) INITERROR; \ +- PyDict_SetItemString(Pdict, #name, Pint); \ +- Py_DECREF(Pint); \ +- } while (0) ++ #define EXPORT_INT_SYMBOL(name) \ ++ do { \ ++ if ((Pint = PyInt_FromLong(name)) == NULL) INITERROR; \ ++ PyDict_SetItemString(Pdict, #name, Pint); \ ++ Py_DECREF(Pint); \ ++ } while (0) + + #define EXPORT_STRING_SYMBOL(name) \ + do { \