pg.ddx.io  pgsql-hackers@postgresql.org mailing list archive  
help / color / mirror / Atom feed
From: Tom Lane <tgl@sss.pgh.pa.us>
To: pgsql-hackers@lists.postgresql.org
Subject: SPI versus read/write expanded datums
Date: Wed, 10 Aug 2022 10:51:00 -0400
Message-ID: <187436.1660143060@sss.pgh.pa.us> (raw)

In the report at [1] we learned that the SQL-language function
handler is too cavalier about read/write expanded datums that
it receives as input.  A function that receives such a datum
is entitled to scribble on its value, or even delete it.
If the function turns around and passes the datum on to some
other function, the same applies there.  So in general, it can
only be safe to pass such a datum to *one* subsidiary function.
If you want to use the value more than once, you'd better convert
the pointer to read-only.  fmgr_sql wasn't doing that, leading
to the reported bug.

After fixing that, I wondered if we had the same problem anywhere
else, and it didn't take long to think of such a place: SPI.
If you pass a read/write datum to SPI_execute_plan or one of its
siblings, and the executed query references that datum more than
once, you're potentially in trouble.  Even if it does only
reference it once, you might be surprised that your copy of the
datum got modified.

However, we can't install a 100% fix in SPI itself, because
plpgsql intentionally exploits exactly this behavior to optimize
things like "arr := array_append(arr, val)".  I considered the
idea of adding a 90% fix by making _SPI_convert_params() convert
R/W pointers to R/O.  That would protect places using the old-style
"char *Nulls" APIs, and then we'd deem it the responsibility
of callers using ParamListInfo APIs to protect themselves.
I can't get terribly excited about that though, because it'd
be adding complexity and cycles for a problem that seems entirely
theoretical at this point.  I can't find any SPI callers that
would *actually* be passing a R/W datum to a query that'd be
likely to modify it.  The non-plpgsql PLs are at the most risk
of calling a hazardous query, but they all pass "flat" datums
that are the immediate result of a typinput function or the like.

So my inclination is to do nothing about this now, and maybe
nothing ever.  But I thought it'd be a good idea to memorialize
this issue for the archives.

			regards, tom lane

[1] https://www.postgresql.org/message-id/flat/WScDU5qfoZ7PB2gXwNqwGGgDPmWzz08VdydcPFLhOwUKZcdWbblbo-0Lk...





Message-ID: <187436.1660143060@sss.pgh.pa.us>
Permalink:  ../187436.1660143060@sss.pgh.pa.us/
Also on:    postgresql.org/message-id/187436.1660143060@sss.pgh.pa.us

 · 

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-hackers@postgresql.org
  Cc: tgl@sss.pgh.pa.us, pgsql-hackers@lists.postgresql.org
  Subject: Re: SPI versus read/write expanded datums
  In-Reply-To: <187436.1660143060@sss.pgh.pa.us>

* 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