From: | Michael Paquier <michael(at)paquier(dot)xyz> |
---|---|
To: | Alexander Lakhin <exclusion(at)gmail(dot)com> |
Cc: | pgsql-bugs(at)lists(dot)postgresql(dot)org |
Subject: | Re: BUG #16801: Invalid memory access on WITH RECURSIVE with nested WITHs |
Date: | 2021-02-24 05:03:40 |
Message-ID: | YDXeLBqjDeQQPGoO@paquier.xyz |
Views: | Raw Message | Whole Thread | Download mbox | Resend email |
Thread: | |
Lists: | pgsql-bugs |
On Tue, Feb 23, 2021 at 09:00:00AM +0300, Alexander Lakhin wrote:
> I've found out that the list implementation doesn't support the
> following usage pattern:
> List *testList = NIL;
> ListCell *testCell;
>
> testList = lcons(NIL, testList);
> testCell = list_head(testList);
> ...
> testList = lcons(NIL, testList);
>
> elog(INFO, "lfirst(testCell): %p", lfirst(testCell)); // prints
> 0x7f7f7f7f7f7f7f7f when compiled with -DUSE_VALGRIND
>
> (Such list manipulation is happening in that makeDependencyGraphWalker
> call.)
Thanks for the reminder, I was not able to get around this issue.
Anyway.. What's happening here is that the second lcons() call does
new_head_cell() as testList is not NIL. This itself calls
enlarge_list(), followed by wipe_mem() which invalidates the position
of the list head previously stored. Oops.
Coming back to the original problem, as you say there is some
confusion about the list operation that we had better clarify. From
what I can see cstate->innerwiths stores a List of Lists, and in each
passage the code tries to build a new list appended to
cstate->innerwiths. Using a ListCell to be able to track where the
new list head is located is awkward on HEAD (the business with cell1),
and there should be no need to keep around the reference to the first
element innerwiths, as long as you save the result in a new, separate,
List.
The second case in checkWellFormedRecursionWalker() is equally
dangerous. I have been playing with subselects and more recursions
and could not trigger a problem with -DUSE_VALGRIND, but let's be
safe.
So attached is a patch to take care of this, with a regression test
based on what has been sent upthread. This solves the issue for me.
Thoughts?
--
Michael
Attachment | Content-Type | Size |
---|---|---|
valgrind-cte-fix.patch | text/x-diff | 2.8 KB |
From | Date | Subject | |
---|---|---|---|
Next Message | PG Bug reporting form | 2021-02-24 07:52:36 | BUG #16893: JDBC Error |
Previous Message | Santosh Udupi | 2021-02-24 02:18:06 | Re: pg_restore - generated column - not populating |