From: Tobias Stoeckmann <tobias@stoeckmann.org>
Date: Fri, 10 May 2019 21:54:14 +0000 (+0200)
Subject: kqueue: Avoid undefined behaviour.
X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=2707a4ffabe539999f37a0364f7b0ef44a90589a;p=libevent

kqueue: Avoid undefined behaviour.

As ploxiln pointed out in pull request 811 the check "newsize < 0"
is undefined behaviour (signed int overflow).

Follow the advice and check kqop->changes_size instead.

Signed-off-by: Tobias Stoeckmann <tobias@stoeckmann.org>
Closes: #813 (cherry-picked)
---

diff --git a/kqueue.c b/kqueue.c
index 9a249511..d08f512c 100644
--- a/kqueue.c
+++ b/kqueue.c
@@ -37,6 +37,7 @@
 #endif
 #include <sys/queue.h>
 #include <sys/event.h>
+#include <limits.h>
 #include <signal.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -208,15 +209,17 @@ kq_build_changes_list(const struct event_changelist *changelist,
 		struct event_change *in_ch = &changelist->changes[i];
 		struct kevent *out_ch;
 		if (n_changes >= kqop->changes_size - 1) {
-			int newsize = kqop->changes_size * 2;
+			int newsize;
 			struct kevent *newchanges;
 
-			if (newsize < 0 || (size_t)newsize >
-			    EV_SIZE_MAX / sizeof(struct kevent)) {
+			if (kqop->changes_size > INT_MAX / 2 ||
+			    (size_t)kqop->changes_size * 2 > EV_SIZE_MAX /
+			    sizeof(struct kevent)) {
 				event_warnx("%s: int overflow", __func__);
 				return (-1);
 			}
 
+			newsize = kqop->changes_size * 2;
 			newchanges = mm_realloc(kqop->changes,
 			    newsize * sizeof(struct kevent));
 			if (newchanges == NULL) {