Skip to content

fix: avoid privileged refresh of h3 distance dependents#204

Open
Komzpa wants to merge 1 commit into
mainfrom
codex/propose-fix-for-upgrade-script-vulnerability
Open

fix: avoid privileged refresh of h3 distance dependents#204
Komzpa wants to merge 1 commit into
mainfrom
codex/propose-fix-for-upgrade-script-vulnerability

Conversation

@Komzpa

@Komzpa Komzpa commented Jun 11, 2026

Copy link
Copy Markdown
Member

Motivation

  • The 4.2.3->4.5.0 upgrade script ran privileged UPDATE, REINDEX, and REFRESH MATERIALIZED VIEW on catalog-discovered objects that depend on h3index_distance / <->, which can evaluate user-controlled expressions as the upgrade-running user and enable privilege escalation.
  • The intent is to preserve necessary internal upgrade work (function/operator and index-format fixes) while avoiding executing tenant code during an extension update.

Description

  • Remove the privileged DO block from h3/sql/updates/h3--4.2.3--4.5.0.sql that walked pg_depend and performed automatic UPDATE/REINDEX/REFRESH, and replace it with a documented comment instructing administrators to perform such maintenance explicitly after upgrade.
  • Preserve the CREATE OR REPLACE FUNCTION h3index_distance(...) and the index-repair logic that do not evaluate user expressions during upgrade.
  • Update the regression test h3/test/sql/extension.sql to perform the required REINDEX, UPDATE (with ALTER TABLE ... DISABLE TRIGGER USER/ENABLE where applicable), and REFRESH MATERIALIZED VIEW commands explicitly after ALTER EXTENSION instead of relying on the upgrade script.
  • Adjust h3/test/expected/extension.out to include the explicit post-upgrade maintenance commands executed by the test.

Testing

  • Ran targeted repository checks and searches with rg to confirm removal of the catalog-driven maintenance (searches for session_replication_role, distance_dependents, REFRESH MATERIALIZED VIEW, and the UPDATE ... SET pattern) and presence of the explicit post-upgrade commands, which matched expectations.
  • Ran git diff --check and local sanity checks which reported no whitespace or diff errors.
  • Attempted a full build with cmake -B build -DCMAKE_BUILD_TYPE=Release but the build and ctest/pg_regress could not complete because FetchContent failed to download upstream H3 from GitHub due to a network/proxy HTTP 403, so end-to-end regression execution was blocked by the environment.

Codex Task

@coderabbitai

coderabbitai Bot commented Jun 11, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

The upgrade from h3 4.2.3 to 4.5.0 shifts maintenance responsibility for h3index_distance() operator dependencies from automatic execution during upgrade to manual steps performed by administrators. The upgrade script no longer auto-updates dependent objects; the test suite demonstrates the required manual procedures.

Changes

h3index_distance() Operator Upgrade: Manual Maintenance Workflow

Layer / File(s) Summary
Upgrade script removes automatic maintenance and adds advisory
h3/sql/updates/h3--4.2.3--4.5.0.sql
The upgrade removes the automatic DO $$ block that previously recomputed generated columns and refreshed dependent indexes and materialized views. An explicit comment instructs administrators to perform these maintenance steps manually.
Test demonstrates post-upgrade manual maintenance procedure
h3/test/sql/extension.sql
The test adds a post-upgrade maintenance sequence showing how to REINDEX indexes, disable/re-enable user triggers on generated-column tables, refresh generated data via no-op row updates, and explicitly REFRESH materialized views.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Poem

A rabbit hops through SQL scripts with care,
Where h3index_distance() once danced in the air.
The upgrade now whispers: "Please do it yourself!"
While tests show the steps to maintain database health.
Hop, REINDEX, REFRESH! 🐰✨

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely summarizes the main change: avoiding privileged refresh operations on h3 distance dependents during upgrade, which aligns with the primary objective of removing the privileged DO block from the upgrade script.
Description check ✅ Passed The description thoroughly explains the motivation, specific changes made, testing performed, and aligns directly with the changeset: removal of the privileged maintenance block from the upgrade script and explicit post-upgrade commands in tests.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/propose-fix-for-upgrade-script-vulnerability

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
h3/sql/updates/h3--4.2.3--4.5.0.sql (1)

50-65: ⚠️ Potential issue | 🟠 Major

Security: the remaining REINDEX loop can execute user-controlled index expressions/predicates (lines 50–65)

PostgreSQL REINDEX rebuilds indexes by evaluating expression-index expressions and partial-index predicates, and it runs those evaluations with the privileges of the role executing REINDEX. This means the loop that REINDEX INDEXes every matching btree index using opclass h3index_ops can re-run user-controlled logic if any such index is expression and/or partial. Filter the candidate indexes to exclude expression/partial ones (e.g., require pg_index.indexprs IS NULL and pg_index.indpred IS NULL) or otherwise ensure the loop can’t target them.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@h3/sql/updates/h3--4.2.3--4.5.0.sql` around lines 50 - 65, The REINDEX loop
selects btree indexes using opclass h3index_ops but doesn't exclude expression
or partial indexes, so update the FOR ... SELECT query (the one joining pg_index
i, pg_class ci, pg_am am, pg_opclass opc and returning r.idx) to filter out
expression and partial indexes by requiring i.indexprs IS NULL and i.indpred IS
NULL before looping and executing REINDEX INDEX on r.idx; this ensures the
EXECUTE pg_catalog.format('REINDEX INDEX %s', r.idx) call cannot evaluate
user-controlled index expressions or predicates.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@h3/sql/updates/h3--4.2.3--4.5.0.sql`:
- Around line 50-65: The REINDEX loop selects btree indexes using opclass
h3index_ops but doesn't exclude expression or partial indexes, so update the FOR
... SELECT query (the one joining pg_index i, pg_class ci, pg_am am, pg_opclass
opc and returning r.idx) to filter out expression and partial indexes by
requiring i.indexprs IS NULL and i.indpred IS NULL before looping and executing
REINDEX INDEX on r.idx; this ensures the EXECUTE pg_catalog.format('REINDEX
INDEX %s', r.idx) call cannot evaluate user-controlled index expressions or
predicates.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 63863f0b-8879-4c59-8da7-e50e0c8d4d43

📥 Commits

Reviewing files that changed from the base of the PR and between 9d70e9c and 39138f8.

⛔ Files ignored due to path filters (1)
  • h3/test/expected/extension.out is excluded by !**/*.out
📒 Files selected for processing (2)
  • h3/sql/updates/h3--4.2.3--4.5.0.sql
  • h3/test/sql/extension.sql

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant