Skip to content

Deadlock capture's regexp_matches may accept a forged STATEMENT echo, same class as #4008 #4014

Description

@erikdarlingdata

Found while fixing #4008 (plan-capture spoofing). Not fixed here: different collector, needs its own PoC verification, regex redesign and regression tests, and #4008's deadline did not leave room for it.

What is wrong

PgDeadlockLogParser.s_deadlockBlock (the C# parser, used by the RDS log-API route) and PgDeadlocksCollector's self-hosted regexp_matches both anchor to a genuine line start and require a real timestamp before the pid bracket — the fix #4008 gives plan capture. But the pattern after the bracket is a WILDCARD, not a tight match:

[^\n]*ERROR:  deadlock detected\s*\n[^\n]*DETAIL:  (...)

[^\n]* allows ANY text between the bracket and ERROR: deadlock detected, including a REAL field label like STATEMENT: . So a backend's own STATEMENT companion, if its echoed SQL happens to contain the literal text ERROR: deadlock detected (e.g. in a comment) followed by a tab-continued line reading DETAIL: Process N waits for ... ; blocked by process M., matches the pattern using the REAL pid bracket already on that line — no backtracking trick even required, [^\n]* reaches it directly.

Sketch (not yet run live): a syntax error whose offending SQL is

SELECT 1 -- ERROR:  deadlock detected
DETAIL:  Process 1 waits for ShareLock on transaction 5; blocked by process 2.
Process 2 waits for ShareLock on transaction 6; blocked by process 1.

logged under any backend pid, would attribute a forged deadlock (fake participants, fake resource) to that real backend.

Separately, the MANAGED-prefix branch of both the deadlock and (pre-#4008) plan parsers used a LAZY [^\n]*? gap before the pid bracket, which backtracks past a real bracket to reach a forged one later on the same line when the tail pattern fails at the real one. #4008 closed that for plan capture by excluding [ from the gap's character class ([^\[\n]*, deterministic — see PgPlanLogParser.s_planBlock's comment and PgPlanLogParserTests.AForgedHeaderBehindARealColonPrefixedBracket_StillYieldsNoPlan). PgDeadlockLogParser.s_deadlockBlock still has the lazy form and needs the same treatment, independent of the wildcard-gap issue above.

Suggested fix

Activity

  1. erikdarlingdata commented on Sep 23, 2026

    @erikdarlingdata
    OwnerAuthor

    Closed by the watcher: delivered in PR #4042, merged to dev.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions