pgpool2.git / summary / log / commit / refs
commit 570fccdd677efb866a449c1b159aafbe960a5e6c
Author: Taiki Koshino <koshio@sraoss.co.jp>
Date: Wed Sep 16 07:29:55 2026 +0000
Fix unsigned underflow in inject_cached_message
This patch modifies the packet length validation in inject_cached_message to prevent
a session crash caused by an unsigned integer underflow.
Previously, the logic determined whether to process a query cache message by checking
if the packet length minus its header size was greater than zero(if ((ntohl(len) - sizeof(len)) > 0)).
However, this evaluation method introduced a critical vulnerability under unsigned arithmetic rules.
When a corrupt packet with a payload length shorter than the header size is processed,
the subtraction underflows into a massive positive integer,
bypassing the guard and forcing a fatal memory allocation failure that terminates the session.
In our local test environment, injecting a short packet successfully reproduced this exact behavior,
causing a memory context allocation crash.
The updated logic changes the condition to a direct comparison
before subtraction(if (ntohl(len) > (uint32) sizeof(len))),
ensuring that invalid short packets are securely blocked and the session remains stable,
which proves the fix is highly valid.
Reported-by: Emond Papegaaij <emond.papegaaij@gmail.com>
Reported-by: Claude code
Author: Taiki Koshino <koshino@sraoss.co.jp>
Discussion: https://www.postgresql.org/message-id/TY4PR01MB17374089B6E89C4B9F44817B094C22%40TY4PR01MB17374.jpnprd01.prod.outlook.com
Backpatch-through: v4.3
src/query_cache/pool_memqcache.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/query_cache/pool_memqcache.c b/src/query_cache/pool_memqcache.c
index bdd89eacc..b86977b63 100644
--- a/src/query_cache/pool_memqcache.c
+++ b/src/query_cache/pool_memqcache.c
@@ -4770,7 +4770,7 @@ inject_cached_message(POOL_CONNECTION *backend, char *qcache, int qcachelen)
pool_push(backend, &kind, sizeof(kind));
pool_read(backend, &len, sizeof(len));
pool_push(backend, &len, sizeof(len));
- if ((ntohl(len) - sizeof(len)) > 0)
+ if (ntohl(len) > (uint32) sizeof(len))
{
buf = pool_read2(backend, ntohl(len) - sizeof(len));
pool_push(backend, buf, ntohl(len) - sizeof(len));