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)
This commit is contained in:
Tobias Stoeckmann 2019-05-10 23:54:14 +02:00 committed by Azat Khuzhin
parent cf8acae36a
commit 2707a4ffab
No known key found for this signature in database
GPG Key ID: B86086848EF8686D

View File

@ -37,6 +37,7 @@
#endif #endif
#include <sys/queue.h> #include <sys/queue.h>
#include <sys/event.h> #include <sys/event.h>
#include <limits.h>
#include <signal.h> #include <signal.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.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 event_change *in_ch = &changelist->changes[i];
struct kevent *out_ch; struct kevent *out_ch;
if (n_changes >= kqop->changes_size - 1) { if (n_changes >= kqop->changes_size - 1) {
int newsize = kqop->changes_size * 2; int newsize;
struct kevent *newchanges; struct kevent *newchanges;
if (newsize < 0 || (size_t)newsize > if (kqop->changes_size > INT_MAX / 2 ||
EV_SIZE_MAX / sizeof(struct kevent)) { (size_t)kqop->changes_size * 2 > EV_SIZE_MAX /
sizeof(struct kevent)) {
event_warnx("%s: int overflow", __func__); event_warnx("%s: int overflow", __func__);
return (-1); return (-1);
} }
newsize = kqop->changes_size * 2;
newchanges = mm_realloc(kqop->changes, newchanges = mm_realloc(kqop->changes,
newsize * sizeof(struct kevent)); newsize * sizeof(struct kevent));
if (newchanges == NULL) { if (newchanges == NULL) {