summaryrefslogtreecommitdiff
path: root/kqueue.c
diff options
context:
space:
mode:
authorTobias Stoeckmann <tobias@stoeckmann.org>2019-05-10 23:54:14 +0200
committerAzat Khuzhin <azat@libevent.org>2019-05-11 11:29:55 +0300
commit2707a4ffabe539999f37a0364f7b0ef44a90589a (patch)
tree0e480cde359447b924d95e6deac4341c4872aca1 /kqueue.c
parentcf8acae36a580935c42228f3d30f3e96c8a3ef59 (diff)
downloadlibevent-2707a4ffabe539999f37a0364f7b0ef44a90589a.tar.gz
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)
Diffstat (limited to 'kqueue.c')
-rw-r--r--kqueue.c9
1 files changed, 6 insertions, 3 deletions
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) {