|
| 1 | +-- Pin CVE-2026-2004 behaviour: attaching a non-built-in selectivity estimator |
| 2 | +-- to an operator requires superuser. Verified against both RESTRICT and JOIN. |
| 3 | +-- |
| 4 | +-- Upstream commits: b764b26f (PG 15.16), bbf5bcf5 (PG 17.8). The check fires in |
| 5 | +-- both ValidateRestrictionEstimator() and ValidateJoinEstimator() in |
| 6 | +-- src/backend/commands/operatorcmds.c. |
| 7 | +-- |
| 8 | +-- We use real non-built-in estimators shipped by intarray (_int_matchsel for |
| 9 | +-- RESTRICT, _int_overlap_joinsel for JOIN) -- these are exactly the customer- |
| 10 | +-- reachable estimators the CVE-2026-2004 fleet-scan query targets. |
| 11 | +-- |
| 12 | +-- Refs: PSQL-1110, PSQL-1234. |
| 13 | +BEGIN; |
| 14 | +-- A schema the non-superuser controls, so CREATE OPERATOR reaches the estimator |
| 15 | +-- validation rather than failing an earlier schema-permission check. |
| 16 | +CREATE SCHEMA op_ns; |
| 17 | +GRANT CREATE, USAGE ON SCHEMA op_ns TO postgres; |
| 18 | +-- Trivial boolean procedure for the operator (no internal args -> valid in SQL). |
| 19 | +CREATE FUNCTION op_ns.fake_op_proc(_int4, _int4) |
| 20 | + RETURNS bool LANGUAGE sql IMMUTABLE AS $$ SELECT true $$; |
| 21 | +-- Switch to a non-superuser role. |
| 22 | +SET ROLE postgres; |
| 23 | +-- 1) RESTRICT = non-built-in estimator should be rejected. |
| 24 | +SAVEPOINT before_restrict; |
| 25 | +CREATE OPERATOR op_ns.@@@ ( |
| 26 | + LEFTARG = _int4, RIGHTARG = _int4, |
| 27 | + PROCEDURE = op_ns.fake_op_proc, |
| 28 | + RESTRICT = _int_matchsel |
| 29 | +); |
| 30 | +ERROR: must be superuser to specify a non-built-in restriction estimator function |
| 31 | +ROLLBACK TO SAVEPOINT before_restrict; |
| 32 | +-- 2) JOIN = non-built-in estimator should be rejected. |
| 33 | +SAVEPOINT before_join; |
| 34 | +CREATE OPERATOR op_ns.@@@ ( |
| 35 | + LEFTARG = _int4, RIGHTARG = _int4, |
| 36 | + PROCEDURE = op_ns.fake_op_proc, |
| 37 | + JOIN = _int_overlap_joinsel |
| 38 | +); |
| 39 | +ERROR: must be superuser to specify a non-built-in join estimator function |
| 40 | +ROLLBACK TO SAVEPOINT before_join; |
| 41 | +-- 3) Sanity check: built-in selectivity estimators still work for non-superusers. |
| 42 | +CREATE OPERATOR op_ns.@@@ ( |
| 43 | + LEFTARG = _int4, RIGHTARG = _int4, |
| 44 | + PROCEDURE = op_ns.fake_op_proc, |
| 45 | + RESTRICT = eqsel, |
| 46 | + JOIN = eqjoinsel |
| 47 | +); |
| 48 | +DROP OPERATOR op_ns.@@@ (_int4, _int4); |
| 49 | +RESET ROLE; |
| 50 | +ROLLBACK; |
0 commit comments