Skip to content

Catalog scan leads to use-after-free under concurrent pressure #502

Description

@hello-world-bfree

What happens?

PostgresCatalogSet::Scan hands its callback a bare CatalogEntry& without pinning it into the calling transaction first. GetEntry and CreateEntry both keep the underlying shared_ptr<CatalogEntry> alive in PostgresTransaction::referenced_entries for the rest of the transaction. Scan does not.

If pg_clear_cache runs after a Scan but before every reference handed out by that Scan is done being used, ClearEntries drops the shared_ptr for those entries and destroys them. Anything still holding a reference from the earlier Scan is then reading freed memory; i.e., funcs from Duckdb core like duckdb_tables() or duckdb_views()

To Reproduce

Needs concurrent pressure. Have one connection repeatedly calling pg_clear_cache(), another concurrently running SELECT * FROM duckdb_tables() (or duckdb_indexes()) against an attached postgres catalog. Timing-dependent so needs to be ran multiple times. Reproduced under ASAN with a 200-iteration concurrent loop, crashed on the 2nd iteration in one run, took up to 5 in others.

==ERROR: AddressSanitizer: heap-use-after-free on address ...
READ of size 8 at ... thread T114    #0 std::__cxx11::basic_string<...>::_M_data() const
    #1 std::__cxx11::basic_string<...>::basic_string(basic_string const&)
    #2 duckdb::Value::Value(duckdb::Identifier const&) duckdb/src/common/types/value.cpp:155
    #3 duckdb::DuckDBTablesFunction(...) duckdb/src/function/table/system/duckdb_tables.cpp:153
...
SUMMARY: AddressSanitizer: heap-use-after-free ... in duckdb::Value::Value(duckdb::Identifier const&)

OS:

arch linux

PostgreSQL Version:

16-alpine

DuckDB Version:

v1.5.4-8377-g2daa4fc9a4

DuckDB Client:

cli

Full Name:

brandon freeman

Affiliation:

hallow

Have you tried this on the latest main branch?

  • I agree

Have you tried the steps to reproduce? Do they include all relevant data and configuration? Does the issue you report still appear there?

  • I agree

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions