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));