commit 4a92d3943554681ce35e8106ef4f889c7a3bfed3
parent fce0277df0380f3758749c84222f0d76b612385b
Author: Christian Grothoff <christian@grothoff.org>
Date: Tue, 26 Sep 2017 12:54:38 +0200
fix integer overflow in cast to long for very large timeouts on 32-bit platforms
Diffstat:
2 files changed, 23 insertions(+), 11 deletions(-)
diff --git a/src/util/network.c b/src/util/network.c
@@ -1793,10 +1793,18 @@ GNUNET_NETWORK_socket_select (struct GNUNET_NETWORK_FDSet *rfds,
_("Fatal internal logic error, process hangs in `%s' (abort with CTRL-C)!\n"),
"select");
}
- tv.tv_sec = timeout.rel_value_us / GNUNET_TIME_UNIT_SECONDS.rel_value_us;
- tv.tv_usec =
- (timeout.rel_value_us -
- (tv.tv_sec * GNUNET_TIME_UNIT_SECONDS.rel_value_us));
+ if (timeout.rel_value_us / GNUNET_TIME_UNIT_SECONDS.rel_value_us > (unsigned long long) LONG_MAX)
+ {
+ tv.tv_sec = LONG_MAX;
+ tv.tv_usec = 999999L;
+ }
+ else
+ {
+ tv.tv_sec = (long) (timeout.rel_value_us / GNUNET_TIME_UNIT_SECONDS.rel_value_us);
+ tv.tv_usec =
+ (timeout.rel_value_us -
+ (tv.tv_sec * GNUNET_TIME_UNIT_SECONDS.rel_value_us));
+ }
return select (nfds,
(NULL != rfds) ? &rfds->sds : NULL,
(NULL != wfds) ? &wfds->sds : NULL,
diff --git a/src/util/scheduler.c b/src/util/scheduler.c
@@ -73,7 +73,7 @@
* Argument to be passed from the driver to
* #GNUNET_SCHEDULER_run_from_driver(). Contains the
* scheduler's internal state.
- */
+ */
struct GNUNET_SCHEDULER_Handle
{
/**
@@ -94,7 +94,7 @@ struct GNUNET_SCHEDULER_Handle
* Driver we used for the event loop.
*/
const struct GNUNET_SCHEDULER_Driver *driver;
-
+
};
@@ -127,7 +127,7 @@ struct GNUNET_SCHEDULER_Task
* Handle to the scheduler's state.
*/
const struct GNUNET_SCHEDULER_Handle *sh;
-
+
/**
* Set of file descriptors this task is waiting
* for for reading. Once ready, this is updated
@@ -172,7 +172,7 @@ struct GNUNET_SCHEDULER_Task
* Size of the @e fds array.
*/
unsigned int fds_len;
-
+
/**
* Why is the task ready? Set after task is added to ready queue.
* Initially set to zero. All reasons that have already been
@@ -1150,6 +1150,10 @@ GNUNET_SCHEDULER_add_at_with_priority (struct GNUNET_TIME_Absolute at,
struct GNUNET_SCHEDULER_Task *pos;
struct GNUNET_SCHEDULER_Task *prev;
+ if (at.abs_value_us > UINT64_MAX / 10)
+ {
+ GNUNET_assert (0);
+ }
GNUNET_assert (NULL != active_task);
GNUNET_assert (NULL != task);
t = GNUNET_new (struct GNUNET_SCHEDULER_Task);
@@ -1849,7 +1853,7 @@ GNUNET_SCHEDULER_task_ready (struct GNUNET_SCHEDULER_Task *task,
*
* @param sh scheduler handle that was given to the `loop`
* @return #GNUNET_OK if there are more tasks that are ready,
- * and thus we would like to run more (yield to avoid
+ * and thus we would like to run more (yield to avoid
* blocking other activities for too long)
* #GNUNET_NO if we are done running tasks (yield to block)
* #GNUNET_SYSERR on error
@@ -1876,11 +1880,11 @@ GNUNET_SCHEDULER_run_from_driver (struct GNUNET_SCHEDULER_Handle *sh)
pending_timeout_last = NULL;
queue_ready_task (pos);
}
-
+
if (0 == ready_count)
return GNUNET_NO;
- /* find out which task priority level we are going to
+ /* find out which task priority level we are going to
process this time */
max_priority_added = GNUNET_SCHEDULER_PRIORITY_KEEP;
GNUNET_assert (NULL == ready_head[GNUNET_SCHEDULER_PRIORITY_KEEP]);