diff options
author | Tobias Stoeckmann <tobias@stoeckmann.org> | 2019-05-10 23:54:14 +0200 |
---|---|---|
committer | Azat Khuzhin <azat@libevent.org> | 2019-05-11 11:29:55 +0300 |
commit | 2707a4ffabe539999f37a0364f7b0ef44a90589a (patch) | |
tree | 0e480cde359447b924d95e6deac4341c4872aca1 /kqueue.c | |
parent | cf8acae36a580935c42228f3d30f3e96c8a3ef59 (diff) | |
download | libevent-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.c | 9 |
1 files changed, 6 insertions, 3 deletions
@@ -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) { |