This patch avoids a possible integer overflow on excessively large
amount of events added to an event base in kqueue mode (default).

Just as with previous changes, this is very unlikely to trigger and
is a just a defensive measure.

Changes in this diff:

* KNF (sorted imports and added limits.h for INT_MAX)
* recallocarray instead of reallocarray, in sync with minheap change
* adjusted error messages from malloc to recallocarray

Okay?


Tobias

Index: kqueue.c
===================================================================
RCS file: /cvs/src/lib/libevent/kqueue.c,v
retrieving revision 1.40
diff -u -p -u -p -r1.40 kqueue.c
--- kqueue.c    10 Jul 2017 21:37:26 -0000      1.40
+++ kqueue.c    7 May 2019 19:49:53 -0000
@@ -32,14 +32,15 @@
 #include <sys/queue.h>
 #include <sys/event.h>
 
+#include <assert.h>
+#include <errno.h>
+#include <inttypes.h>
+#include <limits.h>
 #include <signal.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
-#include <errno.h>
-#include <assert.h>
-#include <inttypes.h>
 
 #include "event.h"
 #include "event-internal.h"
@@ -133,25 +134,29 @@ kq_insert(struct kqop *kqop, struct keve
                struct kevent *newchange;
                struct kevent *newresult;
 
+               if (nevents > INT_MAX / 2) {
+                       event_warnx("%s: integer overflow", __func__);
+                       return (-1);
+               }
                nevents *= 2;
 
-               newchange = reallocarray(kqop->changes,
-                   nevents, sizeof(struct kevent));
+               newchange = recallocarray(kqop->changes,
+                   kqop->nevents, nevents, sizeof(struct kevent));
                if (newchange == NULL) {
-                       event_warn("%s: malloc", __func__);
+                       event_warn("%s: recallocarray", __func__);
                        return (-1);
                }
                kqop->changes = newchange;
 
-               newresult = reallocarray(kqop->events,
-                   nevents, sizeof(struct kevent));
+               newresult = recallocarray(kqop->events,
+                   kqop->nevents, nevents, sizeof(struct kevent));
 
                /*
                 * If we fail, we don't have to worry about freeing,
                 * the next realloc will pick it up.
                 */
                if (newresult == NULL) {
-                       event_warn("%s: malloc", __func__);
+                       event_warn("%s: recallocarray", __func__);
                        return (-1);
                }
                kqop->events = newresult;

Reply via email to