~ubuntu-branches/ubuntu/maverick/dbus/maverick-security

« back to all changes in this revision

Viewing changes to dbus/dbus-message-util.c

  • Committer: Bazaar Package Importer
  • Author(s): Jonathan Riddell
  • Date: 2010-09-27 13:06:32 UTC
  • mfrom: (1.1.23 upstream)
  • Revision ID: james.westby@ubuntu.com-20100927130632-bqs145trvchd2lmf
Tags: 1.4.0-0ubuntu1
* New upstream release
 - Fixes https://bugs.freedesktop.org/show_bug.cgi?id=17754 Race condition in protected_change_timeout
 - Requested by various upstream KDE developers http://lists.kde.org/?t=128514970000004&r=1&w=2

Show diffs side-by-side

added added

removed removed

Lines of Context:
22
22
 *
23
23
 */
24
24
 
 
25
#include <config.h>
25
26
#include "dbus-internals.h"
26
27
#include "dbus-test.h"
27
28
#include "dbus-message-private.h"
28
29
#include "dbus-marshal-recursive.h"
29
30
#include "dbus-string.h"
 
31
#ifdef HAVE_UNIX_FD_PASSING
 
32
#include "dbus-sysdeps-unix.h"
 
33
#endif
 
34
 
 
35
#ifdef __linux__
 
36
/* Necessary for the Linux-specific fd leak checking code only */
 
37
#include <sys/types.h>
 
38
#include <dirent.h>
 
39
#include <stdlib.h>
 
40
#include <errno.h>
 
41
#endif
30
42
 
31
43
/**
32
44
 * @addtogroup DBusMessage
126
138
    }
127
139
}
128
140
 
 
141
void
 
142
_dbus_check_fdleaks(void)
 
143
{
 
144
 
 
145
#ifdef __linux__
 
146
 
 
147
  DIR *d;
 
148
 
 
149
  /* This works on Linux only */
 
150
 
 
151
  if ((d = opendir("/proc/self/fd")))
 
152
    {
 
153
      struct dirent *de;
 
154
 
 
155
      while ((de = readdir(d)))
 
156
        {
 
157
          long l;
 
158
          char *e = NULL;
 
159
          int fd;
 
160
 
 
161
          if (de->d_name[0] == '.')
 
162
            continue;
 
163
 
 
164
          errno = 0;
 
165
          l = strtol(de->d_name, &e, 10);
 
166
          _dbus_assert(errno == 0 && e && !*e);
 
167
 
 
168
          fd = (int) l;
 
169
 
 
170
          if (fd < 3)
 
171
            continue;
 
172
 
 
173
          if (fd == dirfd(d))
 
174
            continue;
 
175
 
 
176
          _dbus_warn("file descriptor %i leaked in %s.\n", fd, __FILE__);
 
177
          _dbus_assert_not_reached("fdleaks");
 
178
        }
 
179
 
 
180
      closedir(d);
 
181
    }
 
182
#endif
 
183
}
 
184
 
