summaryrefslogtreecommitdiff
path: root/tests/modules
diff options
context:
space:
mode:
authorMeir Shpilraien (Spielrein) <meir@redis.com>2022-06-21 10:01:13 +0300
committerGitHub <noreply@github.com>2022-06-21 10:01:13 +0300
commit61baabd8d5cd9178f48b6fad79ae3cb477ef0a11 (patch)
tree87391fd26d89d4dd8d33104a0c9e59773ceb63a3 /tests/modules
parenta3fdc9cd82076ece0796d460a3de0dc60717d21e (diff)
downloadredis-61baabd8d5cd9178f48b6fad79ae3cb477ef0a11.tar.gz
Fix crash on RM_Call with script mode. (#10886)
The PR fixes 2 issues: ### RM_Call crash on script mode `RM_Call` can potentially be called from a background thread where `server.current_client` are not set. In such case we get a crash on `NULL` dereference. The fix is to check first if `server.current_client` is `NULL`, if it does we should verify disc errors and readonly replica as we do to any normal clients (no masters nor AOF). ### RM_Call block OOM commands when not needed Again `RM_Call` can be executed on a background thread using a `ThreadSafeCtx`. In such case `server.pre_command_oom_state` can be irrelevant and should not be considered when check OOM state. This cause OOM commands to be blocked when not necessarily needed. In such case, check the actual used memory (and not the cached value). Notice that in order to know if the cached value can be used, we check that the ctx that was used on the `RM_Call` is a ThreadSafeCtx. Module writer can potentially abuse the API and use ThreadSafeCtx on the main thread. We consider this as a API miss used.
Diffstat (limited to 'tests/modules')
-rw-r--r--tests/modules/blockedclient.c20
1 files changed, 18 insertions, 2 deletions
diff --git a/tests/modules/blockedclient.c b/tests/modules/blockedclient.c
index 9c2598a34..f4234b0d3 100644
--- a/tests/modules/blockedclient.c
+++ b/tests/modules/blockedclient.c
@@ -7,6 +7,7 @@
#include <assert.h>
#include <stdio.h>
#include <pthread.h>
+#include <strings.h>
#define UNUSED(V) ((void) V)
@@ -119,8 +120,20 @@ void *bg_call_worker(void *arg) {
}
// Call the command
- const char* cmd = RedisModule_StringPtrLen(bg->argv[1], NULL);
- RedisModuleCallReply* rep = RedisModule_Call(ctx, cmd, "v", bg->argv + 2, bg->argc - 2);
+ const char *module_cmd = RedisModule_StringPtrLen(bg->argv[0], NULL);
+ int cmd_pos = 1;
+ RedisModuleString *format_redis_str = RedisModule_CreateString(NULL, "v", 1);
+ if (!strcasecmp(module_cmd, "do_bg_rm_call_format")) {
+ cmd_pos = 2;
+ size_t format_len;
+ const char *format = RedisModule_StringPtrLen(bg->argv[1], &format_len);
+ RedisModule_StringAppendBuffer(NULL, format_redis_str, format, format_len);
+ RedisModule_StringAppendBuffer(NULL, format_redis_str, "E", 1);
+ }
+ const char *format = RedisModule_StringPtrLen(format_redis_str, NULL);
+ const char *cmd = RedisModule_StringPtrLen(bg->argv[cmd_pos], NULL);
+ RedisModuleCallReply *rep = RedisModule_Call(ctx, cmd, format, bg->argv + cmd_pos + 1, bg->argc - cmd_pos - 1);
+ RedisModule_FreeString(NULL, format_redis_str);
// Release GIL
RedisModule_ThreadSafeContextUnlock(ctx);
@@ -306,6 +319,9 @@ int RedisModule_OnLoad(RedisModuleCtx *ctx, RedisModuleString **argv, int argc)
if (RedisModule_CreateCommand(ctx, "do_bg_rm_call", do_bg_rm_call, "", 0, 0, 0) == REDISMODULE_ERR)
return REDISMODULE_ERR;
+ if (RedisModule_CreateCommand(ctx, "do_bg_rm_call_format", do_bg_rm_call, "", 0, 0, 0) == REDISMODULE_ERR)
+ return REDISMODULE_ERR;
+
if (RedisModule_CreateCommand(ctx, "do_fake_bg_true", do_fake_bg_true, "", 0, 0, 0) == REDISMODULE_ERR)
return REDISMODULE_ERR;