Unverified Commit 71e6abe4 authored by Shaya Potter's avatar Shaya Potter Committed by GitHub
Browse files

Fix memory leak when RM_Call's RUN_AS_USER fails (#12158)

previously the argv wasn't freed so would leak.  not a common case, but should be handled.

Solution: move RUN_AS_USER setup and error exit to the right place.
this way, when we do `goto cleanup` (instead of return) it'll automatically do the right thing (including autoMemoryAdd)
Removed the user argument from moduleAllocTempClient (reverted to the state before 6e993a5d

)
Co-authored-by: default avatarOran Agra <oran@redislabs.com>
parent 006ab26c
......@@ -620,7 +620,7 @@ void *RM_PoolAlloc(RedisModuleCtx *ctx, size_t bytes) {
* Helpers for modules API implementation
* -------------------------------------------------------------------------- */
 
client *moduleAllocTempClient(user *user) {
client *moduleAllocTempClient(void) {
client *c = NULL;
 
if (moduleTempClientCount > 0) {
......@@ -630,10 +630,8 @@ client *moduleAllocTempClient(user *user) {
} else {
c = createClient(NULL);
c->flags |= CLIENT_MODULE;
c->user = NULL; /* Root user */
}
c->user = user;
return c;
}
 
......@@ -879,7 +877,7 @@ void moduleCreateContext(RedisModuleCtx *out_ctx, RedisModule *module, int ctx_f
out_ctx->module = module;
out_ctx->flags = ctx_flags;
if (ctx_flags & REDISMODULE_CTX_TEMP_CLIENT)
out_ctx->client = moduleAllocTempClient(NULL);
out_ctx->client = moduleAllocTempClient();
else if (ctx_flags & REDISMODULE_CTX_NEW_CLIENT)
out_ctx->client = createClient(NULL);
 
......@@ -6215,20 +6213,7 @@ RedisModuleCallReply *RM_Call(RedisModuleCtx *ctx, const char *cmdname, const ch
error_as_call_replies = flags & REDISMODULE_ARGV_CALL_REPLIES_AS_ERRORS;
va_end(ap);
 
user *user = NULL;
if (flags & REDISMODULE_ARGV_RUN_AS_USER) {
user = ctx->user ? ctx->user->user : ctx->client->user;
if (!user) {
errno = ENOTSUP;
if (error_as_call_replies) {
sds msg = sdsnew("cannot run as user, no user directly attached to context or context's client");
reply = callReplyCreateError(msg, ctx);
}
return reply;
}
}
c = moduleAllocTempClient(user);
c = moduleAllocTempClient();
 
if (!(flags & REDISMODULE_ARGV_ALLOW_BLOCK)) {
/* We do not want to allow block, the module do not expect it */
......@@ -6248,6 +6233,20 @@ RedisModuleCallReply *RM_Call(RedisModuleCtx *ctx, const char *cmdname, const ch
}
if (ctx->module) ctx->module->in_call++;
 
user *user = NULL;
if (flags & REDISMODULE_ARGV_RUN_AS_USER) {
user = ctx->user ? ctx->user->user : ctx->client->user;
if (!user) {
errno = ENOTSUP;
if (error_as_call_replies) {
sds msg = sdsnew("cannot run as user, no user directly attached to context or context's client");
reply = callReplyCreateError(msg, ctx);
}
goto cleanup;
}
c->user = user;
}
/* We handle the above format error only when the client is setup so that
* we can free it normally. */
if (argv == NULL) {
......@@ -7680,8 +7679,8 @@ RedisModuleBlockedClient *moduleBlockClient(RedisModuleCtx *ctx, RedisModuleCmdF
bc->disconnect_callback = NULL; /* Set by RM_SetDisconnectCallback() */
bc->free_privdata = free_privdata;
bc->privdata = privdata;
bc->reply_client = moduleAllocTempClient(NULL);
bc->thread_safe_ctx_client = moduleAllocTempClient(NULL);
bc->reply_client = moduleAllocTempClient();
bc->thread_safe_ctx_client = moduleAllocTempClient();
if (bc->client)
bc->reply_client->resp = bc->client->resp;
bc->dbid = c->db->id;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment