diff options
author | uriyage <78144248+uriyage@users.noreply.github.com> | 2022-11-15 00:40:35 +0200 |
---|---|---|
committer | Oran Agra <oran@redislabs.com> | 2022-12-12 17:02:54 +0200 |
commit | 39e5a6fa2f44ccec70511517a94199e37d6c9f5d (patch) | |
tree | a7f2a0f28f015c5931a30e7341fb31c7ec16d8ad | |
parent | 4ac3d79bfca46d5d2917843085c3b7949e94c423 (diff) | |
download | redis-39e5a6fa2f44ccec70511517a94199e37d6c9f5d.tar.gz |
Module CLIENT_CHANGE, Fix crash on free blocked client with DB!=0 (#11500)
In moduleFireServerEvent we change the real client DB to 0 on freeClient in case the event is REDISMODULE_EVENT_CLIENT_CHANGE.
It results in a crash if the client is blocked on a key on other than DB 0.
The DB change is not necessary even for module-client, as we set its DB to 0 on either createClient or moduleReleaseTempClient.
Co-authored-by: Madelyn Olson <34459052+madolson@users.noreply.github.com>
Co-authored-by: Binbin <binloveplay1314@qq.com>
Co-authored-by: Oran Agra <oran@redislabs.com>
(cherry picked from commit e4eb18b303d716aeebc4153176a6cd93b8bd5d66)
-rw-r--r-- | src/module.c | 3 | ||||
-rw-r--r-- | tests/unit/moduleapi/hooks.tcl | 13 |
2 files changed, 15 insertions, 1 deletions
diff --git a/src/module.c b/src/module.c index e943b5742..f6c51b2a5 100644 --- a/src/module.c +++ b/src/module.c @@ -8321,7 +8321,8 @@ void moduleFireServerEvent(uint64_t eid, int subid, void *data) { * up to the specific event setup to change it when it makes * sense. For instance for FLUSHDB events we select the correct * DB automatically. */ - selectDb(ctx.client, 0); + if (!real_client_used) + selectDb(ctx.client, 0); /* Event specific context and data pointer setup. */ if (eid == REDISMODULE_EVENT_CLIENT_CHANGE) { diff --git a/tests/unit/moduleapi/hooks.tcl b/tests/unit/moduleapi/hooks.tcl index c4af59bd2..4e1103a61 100644 --- a/tests/unit/moduleapi/hooks.tcl +++ b/tests/unit/moduleapi/hooks.tcl @@ -12,6 +12,19 @@ tags "modules" { assert {[r hooks.event_count client-disconnected] > 1} } + test {Test module client change event for blocked client} { + set rd [redis_deferring_client] + # select db other than 0 + $rd select 1 + # block on key + $rd brpop foo 0 + # kill blocked client + r client kill skipme yes + # assert server is still up + assert_equal [r ping] PONG + $rd close + } + test {Test module cron hook} { after 100 assert {[r hooks.event_count cron-loop] > 0} |