summaryrefslogtreecommitdiff
path: root/src/timeout.c
diff options
context:
space:
mode:
authorMoti Cohen <moti.cohen@redis.com>2022-10-06 12:12:05 +0300
committerGitHub <noreply@github.com>2022-10-06 12:12:05 +0300
commit210ad2e4dbed843ef91c2d291a5823d7c3a5cb66 (patch)
tree40c888d49665cc1f16a7ffedc85d067db84ccdb3 /src/timeout.c
parentb08ebff31f1e3a64ae4c537c3acc40dde7a83976 (diff)
downloadredis-210ad2e4dbed843ef91c2d291a5823d7c3a5cb66.tar.gz
Improve BLMPOP/BZMPOP/WAIT timeout overflow handling and error messages (#11338)
Refine getTimeoutFromObjectOrReply() out-of-range check. Timeout is parsed (and verifies out of range) as double and multiplied by 1000, added mstime() and stored in long-long which might lead to out-of-range value of long-long. Co-authored-by: moticless <moticless@github.com> Co-authored-by: Oran Agra <oran@redislabs.com> Co-authored-by: Ozan Tezcan <ozantezcan@gmail.com>
Diffstat (limited to 'src/timeout.c')
-rw-r--r--src/timeout.c15
1 files changed, 13 insertions, 2 deletions
diff --git a/src/timeout.c b/src/timeout.c
index 36cea7c26..7015ed979 100644
--- a/src/timeout.c
+++ b/src/timeout.c
@@ -164,12 +164,19 @@ void handleBlockedClientsTimeout(void) {
int getTimeoutFromObjectOrReply(client *c, robj *object, mstime_t *timeout, int unit) {
long long tval;
long double ftval;
+ mstime_t now = mstime();
if (unit == UNIT_SECONDS) {
if (getLongDoubleFromObjectOrReply(c,object,&ftval,
"timeout is not a float or out of range") != C_OK)
return C_ERR;
- tval = (long long) (ftval * 1000.0);
+
+ ftval *= 1000.0; /* seconds => millisec */
+ if (ftval > LLONG_MAX) {
+ addReplyError(c, "timeout is out of range");
+ return C_ERR;
+ }
+ tval = (long long) ftval;
} else {
if (getLongLongFromObjectOrReply(c,object,&tval,
"timeout is not an integer or out of range") != C_OK)
@@ -182,7 +189,11 @@ int getTimeoutFromObjectOrReply(client *c, robj *object, mstime_t *timeout, int
}
if (tval > 0) {
- tval += mstime();
+ if (tval > LLONG_MAX - now) {
+ addReplyError(c,"timeout is out of range"); /* 'tval+now' would overflow */
+ return C_ERR;
+ }
+ tval += now;
}
*timeout = tval;