CVE-2020-14397: NULL Pointer Dereference (CWE-476)
value: An issue was discovered in LibVNCServer before 0.9.13. libvncserver/rfbregion.c has a NULL pointer dereference.
CWE description: The product dereferences a pointer that it expects to be valid but is NULL.
CVSS v3 base score: 7.5
Published: 2020-06-17T16:15Z
Repository: https://github.com/LibVNC/libvncserver
Language: C
Files changed: libvncserver/rfbregion.c, libvncserver/rfbserver.c
Commit date: 2020-05-28 08:40:09 +0200
Commit message: libvncserver: add missing NULL pointer checks

Diff: diff --git a/libvncserver/rfbregion.c b/libvncserver/rfbregion.c
index 9fb4f1707..1b470e222 100644
--- a/libvncserver/rfbregion.c
+++ b/libvncserver/rfbregion.c
@@ -49,28 +49,34 @@ sraSpanDup(const sraSpan *src) {
   return span;
 }
 
 static void
 sraSpanInsertAfter(sraSpan *newspan, sraSpan *after) {
-  newspan->_next = after->_next;
-  newspan->_prev = after;
-  after->_next->_prev = newspan;
-  after->_next = newspan;
+  if(newspan && after) {
+    newspan->_next = after->_next;
+    newspan->_prev = after;
+    after->_next->_prev = newspan;
+    after->_next = newspan;
+  }
 }
 
 static void
 sraSpanInsertBefore(sraSpan *newspan, sraSpan *before) {
-  newspan->_next = before;
-  newspan->_prev = before->_prev;
-  before->_prev->_next = newspan;
-  before->_prev = newspan;
+  if(newspan && before) {
+    newspan->_next = before;
+    newspan->_prev = before->_prev;
+    before->_prev->_next = newspan;
+    before->_prev = newspan;
+  }
 }
 
 static void
 sraSpanRemove(sraSpan *span) {
-  span->_prev->_next = span->_next;
-  span->_next->_prev = span->_prev;
+  if(span) {
+    span->_prev->_next = span->_next;
+    span->_next->_prev = span->_prev;
+  }
 }
 
 static void
 sraSpanDestroy(sraSpan *span) {
   if (span->subspan) sraSpanListDestroy(span->subspan);
diff --git a/libvncserver/rfbserver.c b/libvncserver/rfbserver.c
index b256b3a30..9d70eb954 100644
--- a/libvncserver/rfbserver.c
+++ b/libvncserver/rfbserver.c
@@ -205,10 +205,12 @@ rfbClientIteratorHead(rfbClientIteratorPtr i)
 }
 
 rfbClientPtr
 rfbClientIteratorNext(rfbClientIteratorPtr i)
 {
+  if (!i)
+    return NULL;
   if(i->next == 0) {
     LOCK(rfbClientListMutex);
     i->next = i->screen->clientHead;
     UNLOCK(rfbClientListMutex);
   } else {
@@ -229,11 +231,11 @@ rfbClientIteratorNext(rfbClientIteratorPtr i)
 }
 
 void
 rfbReleaseClientIterator(rfbClientIteratorPtr iterator)
 {
-  if(iterator->next) rfbDecrClientRef(iterator->next);
+  if(iterator && iterator->next) rfbDecrClientRef(iterator->next);
   free(iterator);
 }
 
 
 /*

Vulnerable code:   newspan->_next = after->_next;
  newspan->_prev = after;
  after->_next->_prev = newspan;
  after->_next = newspan;
  newspan->_next = before;
  newspan->_prev = before->_prev;
  before->_prev->_next = newspan;
  before->_prev = newspan;
  span->_prev->_next = span->_next;
  span->_next->_prev = span->_prev;
  if(iterator->next) rfbDecrClientRef(iterator->next);
Fixed code:   if(newspan && after) {
    newspan->_next = after->_next;
    newspan->_prev = after;
    after->_next->_prev = newspan;
    after->_next = newspan;
  }
  if(newspan && before) {
    newspan->_next = before;
    newspan->_prev = before->_prev;
    before->_prev->_next = newspan;
    before->_prev = newspan;
  }
  if(span) {
    span->_prev->_next = span->_next;
    span->_next->_prev = span->_prev;
  }
  if (!i)
    return NULL;
  if(iterator && iterator->next) rfbDecrClientRef(iterator->next);