Skip to content

Commit 73bad52

Browse files
committed
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
1 parent 54a2330 commit 73bad52

File tree

1 file changed

+9
-3
lines changed

1 file changed

+9
-3
lines changed

src/backend/tcop/fastpath.c

+9-3
Original file line numberDiff line numberDiff line change
@@ -200,7 +200,6 @@ fetch_fp_info(Oid func_id, struct fp_info * fip)
200200
HeapTuple func_htp;
201201
Form_pg_proc pp;
202202

203-
Assert(OidIsValid(func_id));
204203
Assert(fip != NULL);
205204

206205
/*
@@ -214,15 +213,20 @@ fetch_fp_info(Oid func_id, struct fp_info * fip)
214213
MemSet(fip, 0, sizeof(struct fp_info));
215214
fip->funcid = InvalidOid;
216215

217-
fmgr_info(func_id, &fip->flinfo);
218-
219216
func_htp = SearchSysCache1(PROCOID, ObjectIdGetDatum(func_id));
220217
if (!HeapTupleIsValid(func_htp))
221218
ereport(ERROR,
222219
(errcode(ERRCODE_UNDEFINED_FUNCTION),
223220
errmsg("function with OID %u does not exist", func_id)));
224221
pp = (Form_pg_proc) GETSTRUCT(func_htp);
225222

223+
/* reject pg_proc entries that are unsafe to call via fastpath */
224+
if (pp->proisagg || pp->proiswindow || pp->proretset)
225+
ereport(ERROR,
226+
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
227+
errmsg("cannot call function %s via fastpath interface",
228+
NameStr(pp->proname))));
229+
226230
/* watch out for catalog entries with more than FUNC_MAX_ARGS args */
227231
if (pp->pronargs > FUNC_MAX_ARGS)
228232
elog(ERROR, "function %s has more than %d arguments",
@@ -235,6 +239,8 @@ fetch_fp_info(Oid func_id, struct fp_info * fip)
235239

236240
ReleaseSysCache(func_htp);
237241

242+
fmgr_info(func_id, &fip->flinfo);
243+
238244
/*
239245
* This must be last!
240246
*/

0 commit comments

Comments
 (0)