BUG #17855: Uninitialised memory used when the name type value processed in binary mode of Memoize - Mailing list pgsql-bugs

From PG Bug reporting form
Subject BUG #17855: Uninitialised memory used when the name type value processed in binary mode of Memoize
Date
Msg-id 17855-5f523e0f9769a566@postgresql.org
Whole thread Raw
Responses Re: BUG #17855: Uninitialised memory used when the name type value processed in binary mode of Memoize  (David Rowley <dgrowleyml@gmail.com>)
List pgsql-bugs
The following bug has been logged on the website:

Bug reference:      17855
Logged by:          Alexander Lakhin
Email address:      exclusion@gmail.com
PostgreSQL version: 15.2
Operating system:   Ubuntu 22.04
Description:

When the following query executed under valgrind:
SET enable_seqscan TO off;

CREATE TABLE t (n name);
INSERT INTO t VALUES('name'), ('name');
CREATE INDEX t_idx ON t(n);
ANALYZE t;

SELECT COUNT(*) FROM t t1 INNER JOIN t t2 ON t1.n >= t2.n;

An incorrect memory access detected:
==00:00:00:06.975 2318810== Use of uninitialised value of size 8
==00:00:00:06.975 2318810==    at 0x4348B9: memoize_insert_hash_internal
(simplehash.h:633)
==00:00:00:06.975 2318810==    by 0x43515F: memoize_insert
(simplehash.h:763)
==00:00:00:06.975 2318810==    by 0x43515F: cache_lookup
(nodeMemoize.c:519)
==00:00:00:06.975 2318810==    by 0x435832: ExecMemoize
(nodeMemoize.c:705)
==00:00:00:06.975 2318810==    by 0x40EA14: ExecProcNodeFirst
(execProcnode.c:464)
==00:00:00:06.975 2318810==    by 0x43F32B: ExecProcNode (executor.h:259)
==00:00:00:06.975 2318810==    by 0x43F32B: ExecNestLoop
(nodeNestloop.c:160)
==00:00:00:06.975 2318810==    by 0x40EA14: ExecProcNodeFirst
(execProcnode.c:464)
==00:00:00:06.975 2318810==    by 0x41A9BF: ExecProcNode (executor.h:259)
==00:00:00:06.975 2318810==    by 0x41A9BF: fetch_input_tuple
(nodeAgg.c:563)
==00:00:00:06.975 2318810==    by 0x41E2D4: agg_retrieve_direct
(nodeAgg.c:2346)
==00:00:00:06.975 2318810==    by 0x41E5AA: ExecAgg (nodeAgg.c:2161)
==00:00:00:06.975 2318810==    by 0x40EA14: ExecProcNodeFirst
(execProcnode.c:464)
==00:00:00:06.975 2318810==    by 0x407008: ExecProcNode (executor.h:259)
==00:00:00:06.975 2318810==    by 0x407008: ExecutePlan (execMain.c:1636)
==00:00:00:06.975 2318810==    by 0x4071E8: standard_ExecutorRun
(execMain.c:363)
==00:00:00:06.975 2318810==  Uninitialised value was created by a heap
allocation
==00:00:00:06.975 2318810==    at 0x74394C: palloc (mcxt.c:1093)
==00:00:00:06.975 2318810==    by 0x262F07: btrescan (nbtree.c:427)
==00:00:00:06.975 2318810==    by 0x2511F6: index_rescan (indexam.c:314)
==00:00:00:06.975 2318810==    by 0x42F4E7: IndexOnlyNext
(nodeIndexonlyscan.c:111)
==00:00:00:06.975 2318810==    by 0x411CCD: ExecScanFetch (execScan.c:133)
==00:00:00:06.975 2318810==    by 0x411D68: ExecScan (execScan.c:182)
==00:00:00:06.975 2318810==    by 0x42F25F: ExecIndexOnlyScan
(nodeIndexonlyscan.c:315)
==00:00:00:06.975 2318810==    by 0x40EA14: ExecProcNodeFirst
(execProcnode.c:464)
==00:00:00:06.975 2318810==    by 0x43EEB8: ExecProcNode (executor.h:259)
==00:00:00:06.975 2318810==    by 0x43EEB8: ExecNestLoop
(nodeNestloop.c:109)
==00:00:00:06.975 2318810==    by 0x40EA14: ExecProcNodeFirst
(execProcnode.c:464)
==00:00:00:06.975 2318810==    by 0x41A9BF: ExecProcNode (executor.h:259)
==00:00:00:06.975 2318810==    by 0x41A9BF: fetch_input_tuple
(nodeAgg.c:563)
==00:00:00:06.975 2318810==    by 0x41E2D4: agg_retrieve_direct
(nodeAgg.c:2346)
==00:00:00:06.975 2318810==

EXPLAIN shows:
 Aggregate  (cost=21.42..21.43 rows=1 width=8)
   ->  Nested Loop  (cost=0.27..21.42 rows=1 width=0)
         ->  Index Only Scan using t_idx on t t1  (cost=0.13..12.16 rows=2
width=64)
         ->  Memoize  (cost=0.14..6.16 rows=1 width=64)
               Cache Key: t1.n
               Cache Mode: binary
               ->  Index Only Scan using t_idx on t t2  (cost=0.13..6.15
rows=1 width=64)
                     Index Cond: (n <= t1.n)

If I understand the issue and nodeMemoize.c correctly, here
prepare_probe_slot() fills pslot->tts_values[] with a result of
ExecEvalExpr(),
which has length of 'name', but later MemoizeHash_hash() gets
attrs[]->attlen
(64) and passes it to datum_image_hash() for calculating a hash over this
number of bytes.

Reproduced starting from e502150f7.


pgsql-bugs by date:

Previous
From: Peter Eisentraut
Date:
Subject: Re: About the function current_user
Next
From: Tom Lane
Date:
Subject: Re: BUG #17846: pg_dump doesn't properly dump with paused WAL replay