]> git.pld-linux.org Git - packages/python-tdbus.git/blob - use_after_free.patch
user-after-free fix added from upstream git
[packages/python-tdbus.git] / use_after_free.patch
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
5
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
8
9 However you cannot use the result of PyBytes_AsString after you Py_CLEARed the argument
10 ---
11  lib/tdbus/_tdbus.c | 46 ++++++++++++++++++++++++++++++----------------
12  1 file changed, 30 insertions(+), 16 deletions(-)
13
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));
21              Py_CLEAR(Putf8);
22 -        } else
23 +        } else {
24              RETURN_ERROR("expecting str for `%c' format", *format);
25 +        }
26          CHECK_MEMORY_ERROR(subtype == NULL);
27 -        if (!_tdbus_check_signature(subtype, 0, 0))
28 +
29 +        if (!_tdbus_check_signature(subtype, 0, 0)) {
30              RETURN_ERROR("invalid signature");
31 +        }
32 +
33          value.str = subtype;
34 +
35          if (!dbus_message_iter_append_basic(iter, *format, &value))
36              RETURN_MEMORY_ERROR();
37 +
38          free(subtype); subtype = NULL;
39          break;
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();
49 +
50              Py_CLEAR(Putf8);
51          } else if (PyBytes_Check(arg)) {
52              value.str = PyBytes_AsString(arg);
53 -        } else
54 +
55 +            if (!dbus_message_iter_append_basic(iter, *format, &value))
56 +                RETURN_MEMORY_ERROR();
57 +        } else {
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();
61 +        }
62 +
63          break;
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);
80      } else {
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>");
86  
87 -       #define EXPORT_INT_SYMBOL(name) \
88 -               do { \
89 -                       if ((Pint = PyInt_FromLong(name)) == NULL) INITERROR; \
90 -                       PyDict_SetItemString(Pdict, #name, Pint); \
91 -                       Py_DECREF(Pint); \
92 -               } while (0)
93 +    #define EXPORT_INT_SYMBOL(name) \
94 +        do { \
95 +            if ((Pint = PyInt_FromLong(name)) == NULL) INITERROR; \
96 +            PyDict_SetItemString(Pdict, #name, Pint); \
97 +            Py_DECREF(Pint); \
98 +        } while (0)
99  
100      #define EXPORT_STRING_SYMBOL(name) \
101          do { \
This page took 0.03309 seconds and 3 git commands to generate.