CVE-2022-48620 (published 2024-01-12T04:15Z)

uev (aka libuev) before 2.4.1 has a buffer overflow in epoll_wait if maxevents is a large number.

CVSS v3 base score: 9.8, CRITICAL (CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H)

Weakness information:
cwe_id: CWE-120
cwe_name: Buffer Copy without Checking Size of Input ('Classic Buffer Overflow')
description: The product copies an input buffer to an output buffer without verifying that the size of the input buffer is less than the size of the output buffer, leading to a buffer overflow.
extended_description: A buffer overflow condition exists when a product attempts to put more data in a buffer than it can hold, or when it attempts to put data in a memory area outside of the boundaries of a buffer. The simplest type of error, and the most common cause of buffer overflows, is the "classic" case in which the product copies the buffer without restricting how much is copied. Other variants exist, but the existence of a classic overflow strongly suggests that the programmer is not considering even the most basic of security protections.
         

Fix information:
repo_url: https://github.com/troglobit/libuev
commit_details: repo_url: https://github.com/troglobit/libuev
author: Joachim Wiberg
author_date: 2022-12-17 15:02:21+01:00
msg: 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 <troglobit@gmail.com>
repository: repo_url: https://github.com/troglobit/libuev
repo_name: troglobit/libuev
description: Lightweight event loop library for Linux epoll() family APIs
repo_language: C
owner: troglobit
file_changes: filename: uev.c
change_type: ModificationType.MODIFY
diff: @@ -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;
 

programming_language: C