From fc7b4fc9ecf26d60384ad3fd3551f3de53fc91e6 Mon Sep 17 00:00:00 2001 From: Scott James Remnant Date: Mon, 11 May 2009 22:41:49 +0100 Subject: Fix issue where timeouts can overflow. * dbus/dbus-connection.c (_dbus_connection_block_pending_call): Rework the timeout math so instead of calculating an end time, which may overflow, we instead calculate the elapsed time which is always smaller than the boundaries. Signed-off-by: Scott James Remnant (cherry picked from commit 1faa92114f6489d286ad4cebe5e91b2145a4f7d1) --- dbus/dbus-connection.c | 21 +++++++-------------- 1 file changed, 7 insertions(+), 14 deletions(-) diff --git a/dbus/dbus-connection.c b/dbus/dbus-connection.c index 31a1d99d..d18cad61 100644 --- a/dbus/dbus-connection.c +++ b/dbus/dbus-connection.c @@ -2275,13 +2275,12 @@ void _dbus_connection_block_pending_call (DBusPendingCall *pending) { long start_tv_sec, start_tv_usec; - long end_tv_sec, end_tv_usec; long tv_sec, tv_usec; DBusDispatchStatus status; DBusConnection *connection; dbus_uint32_t client_serial; DBusTimeout *timeout; - int timeout_milliseconds; + int timeout_milliseconds, elapsed_milliseconds; _dbus_assert (pending != NULL); @@ -2305,18 +2304,12 @@ _dbus_connection_block_pending_call (DBusPendingCall *pending) if (timeout) { timeout_milliseconds = dbus_timeout_get_interval (timeout); - _dbus_get_current_time (&start_tv_sec, &start_tv_usec); - end_tv_sec = start_tv_sec + timeout_milliseconds / 1000; - end_tv_usec = start_tv_usec + (timeout_milliseconds % 1000) * 1000; - end_tv_sec += end_tv_usec / _DBUS_USEC_PER_SECOND; - end_tv_usec = end_tv_usec % _DBUS_USEC_PER_SECOND; - _dbus_verbose ("dbus_connection_send_with_reply_and_block(): will block %d milliseconds for reply serial %u from %ld sec %ld usec to %ld sec %ld usec\n", + _dbus_verbose ("dbus_connection_send_with_reply_and_block(): will block %d milliseconds for reply serial %u from %ld sec %ld usec\n", timeout_milliseconds, client_serial, - start_tv_sec, start_tv_usec, - end_tv_sec, end_tv_usec); + start_tv_sec, start_tv_usec); } else { @@ -2365,6 +2358,8 @@ _dbus_connection_block_pending_call (DBusPendingCall *pending) } _dbus_get_current_time (&tv_sec, &tv_usec); + elapsed_milliseconds = (tv_sec - start_tv_sec) * 1000 + + (tv_usec - start_tv_usec) / 1000; if (!_dbus_connection_get_is_connected_unlocked (connection)) { @@ -2406,11 +2401,9 @@ _dbus_connection_block_pending_call (DBusPendingCall *pending) } else if (tv_sec < start_tv_sec) _dbus_verbose ("dbus_connection_send_with_reply_and_block(): clock set backward\n"); - else if (tv_sec < end_tv_sec || - (tv_sec == end_tv_sec && tv_usec < end_tv_usec)) + else if (elapsed_milliseconds < timeout_milliseconds) { - timeout_milliseconds = (end_tv_sec - tv_sec) * 1000 + - (end_tv_usec - tv_usec) / 1000; + timeout_milliseconds -= elapsed_milliseconds; _dbus_verbose ("dbus_connection_send_with_reply_and_block(): %d milliseconds remain\n", timeout_milliseconds); _dbus_assert (timeout_milliseconds >= 0); -- cgit