129
185
static dbus_bool_t
130
186
check_have_valid_message (DBusMessageLoader *loader)
131
187
{
895
951
dbus_bool_t
896
952
_dbus_message_test (const char *test_data_dir)
897
953
{
898
 
  DBusMessage *message;
 
954
  DBusMessage *message, *message_without_unix_fds;
899
955
  DBusMessageLoader *loader;
900
956
  int i;
901
957
  const char *data;
940
996
  unsigned char v2_BYTE;
941
997
  dbus_bool_t v_BOOLEAN;
942
998
  DBusMessageIter iter, array_iter, struct_iter;
 
999
#ifdef HAVE_UNIX_FD_PASSING
 
1000
  int v_UNIX_FD;
 
1001
#endif
 
1002
  char **decomposed;
943
1003
 
944
1004
  message = dbus_message_new_method_call ("org.freedesktop.DBus.TestService",
945
1005
                                          "/org/freedesktop/TestPath",
1035
1095
  _dbus_assert (strcmp (dbus_message_get_member (message),
1036
1096
                        "Bar") == 0);
1037
1097
 
 
1098
  /* Path decomposing */
 
1099
  dbus_message_set_path (message, NULL);
 
1100
  dbus_message_get_path_decomposed (message, &decomposed);
 
1101
  _dbus_assert (decomposed == NULL);
 
1102
  dbus_free_string_array (decomposed);
 
1103
 
 
1104
  dbus_message_set_path (message, "/");
 
1105
  dbus_message_get_path_decomposed (message, &decomposed);
 
1106
  _dbus_assert (decomposed != NULL);
 
1107
  _dbus_assert (decomposed[0] == NULL);
 
1108
  dbus_free_string_array (decomposed);
 
1109
 
 
1110
  dbus_message_set_path (message, "/a/b");
 
1111
  dbus_message_get_path_decomposed (message, &decomposed);
 
1112
  _dbus_assert (decomposed != NULL);
 
1113
  _dbus_assert (strcmp (decomposed[0], "a") == 0);
 
1114
  _dbus_assert (strcmp (decomposed[1], "b") == 0);
 
1115
  _dbus_assert (decomposed[2] == NULL);
 
1116
  dbus_free_string_array (decomposed);
 
1117
 
 
1118
  dbus_message_set_path (message, "/spam/eggs");
 
1119
  dbus_message_get_path_decomposed (message, &decomposed);
 
1120
  _dbus_assert (decomposed != NULL);
 
1121
  _dbus_assert (strcmp (decomposed[0], "spam") == 0);
 
1122
  _dbus_assert (strcmp (decomposed[1], "eggs") == 0);
 
1123
  _dbus_assert (decomposed[2] == NULL);
 
1124
  dbus_free_string_array (decomposed);
 
1125
 
1038
1126
  dbus_message_unref (message);
1039
1127
 
1040
1128
  /* Test the vararg functions */
1058
1146
  v_BOOLEAN = TRUE;
1059
1147
  v_BYTE = 42;
1060
1148
  v2_BYTE = 24;
 
1149
#ifdef HAVE_UNIX_FD_PASSING
 
1150
  v_UNIX_FD = 1;
 
1151
#endif
1061
1152
 
1062
1153
  dbus_message_append_args (message,
1063
1154
                            DBUS_TYPE_INT16, &v_INT16,
1091
1182
                            _DBUS_N_ELEMENTS (our_boolean_array),
1092
1183
                            DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, &v_ARRAY_STRING,
1093
1184
                            _DBUS_N_ELEMENTS (our_string_array),
 
1185
 
1094
1186
                            DBUS_TYPE_INVALID);
1095
1187
 
1096
1188
  i = 0;
1125
1217
  sig[i++] = DBUS_TYPE_BOOLEAN;
1126
1218
  sig[i++] = DBUS_TYPE_ARRAY;
1127
1219
  sig[i++] = DBUS_TYPE_STRING;
1128
 
  sig[i++] = DBUS_TYPE_INVALID;  
 
1220
 
 
1221
  message_without_unix_fds = dbus_message_copy(message);
 
1222
  _dbus_assert(message_without_unix_fds);
 
1223
#ifdef HAVE_UNIX_FD_PASSING
 
1224
  dbus_message_append_args (message,
 
1225
                            DBUS_TYPE_UNIX_FD, &v_UNIX_FD,
 
1226
                            DBUS_TYPE_INVALID);
 
1227
  sig[i++] = DBUS_TYPE_UNIX_FD;
 
1228
#endif
 
1229
  sig[i++] = DBUS_TYPE_INVALID;
1129
1230
 
1130
1231
  _dbus_assert (i < (int) _DBUS_N_ELEMENTS (sig));
1131
1232
 
1202
1303
      _dbus_message_loader_return_buffer (loader, buffer, 1);
1203
1304
    }
1204
1305
 
 
1306
#ifdef HAVE_UNIX_FD_PASSING
 
1307
  {
 
1308
    int *unix_fds;
 
1309
    unsigned n_unix_fds;
 
1310
    /* Write unix fd */
 
1311
    _dbus_message_loader_get_unix_fds(loader, &unix_fds, &n_unix_fds);
 
1312
    _dbus_assert(n_unix_fds > 0);
 
1313
    _dbus_assert(message->n_unix_fds == 1);
 
1314
    unix_fds[0] = _dbus_dup(message->unix_fds[0], NULL);
 
1315
    _dbus_assert(unix_fds[0] >= 0);
 
1316
    _dbus_message_loader_return_unix_fds(loader, unix_fds, 1);
 
1317
  }
 
1318
#endif
 
1319
 
1205
1320
  dbus_message_unref (message);
1206
1321
 
1207
1322
  /* Now pop back the message */
1218
1333
  if (dbus_message_get_reply_serial (message) != 5678)
1219
1334
    _dbus_assert_not_reached ("reply serial fields differ");
1220
1335
 
1221
 
  verify_test_message (message);
 
1336
  dbus_message_unref (message);
 
1337
 
 
1338
  /* ovveride the serial, since it was reset by dbus_message_copy() */
 
1339
  dbus_message_set_serial(message_without_unix_fds, 8901);
 
1340
 
 
1341
  dbus_message_lock (message_without_unix_fds);
 
1342
 
 
1343
  verify_test_message (message_without_unix_fds);
1222
1344
 
1223
1345
    {
1224
1346
      /* Marshal and demarshal the message. */
1229
1351
      int len = 0;
1230
1352
      char garbage_header[DBUS_MINIMUM_HEADER_SIZE] = "xxx";
1231
1353
 
1232
 
      if (!dbus_message_marshal (message, &marshalled, &len))
 
1354
      if (!dbus_message_marshal (message_without_unix_fds, &marshalled, &len))
1233
1355
        _dbus_assert_not_reached ("failed to marshal message");
1234
1356
 
1235
1357
      _dbus_assert (len != 0);
1268
1390
      _dbus_assert (dbus_message_demarshal_bytes_needed (garbage_header, DBUS_MINIMUM_HEADER_SIZE) == -1);
1269
1391
    }
1270
1392
 
1271
 
  dbus_message_unref (message);
 
1393
  dbus_message_unref (message_without_unix_fds);
1272
1394
  _dbus_message_loader_unref (loader);
1273
1395
 
1274
1396
  check_memleaks ();
 
1397
  _dbus_check_fdleaks();
1275
1398
 
1276
1399
  /* Check that we can abandon a container */
1277
1400
  message = dbus_message_new_method_call ("org.freedesktop.DBus.TestService",
1333
1456
    print_validities_seen (FALSE);
1334
1457
    print_validities_seen (TRUE);
1335
1458
  }
1336
 
  
 
1459
 
1337
1460
  check_memleaks ();
1338
 
  
 
1461
  _dbus_check_fdleaks();
 
1462
 
1339
1463
  /* Now load every message in test_data_dir if we have one */
1340
1464
  if (test_data_dir == NULL)
1341
1465
    return TRUE;