advance_tcp_send_queue: avoid NULL ptr dereference
authorDaniel Stenberg <daniel@haxx.se>
Mon, 27 Dec 2010 12:10:48 +0000 (13:10 +0100)
committerDaniel Stenberg <daniel@haxx.se>
Mon, 27 Dec 2010 12:10:48 +0000 (13:10 +0100)
If given a too large 'num_bytes' value, it would cause a NULL ptr
dereference. Instead the code will now break out of the loop at the end
of the list.

ares_process.c

index 7d04eff..ca4c8ee 100644 (file)
@@ -300,29 +300,28 @@ static void advance_tcp_send_queue(ares_channel channel, int whichserver,
 {
   struct send_request *sendreq;
   struct server_state *server = &channel->servers[whichserver];
-  while (num_bytes > 0)
-    {
-      sendreq = server->qhead;
-      if ((size_t)num_bytes >= sendreq->len)
-       {
-         num_bytes -= sendreq->len;
-         server->qhead = sendreq->next;
-         if (server->qhead == NULL)
-           {
-             SOCK_STATE_CALLBACK(channel, server->tcp_socket, 1, 0);
-             server->qtail = NULL;
-           }
-         if (sendreq->data_storage != NULL)
-           free(sendreq->data_storage);
-         free(sendreq);
-       }
-      else
-       {
-         sendreq->data += num_bytes;
-         sendreq->len -= num_bytes;
-         num_bytes = 0;
-       }
+  while (num_bytes > 0) {
+    sendreq = server->qhead;
+    if ((size_t)num_bytes >= sendreq->len) {
+      num_bytes -= sendreq->len;
+      server->qhead = sendreq->next;
+      if (sendreq->data_storage)
+        free(sendreq->data_storage);
+      free(sendreq);
+      if (server->qhead == NULL) {
+        SOCK_STATE_CALLBACK(channel, server->tcp_socket, 1, 0);
+        server->qtail = NULL;
+
+        /* qhead is NULL so we cannot continue this loop */
+        break;
+      }
+    }
+    else {
+      sendreq->data += num_bytes;
+      sendreq->len -= num_bytes;
+      num_bytes = 0;
     }
+  }
 }
 
 /* If any TCP socket selects true for reading, read some data,