summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorantirez <antirez@gmail.com>2018-10-30 13:38:41 +0100
committerantirez <antirez@gmail.com>2018-12-11 18:05:47 +0100
commitb6cd3b3c57e95bc574d09391c507855f17a8e41c (patch)
treeabdd4d58ff9fc7b4541c996f719c2c4311874608
parente16402b0c8d29a5caded5013c6b219f19ad4f51b (diff)
downloadredis-b6cd3b3c57e95bc574d09391c507855f17a8e41c.tar.gz
asyncCloseClientOnOutputBufferLimitReached(): don't free fake clients.
Fake clients are used in special situations and are not linked to the normal clients list, freeing them will always result in Redis crashing in one way or the other. It's not common to send replies to fake clients, but we have one usage in the modules API. When a client is blocked, we associate to the blocked client object (that is safe to manipulate in a thread), a fake client that accumulates replies. So because of this bug there was the problem described in issue #5443. The fix was verified to work with the provided example module. To write a regression is very hard and unlikely to be triggered in the future.
-rw-r--r--src/networking.c1
1 files changed, 1 insertions, 0 deletions
diff --git a/src/networking.c b/src/networking.c
index 82c763c95..00f5bab02 100644
--- a/src/networking.c
+++ b/src/networking.c
@@ -1944,6 +1944,7 @@ int checkClientOutputBufferLimits(client *c) {
* called from contexts where the client can't be freed safely, i.e. from the
* lower level functions pushing data inside the client output buffers. */
void asyncCloseClientOnOutputBufferLimitReached(client *c) {
+ if (c->fd == -1) return; /* It is unsafe to free fake clients. */
serverAssert(c->reply_bytes < SIZE_MAX-(1024*64));
if (c->reply_bytes == 0 || c->flags & CLIENT_CLOSE_ASAP) return;
if (checkClientOutputBufferLimits(c)) {