From 6cc25a78ee7e59ed57e1339c590f1017b2f3b865 Mon Sep 17 00:00:00 2001 From: Taiki Koshino Date: Wed, 2 Sep 2026 18:54:55 +0900 Subject: [PATCH v2] 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. eported-by: Emond Papegaaij Reported-by: Claude code Author: Taiki Koshino 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)); -- 2.52.0