I know the $subject can be scary, but I want to preface that we have NO
memory overruns here.
When compiling Postgres with -fsanitize=bounds, I get the following
errors in the log:
jsonpath_exec.c:3832:3: runtime error: index 3 out of bounds for type 'JsonbValue[2]'
jsonpath_exec.c:3918:10: runtime error: index 3 out of bounds for type 'JsonbValue[2]'
The lines corrspond to accesses in JsonValueListAppend() and
JsonValueListNext(). A query like the following is enough to trigger the
errors:
SELECT jsonb_path_query('[1,2,3,4,5,6]', '$[*]');
This behavior was introduced in
5a2043bf713113b0f6e9dbf2046499a5ca67883c[0]. It made JsonValueList
a chunked list whose first chunk lives on the caller's stack. All chunks
shared one struct type, whose trailing array was declared as
items[BASE_JVL_ITEMS]. Extra chunks were allocated with room for more
entries and code indexed past the declared bound of 2.
C11 6.5.6p8 makes pointer arithmetic that does more than one element
past the end of an array undefined behavior, and Annex J.2 confirms this
holds "even if an object is apparently accessible with the given
subscript".
We can fix this by separating JsonValueList into two structs:
JsonValueList and JsonValueListChunk. JsonValueList holds the first
BASE_JVL_ITEMS, and it points to any subsequent JsonValueListChunks,
which hold additional items.
I think this is good motivation (for me) for standing up a buildfarm
animal to catch these sorts of issues. CCing Peter since he has started
committing some of my related counted_by work.
C11 Standard: https://www.open-std.org/jtc1/sc22/wg14/www/docs/n1548.pdf
[0]: https://git.postgresql.org/gitweb/?p=postgresql.git;a=commit;h=5a2043bf713113b0f6e9dbf2046499a5ca67883c
--
Tristan Partin
PostgreSQL Contributors Team
AWS (https://aws.amazon.com)