From 4ae5bd7a0b30f185da4a886d5c3b72e3804c34db Mon Sep 17 00:00:00 2001 From: 14067 Date: Wed, 31 Dec 2025 10:56:02 +0800 Subject: [PATCH 1/2] =?UTF-8?q?The=20iterator=20logic=20in=20LibVNCServer?= =?UTF-8?q?=20follows=20a=20"take-and-release"=20pattern.=20rfbClientItera?= =?UTF-8?q?torNext=20decrements=20the=20reference=20of=20the=20current=20n?= =?UTF-8?q?ode=20and=20increments=20the=20next=20one.=20However,=20rfbClie?= =?UTF-8?q?ntIteratorHead=20was=20only=20performing=20a=20decrement=20on?= =?UTF-8?q?=20the=20existing=20i->next,=20but=20not=20performing=20an=20in?= =?UTF-8?q?crement=20when=20setting=20the=20new=20i->next=20from=20screen-?= =?UTF-8?q?>clientHead.=20=EF=BB=BF=20This=20led=20to=20a=20negative=20ref?= =?UTF-8?q?Count=20(e.g.,=20-1,=20-2,=20-3)=20because=20the=20subsequent?= =?UTF-8?q?=20call=20to=20rfbClientIteratorNext=20in=20rfbProcessEvents=20?= =?UTF-8?q?would=20attempt=20to=20decrement=20a=20reference=20that=20was?= =?UTF-8?q?=20never=20legally=20"taken."?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit rfbProcessEvents cl = rfbClientIteratorHead(i) ----i->next=i->screen->clientHead; while(cl) { cl=rfbClientIteratorNext(i); -----i->next !=0 ----->rfbDecrClientRef(cl); } Signed-off-by: 14067 --- src/libvncserver/rfbserver.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/libvncserver/rfbserver.c b/src/libvncserver/rfbserver.c index ccc09a77..c26be7c1 100644 --- a/src/libvncserver/rfbserver.c +++ b/src/libvncserver/rfbserver.c @@ -201,6 +201,15 @@ rfbClientIteratorHead(rfbClientIteratorPtr i) LOCK(rfbClientListMutex); i->next = i->screen->clientHead; UNLOCK(rfbClientListMutex); + +#if defined(LIBVNCSERVER_HAVE_LIBPTHREAD) || defined(LIBVNCSERVER_HAVE_WIN32THREADS) + if(!i->closedToo) + while(i->next && i->next->sock<0) + i->next = i->next->next; + if(i->next) + rfbIncrClientRef(i->next); +#endif + return i->next; } From 8c7d40c3e17354f74a2072b51a4789c2245e296f Mon Sep 17 00:00:00 2001 From: 14067 Date: Wed, 31 Dec 2025 10:56:02 +0800 Subject: [PATCH 2/2] =?UTF-8?q?The=20iterator=20logic=20in=20LibVNCServer?= =?UTF-8?q?=20follows=20a=20"take-and-release"=20pattern.=20rfbClientItera?= =?UTF-8?q?torNext=20decrements=20the=20reference=20of=20the=20current=20n?= =?UTF-8?q?ode=20and=20increments=20the=20next=20one.=20However,=20rfbClie?= =?UTF-8?q?ntIteratorHead=20was=20only=20performing=20a=20decrement=20on?= =?UTF-8?q?=20the=20existing=20i->next,=20but=20not=20performing=20an=20in?= =?UTF-8?q?crement=20when=20setting=20the=20new=20i->next=20from=20screen-?= =?UTF-8?q?>clientHead.=20=EF=BB=BF=20This=20led=20to=20a=20negative=20ref?= =?UTF-8?q?Count=20(e.g.,=20-1,=20-2,=20-3)=20because=20the=20subsequent?= =?UTF-8?q?=20call=20to=20rfbClientIteratorNext=20in=20rfbProcessEvents=20?= =?UTF-8?q?would=20attempt=20to=20decrement=20a=20reference=20that=20was?= =?UTF-8?q?=20never=20legally=20"taken."?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit rfbProcessEvents cl = rfbClientIteratorHead(i) ----i->next=i->screen->clientHead; while(cl) { cl=rfbClientIteratorNext(i); -----i->next !=0 ----->rfbDecrClientRef(cl); } Signed-off-by: 14067 --- src/libvncserver/rfbserver.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/libvncserver/rfbserver.c b/src/libvncserver/rfbserver.c index ccc09a77..d843f694 100644 --- a/src/libvncserver/rfbserver.c +++ b/src/libvncserver/rfbserver.c @@ -197,6 +197,8 @@ rfbClientIteratorHead(rfbClientIteratorPtr i) rfbDecrClientRef(i->next); rfbIncrClientRef(i->screen->clientHead); } + else + rfbIncrClientRef(i->screen->clientHead); #endif LOCK(rfbClientListMutex); i->next = i->screen->clientHead;