aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2021-04-30 14:10:26 -0400
committerTom Lane <tgl@sss.pgh.pa.us>2021-04-30 14:10:26 -0400
commit4d225ba0e6da73ddcbf207d2d91fc26537cfc5e1 (patch)
tree5e5eee9f5613b7a1cccb2ba336e555f3cdb09ec9 /src
parentbbcfee0e56a2a563a4907b116da72081a408eadf (diff)
downloadpostgresql-4d225ba0e6da73ddcbf207d2d91fc26537cfc5e1.tar.gz
postgresql-4d225ba0e6da73ddcbf207d2d91fc26537cfc5e1.zip
Disallow calling anything but plain functions via the fastpath API.
Reject aggregates, window functions, and procedures. Aggregates failed anyway, though with a somewhat obscure error message. Window functions would hit an Assert or null-pointer dereference. Procedures seemed to work as long as you didn't try to do transaction control, but (a) transaction control is sort of the point of a procedure, and (b) it's not entirely clear that no bugs lurk in that path. Given the lack of testing of this area, it seems safest to be conservative in what we support. Also reject proretset functions, as the fastpath protocol can't support returning a set. Also remove an easily-triggered assertion that the given OID isn't 0; the subsequent lookups can handle that case themselves. Per report from Theodor-Arsenij Larionov-Trichkin. Back-patch to all supported branches. (The procedure angle only applies in v11+, of course.) Discussion: https://postgr.es/m/2039442.1615317309@sss.pgh.pa.us
Diffstat (limited to 'src')
-rw-r--r--src/backend/tcop/fastpath.c12
1 files changed, 9 insertions, 3 deletions
diff --git a/src/backend/tcop/fastpath.c b/src/backend/tcop/fastpath.c
index e793984a9f3..e561eec7de8 100644
--- a/src/backend/tcop/fastpath.c
+++ b/src/backend/tcop/fastpath.c
@@ -198,7 +198,6 @@ fetch_fp_info(Oid func_id, struct fp_info *fip)
HeapTuple func_htp;
Form_pg_proc pp;
- Assert(OidIsValid(func_id));
Assert(fip != NULL);
/*
@@ -212,8 +211,6 @@ fetch_fp_info(Oid func_id, struct fp_info *fip)
MemSet(fip, 0, sizeof(struct fp_info));
fip->funcid = InvalidOid;
- fmgr_info(func_id, &fip->flinfo);
-
func_htp = SearchSysCache1(PROCOID, ObjectIdGetDatum(func_id));
if (!HeapTupleIsValid(func_htp))
ereport(ERROR,
@@ -221,6 +218,13 @@ fetch_fp_info(Oid func_id, struct fp_info *fip)
errmsg("function with OID %u does not exist", func_id)));
pp = (Form_pg_proc) GETSTRUCT(func_htp);
+ /* reject pg_proc entries that are unsafe to call via fastpath */
+ if (pp->prokind != PROKIND_FUNCTION || pp->proretset)
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("cannot call function %s via fastpath interface",
+ NameStr(pp->proname))));
+
/* watch out for catalog entries with more than FUNC_MAX_ARGS args */
if (pp->pronargs > FUNC_MAX_ARGS)
elog(ERROR, "function %s has more than %d arguments",
@@ -233,6 +237,8 @@ fetch_fp_info(Oid func_id, struct fp_info *fip)
ReleaseSysCache(func_htp);
+ fmgr_info(func_id, &fip->flinfo);
+
/*
* This must be last!
*/