0001-Fix-WaitEventSetWait-buffer-overrun.patch
text/x-patch
Filename: 0001-Fix-WaitEventSetWait-buffer-overrun.patch
Type: text/x-patch
Part: 0
Patch
Format: format-patch
Series: patch 0001
Subject: Fix WaitEventSetWait() buffer overrun.
| File | + | − |
|---|---|---|
| src/backend/storage/ipc/latch.c | 3 | 2 |
From f3d201a2509affc8248a930f18a58cdb7ed3220f Mon Sep 17 00:00:00 2001 From: Thomas Munro <thomas.munro@gmail.com> Date: Thu, 12 Jan 2023 20:05:38 +1300 Subject: [PATCH] Fix WaitEventSetWait() buffer overrun. The WAIT_USE_EPOLL and WAIT_USE_KQUEUE implementations of WaitEventSetWaitBlock() confused the size of their internal buffer with the size of the caller's output buffer, and could ask the kernel for too many events. In fact the set of events retrieved from the kernel needs to be able to fit in both buffers, so take the minimum of the two. The WAIT_USE_POLL and WAIT_USE WIN32 implementations didn't have this confusion. This probably didn't come up before because we always used the same number in both places, but commit 7389aad6 calculates a dynamic size at construction time, while using MAXLISTEN for its output event buffer on the stack. That seems like a reasonable thing to want to do, so consider this to be a pre-existing bug worth fixing. As reported by skink, valgrind and Tom Lane. Discussion: https://postgr.es/m/901504.1673504836%40sss.pgh.pa.us --- src/backend/storage/ipc/latch.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/backend/storage/ipc/latch.c b/src/backend/storage/ipc/latch.c index a238c5827c..d79d71a851 100644 --- a/src/backend/storage/ipc/latch.c +++ b/src/backend/storage/ipc/latch.c @@ -1525,7 +1525,7 @@ WaitEventSetWaitBlock(WaitEventSet *set, int cur_timeout, /* Sleep */ rc = epoll_wait(set->epoll_fd, set->epoll_ret_events, - nevents, cur_timeout); + Min(nevents, set->nevents_space), cur_timeout); /* Check return code */ if (rc < 0) @@ -1685,7 +1685,8 @@ WaitEventSetWaitBlock(WaitEventSet *set, int cur_timeout, /* Sleep */ rc = kevent(set->kqueue_fd, NULL, 0, - set->kqueue_ret_events, nevents, + set->kqueue_ret_events, + Min(nevents, set->nevents_space), timeout_p); /* Check return code */ -- 2.35.1