diff --git a/evmap.c b/evmap.c index 9f46dd0f..ffc991f5 100644 --- a/evmap.c +++ b/evmap.c @@ -43,6 +43,7 @@ #include #endif #include +#include #include #include #include @@ -207,9 +208,15 @@ evmap_make_space(struct event_signal_map *map, int slot, int msize) int nentries = map->nentries ? map->nentries : 32; void **tmp; + if (slot > INT_MAX / 2) + return (-1); + while (nentries <= slot) nentries <<= 1; + if (nentries > INT_MAX / msize) + return (-1); + tmp = (void **)mm_realloc(map->entries, nentries * msize); if (tmp == NULL) return (-1); @@ -446,6 +453,9 @@ evmap_signal_add_(struct event_base *base, int sig, struct event *ev) struct event_signal_map *map = &base->sigmap; struct evmap_signal *ctx = NULL; + if (sig < 0 || sig >= NSIG) + return (-1); + if (sig >= map->nentries) { if (evmap_make_space( map, sig, sizeof(struct evmap_signal *)) == -1) @@ -472,7 +482,7 @@ evmap_signal_del_(struct event_base *base, int sig, struct event *ev) struct event_signal_map *map = &base->sigmap; struct evmap_signal *ctx; - if (sig >= map->nentries) + if (sig < 0 || sig >= map->nentries) return (-1); GET_SIGNAL_SLOT(ctx, map, sig, evmap_signal); diff --git a/test/regress.c b/test/regress.c index 02380c01..0ebadcb9 100644 --- a/test/regress.c +++ b/test/regress.c @@ -46,6 +46,7 @@ #ifndef _WIN32 #include #include +#include #include #include #include @@ -3303,6 +3304,46 @@ tabf_cb(evutil_socket_t fd, short what, void *arg) *ptr += 0x10000; } +static void +test_evmap_invalid_slots(void *arg) +{ + struct basic_test_data *data = arg; + struct event_base *base = data->base; + struct event *ev1 = NULL, *ev2 = NULL; + int e1, e2; +#ifndef _WIN32 + struct event *ev3 = NULL, *ev4 = NULL; + int e3, e4; +#endif + + ev1 = evsignal_new(base, -1, dummy_read_cb, (void *)base); + ev2 = evsignal_new(base, NSIG, dummy_read_cb, (void *)base); + tt_assert(ev1); + tt_assert(ev2); + e1 = event_add(ev1, NULL); + e2 = event_add(ev2, NULL); + tt_int_op(e1, !=, 0); + tt_int_op(e2, !=, 0); +#ifndef _WIN32 + ev3 = event_new(base, INT_MAX, EV_READ, dummy_read_cb, (void *)base); + ev4 = event_new(base, INT_MAX / 2, EV_READ, dummy_read_cb, (void *)base); + tt_assert(ev3); + tt_assert(ev4); + e3 = event_add(ev3, NULL); + e4 = event_add(ev4, NULL); + tt_int_op(e3, !=, 0); + tt_int_op(e4, !=, 0); +#endif + +end: + event_free(ev1); + event_free(ev2); +#ifndef _WIN32 + event_free(ev3); + event_free(ev4); +#endif +} + static void test_active_by_fd(void *arg) { @@ -3402,6 +3443,7 @@ struct testcase_t main_testcases[] = { BASIC(event_assign_selfarg, TT_FORK|TT_NEED_BASE), BASIC(event_base_get_num_events, TT_FORK|TT_NEED_BASE), BASIC(event_base_get_max_events, TT_FORK|TT_NEED_BASE), + BASIC(evmap_invalid_slots, TT_FORK|TT_NEED_BASE), BASIC(bad_assign, TT_FORK|TT_NEED_BASE|TT_NO_LOGS), BASIC(bad_reentrant, TT_FORK|TT_NEED_BASE|TT_NO_LOGS),