From 03e71efcc513c9f13eb25b693b011b43f1f4a2d3 Mon Sep 17 00:00:00 2001 From: Simon Tatham Date: Wed, 4 May 2022 12:46:06 +0100 Subject: [PATCH] Fix linked-list mismanagement in global request queue. When we linked a new entry on to the global request queue, we forgot to set its next pointer to NULL, so that when it was removed again, s->globreq_head could end up pointing to nonsense. In addition, even if the next pointer happened to be NULL by luck, we also did not notice that s->globreq_head had become NULL and respond by nulling out s->globreq_tail, which would leave s->globreq_tail as a stale pointer to the just-freed list element, causing a memory access error on the next attempt to link something on to the list. This could come up in the situation where you open Change Settings and configure a remote port forwarding, close it (so that the global request is sent, queued, replied to, and unqueued again), and then reopen Change Settings and configure a second one (so that the linked list in the confused state actually gets used). --- ssh/connection2.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/ssh/connection2.c b/ssh/connection2.c index fb24b7c6..ec330927 100644 --- a/ssh/connection2.c +++ b/ssh/connection2.c @@ -178,6 +178,7 @@ void ssh2_queue_global_request_handler( snew(struct outstanding_global_request); ogr->handler = handler; ogr->ctx = ctx; + ogr->next = NULL; if (s->globreq_tail) s->globreq_tail->next = ogr; else @@ -372,6 +373,8 @@ static bool ssh2_connection_filter_queue(struct ssh2_connection_state *s) s->globreq_head = s->globreq_head->next; sfree(tmp); } + if (!s->globreq_head) + s->globreq_tail = NULL; pq_pop(s->ppl.in_pq); break;