From 2d9f1c9ce655cc38511aeeb6e95ac30914f7aec9 Mon Sep 17 00:00:00 2001 From: Joachim Wiberg Date: Sat, 17 Dec 2022 15:02:21 +0100 Subject: [PATCH] Fix #27: possible buffer overrun in uev_run() If uev_init1() is called with maxevents > 10 the call to epoll_wait() might cause buffer overflow. Reported by Steve Palmer. Signed-off-by: Joachim Wiberg --- src/uev.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/src/uev.c b/src/uev.c index 10d025f..548866a 100644 --- a/src/uev.c +++ b/src/uev.c @@ -196,11 +196,11 @@ int uev_init(uev_ctx_t *ctx) /** * Create an event loop context * @param ctx Pointer to an uev_ctx_t context to be initialized - * @param maxevents Maximum number of events in event cache + * @param maxevents Maximum number of events in event cache [1, 10] * * This function is the same as uev_init() except for the @p maxevents - * argument, which controls the number of events in the event cache - * returned to the main loop. + * argument, max ::UEV_MAX_EVENTS, which controls the number of events + * in the event cache returned to the main loop. * * In cases where you have multiple events pending in the cache and some * event may cause later ones, already sent by the kernel to userspace, @@ -222,6 +222,9 @@ int uev_init1(uev_ctx_t *ctx, int maxevents) return -1; } + if (maxevents > UEV_MAX_EVENTS) + maxevents = UEV_MAX_EVENTS; + memset(ctx, 0, sizeof(*ctx)); ctx->maxevents = maxevents; @@ -319,8 +322,12 @@ int uev_run(uev_ctx_t *ctx, int flags) while (ctx->running && ctx->watchers) { struct epoll_event ee[UEV_MAX_EVENTS]; + int maxevents = ctx->maxevents; int i, nfds, rerun = 0; + if (maxevents > UEV_MAX_EVENTS) + maxevents = UEV_MAX_EVENTS; + /* Handle special case: `application < file.txt` */ if (ctx->workaround) { _UEV_FOREACH(w, ctx->watchers) { @@ -341,7 +348,7 @@ int uev_run(uev_ctx_t *ctx, int flags) continue; ctx->workaround = 0; - while ((nfds = epoll_wait(ctx->fd, ee, ctx->maxevents, timeout)) < 0) { + while ((nfds = epoll_wait(ctx->fd, ee, maxevents, timeout)) < 0) { if (!ctx->running) break;