diff options
| author | Paul Eggert | 2011-05-23 22:16:14 -0700 |
|---|---|---|
| committer | Paul Eggert | 2011-05-23 22:16:14 -0700 |
| commit | 0868606086aade7d84c23522f2624efa6e3040b8 (patch) | |
| tree | 8e4a85f13856503ad3a41d1da8cf26a006301655 /src | |
| parent | 30217ff0cf028810c4f7c6d3b0324e2dfaf2c131 (diff) | |
| download | emacs-0868606086aade7d84c23522f2624efa6e3040b8.tar.gz emacs-0868606086aade7d84c23522f2624efa6e3040b8.zip | |
* dbusbind.c: Serial number integer overflow fixes.
(CHECK_DBUS_SERIAL_GET_SERIAL): New macro.
(xd_invalid_serial): New static function.
(Fdbus_call_method_asynchronously, xd_read_message_1): Use a float
to hold a serial number that is too large for a fixnum.
(Fdbus_method_return_internal, Fdbus_method_error_internal):
Check for serial numbers out of range. Decode any serial number
that was so large that it became a float.
Diffstat (limited to 'src')
| -rw-r--r-- | src/ChangeLog | 9 | ||||
| -rw-r--r-- | src/dbusbind.c | 73 |
2 files changed, 60 insertions, 22 deletions
diff --git a/src/ChangeLog b/src/ChangeLog index 9037adeeb01..d64f914c8d9 100644 --- a/src/ChangeLog +++ b/src/ChangeLog | |||
| @@ -1,5 +1,14 @@ | |||
| 1 | 2011-05-24 Paul Eggert <eggert@cs.ucla.edu> | 1 | 2011-05-24 Paul Eggert <eggert@cs.ucla.edu> |
| 2 | 2 | ||
| 3 | * dbusbind.c: Serial number integer overflow fixes. | ||
| 4 | (CHECK_DBUS_SERIAL_GET_SERIAL): New macro. | ||
| 5 | (xd_invalid_serial): New static function. | ||
| 6 | (Fdbus_call_method_asynchronously, xd_read_message_1): Use a float | ||
| 7 | to hold a serial number that is too large for a fixnum. | ||
| 8 | (Fdbus_method_return_internal, Fdbus_method_error_internal): | ||
| 9 | Check for serial numbers out of range. Decode any serial number | ||
| 10 | that was so large that it became a float. | ||
| 11 | |||
| 3 | * dbusbind.c: Use XFASTINT rather than XUINT, and check for nonneg. | 12 | * dbusbind.c: Use XFASTINT rather than XUINT, and check for nonneg. |
| 4 | (Fdbus_call_method, Fdbus_call_method_asynchronously): | 13 | (Fdbus_call_method, Fdbus_call_method_asynchronously): |
| 5 | Use XFASTINT rather than XUINT when numbers are nonnegative. | 14 | Use XFASTINT rather than XUINT when numbers are nonnegative. |
diff --git a/src/dbusbind.c b/src/dbusbind.c index 50f70f9b9e1..9df7f443d7d 100644 --- a/src/dbusbind.c +++ b/src/dbusbind.c | |||
| @@ -242,6 +242,31 @@ xd_symbol_to_dbus_type (Lisp_Object object) | |||
| 242 | #define XD_NEXT_VALUE(object) \ | 242 | #define XD_NEXT_VALUE(object) \ |
| 243 | ((XD_DBUS_TYPE_P (CAR_SAFE (object))) ? CDR_SAFE (object) : object) | 243 | ((XD_DBUS_TYPE_P (CAR_SAFE (object))) ? CDR_SAFE (object) : object) |
| 244 | 244 | ||
| 245 | /* Check whether X is a valid dbus serial number. If valid, set | ||
| 246 | SERIAL to its value. Otherwise, signal an error. */ | ||
| 247 | #define CHECK_DBUS_SERIAL_GET_SERIAL(x, serial) \ | ||
| 248 | do \ | ||
| 249 | { \ | ||
| 250 | dbus_uint32_t DBUS_SERIAL_MAX = -1; \ | ||
| 251 | if (NATNUMP (x) && XINT (x) <= DBUS_SERIAL_MAX) \ | ||
| 252 | serial = XINT (x); \ | ||
| 253 | else if (MOST_POSITIVE_FIXNUM < DBUS_SERIAL_MAX \ | ||
| 254 | && FLOATP (x) \ | ||
| 255 | && 0 <= XFLOAT_DATA (x) \ | ||
| 256 | && XFLOAT_DATA (x) <= DBUS_SERIAL_MAX) \ | ||
| 257 | serial = XFLOAT_DATA (x); \ | ||
| 258 | else \ | ||
| 259 | xd_invalid_serial (x); \ | ||
| 260 | } \ | ||
| 261 | while (0) | ||
| 262 | |||
| 263 | static void xd_invalid_serial (Lisp_Object) NO_RETURN; | ||
| 264 | static void | ||
| 265 | xd_invalid_serial (Lisp_Object x) | ||
| 266 | { | ||
| 267 | signal_error ("Invalid dbus serial", x); | ||
| 268 | } | ||
| 269 | |||
| 245 | /* Compute SIGNATURE of OBJECT. It must have a form that it can be | 270 | /* Compute SIGNATURE of OBJECT. It must have a form that it can be |
| 246 | used in dbus_message_iter_open_container. DTYPE is the DBusType | 271 | used in dbus_message_iter_open_container. DTYPE is the DBusType |
| 247 | the object is related to. It is passed as argument, because it | 272 | the object is related to. It is passed as argument, because it |
| @@ -1251,6 +1276,7 @@ usage: (dbus-call-method-asynchronously BUS SERVICE PATH INTERFACE METHOD HANDLE | |||
| 1251 | DBusMessage *dmessage; | 1276 | DBusMessage *dmessage; |
| 1252 | DBusMessageIter iter; | 1277 | DBusMessageIter iter; |
| 1253 | unsigned int dtype; | 1278 | unsigned int dtype; |
| 1279 | dbus_uint32_t serial; | ||
| 1254 | int timeout = -1; | 1280 | int timeout = -1; |
| 1255 | size_t i = 6; | 1281 | size_t i = 6; |
| 1256 | char signature[DBUS_MAXIMUM_SIGNATURE_LENGTH]; | 1282 | char signature[DBUS_MAXIMUM_SIGNATURE_LENGTH]; |
| @@ -1335,7 +1361,8 @@ usage: (dbus-call-method-asynchronously BUS SERVICE PATH INTERFACE METHOD HANDLE | |||
| 1335 | XD_SIGNAL1 (build_string ("Cannot send message")); | 1361 | XD_SIGNAL1 (build_string ("Cannot send message")); |
| 1336 | 1362 | ||
| 1337 | /* The result is the key in Vdbus_registered_objects_table. */ | 1363 | /* The result is the key in Vdbus_registered_objects_table. */ |
| 1338 | result = (list2 (bus, make_number (dbus_message_get_serial (dmessage)))); | 1364 | serial = dbus_message_get_serial (dmessage); |
| 1365 | result = list2 (bus, make_fixnum_or_float (serial)); | ||
| 1339 | 1366 | ||
| 1340 | /* Create a hash table entry. */ | 1367 | /* Create a hash table entry. */ |
| 1341 | Fputhash (result, handler, Vdbus_registered_objects_table); | 1368 | Fputhash (result, handler, Vdbus_registered_objects_table); |
| @@ -1368,25 +1395,26 @@ This is an internal function, it shall not be used outside dbus.el. | |||
| 1368 | usage: (dbus-method-return-internal BUS SERIAL SERVICE &rest ARGS) */) | 1395 | usage: (dbus-method-return-internal BUS SERIAL SERVICE &rest ARGS) */) |
| 1369 | (size_t nargs, register Lisp_Object *args) | 1396 | (size_t nargs, register Lisp_Object *args) |
| 1370 | { | 1397 | { |
| 1371 | Lisp_Object bus, serial, service; | 1398 | Lisp_Object bus, service; |
| 1372 | struct gcpro gcpro1, gcpro2, gcpro3; | 1399 | struct gcpro gcpro1, gcpro2; |
| 1373 | DBusConnection *connection; | 1400 | DBusConnection *connection; |
| 1374 | DBusMessage *dmessage; | 1401 | DBusMessage *dmessage; |
| 1375 | DBusMessageIter iter; | 1402 | DBusMessageIter iter; |
| 1376 | unsigned int dtype; | 1403 | dbus_uint32_t serial; |
| 1404 | unsigned int ui_serial, dtype; | ||
| 1377 | size_t i; | 1405 | size_t i; |
| 1378 | char signature[DBUS_MAXIMUM_SIGNATURE_LENGTH]; | 1406 | char signature[DBUS_MAXIMUM_SIGNATURE_LENGTH]; |
| 1379 | 1407 | ||
| 1380 | /* Check parameters. */ | 1408 | /* Check parameters. */ |
| 1381 | bus = args[0]; | 1409 | bus = args[0]; |
| 1382 | serial = args[1]; | ||
| 1383 | service = args[2]; | 1410 | service = args[2]; |
| 1384 | 1411 | ||
| 1385 | CHECK_NATNUM (serial); | 1412 | CHECK_DBUS_SERIAL_GET_SERIAL (args[1], serial); |
| 1386 | CHECK_STRING (service); | 1413 | CHECK_STRING (service); |
| 1387 | GCPRO3 (bus, serial, service); | 1414 | GCPRO2 (bus, service); |
| 1388 | 1415 | ||
| 1389 | XD_DEBUG_MESSAGE ("%"pI"d %s ", XFASTINT (serial), SSDATA (service)); | 1416 | ui_serial = serial; |
| 1417 | XD_DEBUG_MESSAGE ("%u %s ", ui_serial, SSDATA (service)); | ||
| 1390 | 1418 | ||
| 1391 | /* Open a connection to the bus. */ | 1419 | /* Open a connection to the bus. */ |
| 1392 | connection = xd_initialize (bus, TRUE); | 1420 | connection = xd_initialize (bus, TRUE); |
| @@ -1394,7 +1422,7 @@ usage: (dbus-method-return-internal BUS SERIAL SERVICE &rest ARGS) */) | |||
| 1394 | /* Create the message. */ | 1422 | /* Create the message. */ |
| 1395 | dmessage = dbus_message_new (DBUS_MESSAGE_TYPE_METHOD_RETURN); | 1423 | dmessage = dbus_message_new (DBUS_MESSAGE_TYPE_METHOD_RETURN); |
| 1396 | if ((dmessage == NULL) | 1424 | if ((dmessage == NULL) |
| 1397 | || (!dbus_message_set_reply_serial (dmessage, XFASTINT (serial))) | 1425 | || (!dbus_message_set_reply_serial (dmessage, serial)) |
| 1398 | || (!dbus_message_set_destination (dmessage, SSDATA (service)))) | 1426 | || (!dbus_message_set_destination (dmessage, SSDATA (service)))) |
| 1399 | { | 1427 | { |
| 1400 | UNGCPRO; | 1428 | UNGCPRO; |
| @@ -1456,25 +1484,26 @@ This is an internal function, it shall not be used outside dbus.el. | |||
| 1456 | usage: (dbus-method-error-internal BUS SERIAL SERVICE &rest ARGS) */) | 1484 | usage: (dbus-method-error-internal BUS SERIAL SERVICE &rest ARGS) */) |
| 1457 | (size_t nargs, register Lisp_Object *args) | 1485 | (size_t nargs, register Lisp_Object *args) |
| 1458 | { | 1486 | { |
| 1459 | Lisp_Object bus, serial, service; | 1487 | Lisp_Object bus, service; |
| 1460 | struct gcpro gcpro1, gcpro2, gcpro3; | 1488 | struct gcpro gcpro1, gcpro2; |
| 1461 | DBusConnection *connection; | 1489 | DBusConnection *connection; |
| 1462 | DBusMessage *dmessage; | 1490 | DBusMessage *dmessage; |
| 1463 | DBusMessageIter iter; | 1491 | DBusMessageIter iter; |
| 1464 | unsigned int dtype; | 1492 | dbus_uint32_t serial; |
| 1493 | unsigned int ui_serial, dtype; | ||
| 1465 | size_t i; | 1494 | size_t i; |
| 1466 | char signature[DBUS_MAXIMUM_SIGNATURE_LENGTH]; | 1495 | char signature[DBUS_MAXIMUM_SIGNATURE_LENGTH]; |
| 1467 | 1496 | ||
| 1468 | /* Check parameters. */ | 1497 | /* Check parameters. */ |
| 1469 | bus = args[0]; | 1498 | bus = args[0]; |
| 1470 | serial = args[1]; | ||
| 1471 | service = args[2]; | 1499 | service = args[2]; |
| 1472 | 1500 | ||
| 1473 | CHECK_NATNUM (serial); | 1501 | CHECK_DBUS_SERIAL_GET_SERIAL (args[1], serial); |
| 1474 | CHECK_STRING (service); | 1502 | CHECK_STRING (service); |
| 1475 | GCPRO3 (bus, serial, service); | 1503 | GCPRO2 (bus, service); |
| 1476 | 1504 | ||
| 1477 | XD_DEBUG_MESSAGE ("%"pI"d %s ", XFASTINT (serial), SSDATA (service)); | 1505 | ui_serial = serial; |
| 1506 | XD_DEBUG_MESSAGE ("%u %s ", ui_serial, SSDATA (service)); | ||
| 1478 | 1507 | ||
| 1479 | /* Open a connection to the bus. */ | 1508 | /* Open a connection to the bus. */ |
| 1480 | connection = xd_initialize (bus, TRUE); | 1509 | connection = xd_initialize (bus, TRUE); |
| @@ -1483,7 +1512,7 @@ usage: (dbus-method-error-internal BUS SERIAL SERVICE &rest ARGS) */) | |||
| 1483 | dmessage = dbus_message_new (DBUS_MESSAGE_TYPE_ERROR); | 1512 | dmessage = dbus_message_new (DBUS_MESSAGE_TYPE_ERROR); |
| 1484 | if ((dmessage == NULL) | 1513 | if ((dmessage == NULL) |
| 1485 | || (!dbus_message_set_error_name (dmessage, DBUS_ERROR_FAILED)) | 1514 | || (!dbus_message_set_error_name (dmessage, DBUS_ERROR_FAILED)) |
| 1486 | || (!dbus_message_set_reply_serial (dmessage, XFASTINT (serial))) | 1515 | || (!dbus_message_set_reply_serial (dmessage, serial)) |
| 1487 | || (!dbus_message_set_destination (dmessage, SSDATA (service)))) | 1516 | || (!dbus_message_set_destination (dmessage, SSDATA (service)))) |
| 1488 | { | 1517 | { |
| 1489 | UNGCPRO; | 1518 | UNGCPRO; |
| @@ -1665,7 +1694,7 @@ xd_read_message_1 (DBusConnection *connection, Lisp_Object bus) | |||
| 1665 | unsigned int dtype; | 1694 | unsigned int dtype; |
| 1666 | int mtype; | 1695 | int mtype; |
| 1667 | dbus_uint32_t serial; | 1696 | dbus_uint32_t serial; |
| 1668 | unsigned int userial; | 1697 | unsigned int ui_serial; |
| 1669 | const char *uname, *path, *interface, *member; | 1698 | const char *uname, *path, *interface, *member; |
| 1670 | 1699 | ||
| 1671 | dmessage = dbus_connection_pop_message (connection); | 1700 | dmessage = dbus_connection_pop_message (connection); |
| @@ -1694,7 +1723,7 @@ xd_read_message_1 (DBusConnection *connection, Lisp_Object bus) | |||
| 1694 | /* Read message type, message serial, unique name, object path, | 1723 | /* Read message type, message serial, unique name, object path, |
| 1695 | interface and member from the message. */ | 1724 | interface and member from the message. */ |
| 1696 | mtype = dbus_message_get_type (dmessage); | 1725 | mtype = dbus_message_get_type (dmessage); |
| 1697 | userial = serial = | 1726 | ui_serial = serial = |
| 1698 | ((mtype == DBUS_MESSAGE_TYPE_METHOD_RETURN) | 1727 | ((mtype == DBUS_MESSAGE_TYPE_METHOD_RETURN) |
| 1699 | || (mtype == DBUS_MESSAGE_TYPE_ERROR)) | 1728 | || (mtype == DBUS_MESSAGE_TYPE_ERROR)) |
| 1700 | ? dbus_message_get_reply_serial (dmessage) | 1729 | ? dbus_message_get_reply_serial (dmessage) |
| @@ -1714,14 +1743,14 @@ xd_read_message_1 (DBusConnection *connection, Lisp_Object bus) | |||
| 1714 | : (mtype == DBUS_MESSAGE_TYPE_ERROR) | 1743 | : (mtype == DBUS_MESSAGE_TYPE_ERROR) |
| 1715 | ? "DBUS_MESSAGE_TYPE_ERROR" | 1744 | ? "DBUS_MESSAGE_TYPE_ERROR" |
| 1716 | : "DBUS_MESSAGE_TYPE_SIGNAL", | 1745 | : "DBUS_MESSAGE_TYPE_SIGNAL", |
| 1717 | userial, uname, path, interface, member, | 1746 | ui_serial, uname, path, interface, member, |
| 1718 | SDATA (format2 ("%s", args, Qnil))); | 1747 | SDATA (format2 ("%s", args, Qnil))); |
| 1719 | 1748 | ||
| 1720 | if ((mtype == DBUS_MESSAGE_TYPE_METHOD_RETURN) | 1749 | if ((mtype == DBUS_MESSAGE_TYPE_METHOD_RETURN) |
| 1721 | || (mtype == DBUS_MESSAGE_TYPE_ERROR)) | 1750 | || (mtype == DBUS_MESSAGE_TYPE_ERROR)) |
| 1722 | { | 1751 | { |
| 1723 | /* Search for a registered function of the message. */ | 1752 | /* Search for a registered function of the message. */ |
| 1724 | key = list2 (bus, make_number (serial)); | 1753 | key = list2 (bus, make_fixnum_or_float (serial)); |
| 1725 | value = Fgethash (key, Vdbus_registered_objects_table, Qnil); | 1754 | value = Fgethash (key, Vdbus_registered_objects_table, Qnil); |
| 1726 | 1755 | ||
| 1727 | /* There shall be exactly one entry. Construct an event. */ | 1756 | /* There shall be exactly one entry. Construct an event. */ |
| @@ -1787,7 +1816,7 @@ xd_read_message_1 (DBusConnection *connection, Lisp_Object bus) | |||
| 1787 | event.arg); | 1816 | event.arg); |
| 1788 | event.arg = Fcons ((uname == NULL ? Qnil : build_string (uname)), | 1817 | event.arg = Fcons ((uname == NULL ? Qnil : build_string (uname)), |
| 1789 | event.arg); | 1818 | event.arg); |
| 1790 | event.arg = Fcons (make_number (serial), event.arg); | 1819 | event.arg = Fcons (make_fixnum_or_float (serial), event.arg); |
| 1791 | event.arg = Fcons (make_number (mtype), event.arg); | 1820 | event.arg = Fcons (make_number (mtype), event.arg); |
| 1792 | 1821 | ||
| 1793 | /* Add the bus symbol to the event. */ | 1822 | /* Add the bus symbol to the event. */ |