pg.ddx.io  pgsql-bugs@postgresql.org mailing list archive  
help / color / mirror / Atom feed
From: PG Bug reporting form <noreply@postgresql.org>
To: pgsql-bugs@lists.postgresql.org
Cc: demurgos@demurgos.net
Subject: BUG #17053: Memory corruption in parser on prepared query reuse
Date: Wed, 09 Jun 2021 20:13:17 +0000
Message-ID: <17053-3ca3f501bbc212b4@postgresql.org> (raw)

The following bug has been logged on the website:

Bug reference:      17053
Logged by:          Charles Samborski
Email address:      demurgos@demurgos.net
PostgreSQL version: 13.3
Operating system:   Linux 5.12 (Arch Linux)
Description:        

I found a bug in Postgres where I can reliably trigger the following error:
"unrecognized node type: X", where X can be anything and changes across
program executions. For example, I can get "unrecognized node type: 0",
"nrecognized node type: 184", "unrecognized node type: 196608" and many
others (including negative values). This implies that a node type is read
from a corrupted memory location.

The following repo has C and Rust programs exhibiting this behavior:
https://github.com/demurgos/pg_unrecognized_node.

Here is the C program:

```
#include <stdio.h>
#include <stdlib.h>
#include "libpq-fe.h"

int
main(int argc, char **argv)
{
	PGconn        *conn;
	PGresult      *res;

	conn = PQconnectdb("");

	PQexec(conn, "DROP DOMAIN IF EXISTS schema_meta");
	PQexec(conn, "CREATE TYPE raw_schema_meta AS (version int4)");
	PQprepare(conn, "q1", "CREATE DOMAIN schema_meta AS raw_schema_meta CHECK
((value).version IS NOT NULL AND (value).version >= 1)", 0, NULL);
	PQexecPrepared(conn, "q1", 0, NULL, 0, 0, 0);
	PQexec(conn, "DROP DOMAIN IF EXISTS schema_meta");
	res = PQexecPrepared(conn, "q1", 0, NULL, 0, 0, 0);

	fprintf(stdout, "%s", PQresultErrorMessage(res));

	PQfinish(conn);

	return 0;
}
```

You can compile it with `gcc -lpq -o main main.c` and run it on fresh DB by
passing the credentials through the environment, e.g.: `PGUSER=test
PGPASSWORD=test PGDATABASE=test ./main`

I investigated this issue with the help of some people from IRC and would
like to thank them: ioguix, johto and Zr40.

The code is fairly short, the core of the issue is that the prepared query
`q1` is executed twice and it somehow messes up with the parser because of
the `CHECK` clause.



view thread (4+ messages)  latest in thread

Message-ID: <17053-3ca3f501bbc212b4@postgresql.org>
Permalink:  ../17053-3ca3f501bbc212b4@postgresql.org/
Also on:    postgresql.org/message-id/17053-3ca3f501bbc212b4@postgresql.org

 · 

reply

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Reply to all the recipients using the --to and --cc options:
  reply via email

  To: pgsql-bugs@postgresql.org
  Cc: noreply@postgresql.org, pgsql-bugs@lists.postgresql.org, demurgos@demurgos.net
  Subject: Re: BUG #17053: Memory corruption in parser on prepared query reuse
  In-Reply-To: <17053-3ca3f501bbc212b4@postgresql.org>

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

This inbox is served by DDX for PostgreSQL; see mirroring instructions
for how to clone and mirror all data and code used for this inbox