From 24187ed8e396625cc44a6bbeeb87e01aec55c27d Mon Sep 17 00:00:00 2001 From: Nir Rattner Date: Sun, 24 Sep 2023 06:31:12 -0400 Subject: [PATCH] Fix overflow calculation for next timer event (#12474) The `retval` variable is defined as an `int`, so with 4 bytes, it cannot properly represent microsecond values greater than the equivalent of about 35 minutes. This bug shouldn't impact standard Redis behavior because Redis doesn't have timer events that are scheduled as far as 35 minutes out, but it may affect custom Redis modules which interact with the event timers via the RM_CreateTimer API. The impact is that `usUntilEarliestTimer` may return 0 for as long as `retval` is scaled to an overflowing value. While `usUntilEarliestTimer` continues to return `0`, `aeApiPoll` will have a zero timeout, and so Redis will use significantly more CPU iterating through its event loop without pause. For timers scheduled far enough into the future, Redis will cycle between ~35 minute periods of high CPU usage and ~35 minute periods of standard CPU usage. --- src/ae.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ae.c b/src/ae.c index 1b6422b2d..ff60630e3 100644 --- a/src/ae.c +++ b/src/ae.c @@ -333,7 +333,7 @@ static int processTimeEvents(aeEventLoop *eventLoop) { processed++; now = getMonotonicUs(); if (retval != AE_NOMORE) { - te->when = now + retval * 1000; + te->when = now + (monotime)retval * 1000; } else { te->id = AE_DELETED_EVENT_ID; }