Improve moduleBlockClient timeout overflow handling (#12174)

Continuation of https://github.com/redis/redis/pull/11338
avoid overflow adding input timeout to "now" in moduleBlockClient.
This commit is contained in:
guybe7 2023-06-21 11:48:13 +02:00 committed by GitHub
parent 73cf0243df
commit d46ef88671
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -7677,7 +7677,6 @@ RedisModuleBlockedClient *moduleBlockClient(RedisModuleCtx *ctx, RedisModuleCmdF
* commands from Lua or MULTI. We actually create an already aborted
* (client set to NULL) blocked client handle, and actually reply with
* an error. */
mstime_t timeout = timeout_ms ? (mstime()+timeout_ms) : 0;
bc->client = (islua || ismulti) ? NULL : c;
bc->module = ctx->module;
bc->reply_callback = reply_callback;
@ -7695,7 +7694,17 @@ RedisModuleBlockedClient *moduleBlockClient(RedisModuleCtx *ctx, RedisModuleCmdF
bc->unblocked = 0;
bc->background_timer = 0;
bc->background_duration = 0;
c->bstate.timeout = timeout;
c->bstate.timeout = 0;
if (timeout_ms) {
mstime_t now = mstime();
if (timeout_ms > LLONG_MAX - now) {
c->bstate.module_blocked_handle = NULL;
addReplyError(c, "timeout is out of range"); /* 'timeout_ms+now' would overflow */
return bc;
}
c->bstate.timeout = timeout_ms + now;
}
if (islua || ismulti) {
c->bstate.module_blocked_handle = NULL;
@ -7705,13 +7714,12 @@ RedisModuleBlockedClient *moduleBlockClient(RedisModuleCtx *ctx, RedisModuleCmdF
} else if (ctx->flags & REDISMODULE_CTX_BLOCKED_REPLY) {
c->bstate.module_blocked_handle = NULL;
addReplyError(c, "Blocking module command called from a Reply callback context");
}
else if (!auth_reply_callback && clientHasModuleAuthInProgress(c)) {
} else if (!auth_reply_callback && clientHasModuleAuthInProgress(c)) {
c->bstate.module_blocked_handle = NULL;
addReplyError(c, "Clients undergoing module based authentication can only be blocked on auth");
} else {
if (keys) {
blockForKeys(c,BLOCKED_MODULE,keys,numkeys,timeout,flags&REDISMODULE_BLOCK_UNBLOCK_DELETED);
blockForKeys(c,BLOCKED_MODULE,keys,numkeys,c->bstate.timeout,flags&REDISMODULE_BLOCK_UNBLOCK_DELETED);
} else {
blockClient(c,BLOCKED_MODULE);
}