summaryrefslogtreecommitdiff
path: root/sysutils/dbus/patches/patch-CVE-2010-4352-2
blob: 1637839a9dffd36e4727c00e84d7b80635265869 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
$NetBSD: patch-CVE-2010-4352-2,v 1.1.2.2 2010/12/30 03:37:22 sbd Exp $

Fix for CVE-2010-4352 taken from here:

http://cgit.freedesktop.org/dbus/dbus/commit/?h=dbus-1.2&id=5042c1e5e6df31700215c9dc0618634911b0c9f5

--- dbus/dbus-message-factory.c.orig	2009-05-06 18:26:48.000000000 +0100
+++ dbus/dbus-message-factory.c	2010-12-29 10:35:49.000000000 +0000
@@ -333,6 +333,53 @@
   return message;
 }
 
+static DBusMessage*
+message_with_nesting_levels (int levels)
+{
+  DBusMessage *message;
+  dbus_int32_t v_INT32;
+  DBusMessageIter *parents;
+  DBusMessageIter *children;
+  int i;
+
+  /* If levels is higher it breaks sig_refcount in DBusMessageRealIter
+   * in dbus-message.c, this assert is just to help you know you need
+   * to fix that if you hit it
+   */
+  _dbus_assert (levels < 256);
+
+  parents = dbus_new(DBusMessageIter, levels + 1);
+  children = dbus_new(DBusMessageIter, levels + 1);
+
+  v_INT32 = 42;
+  message = simple_method_call ();
+
+  i = 0;
+  dbus_message_iter_init_append (message, &parents[i]);
+  while (i < levels)
+    {
+      dbus_message_iter_open_container (&parents[i], DBUS_TYPE_VARIANT,
+                                        i == (levels - 1) ?
+                                        DBUS_TYPE_INT32_AS_STRING :
+                                        DBUS_TYPE_VARIANT_AS_STRING,
+                                        &children[i]);
+      ++i;
+      parents[i] = children[i-1];
+    }
+  --i;
+  dbus_message_iter_append_basic (&children[i], DBUS_TYPE_INT32, &v_INT32);
+  while (i >= 0)
+    {
+      dbus_message_iter_close_container (&parents[i], &children[i]);
+      --i;
+    }
+
+  dbus_free(parents);
+  dbus_free(children);
+
+  return message;
+}
+
 static dbus_bool_t
 generate_special (DBusMessageDataIter   *iter,
                   DBusString            *data,
@@ -735,6 +782,24 @@
       
       *expected_validity = DBUS_INVALID_DICT_ENTRY_HAS_NO_FIELDS;
     }
+  else if (item_seq == 20)
+    {
+      /* 64 levels of nesting is OK */
+      message = message_with_nesting_levels(64);
+
+      generate_from_message (data, expected_validity, message);
+
+      *expected_validity = DBUS_VALID;
+    }
+  else if (item_seq == 21)
+    {
+      /* 65 levels of nesting is not OK */
+      message = message_with_nesting_levels(65);
+
+      generate_from_message (data, expected_validity, message);
+
+      *expected_validity = DBUS_INVALID_NESTED_TOO_DEEPLY;
+    }
   else
     {
       return FALSE;