Commit 393cebf
committed
fix: prevent backend segfault from user-mapping FFI and harden the FDW
A scan running under a role with no user mapping could crash the backend
with SIGSEGV (signal 11). In new(), GetUserMapping() raises a Postgres
ERROR (a C longjmp) when no mapping exists; this unwound past the already
constructed multi-threaded tokio runtime, skipping its Drop and leaking
worker threads until the backend destabilized. pg_timetable's repeated
scheduling (CALL timetable.f_control_importers()) made it reliably fatal.
Crash fix:
- Read the user mapping BEFORE creating the runtime, so a longjmp from
GetUserMapping can no longer skip a live runtime.
- Use a current-thread tokio runtime (a Postgres backend is single
threaded and the FDW only ever block_on's), removing the leaked
worker-thread failure mode entirely.
- Connect to etcd lazily in begin_scan / the modify path instead of in
new(), which the framework may call at planning time.
Robustness:
- iter_scan: convert non-UTF-8 etcd keys/values lossily instead of
panicking, and iterate by index instead of draining the vec front
(was O(n^2) per scan).
- begin_scan: do not panic when incrementing a prefix yields invalid
UTF-8; fall back to the wider, still-correct range.
- insert/update: return an error on NULL key/value cells instead of
panicking; do not panic on an empty user-mapping options list.
- update/delete: error on a missing key instead of silently creating it.
Tests:
- Add a regression test asserting that a scan with no user mapping
returns a clean error instead of crashing the backend.
Build / reproducibility:
- Make testcontainers an optional dependency enabled by the `pg_test`
feature (built for `cargo pgrx test`, not for release) and drop the
unused serde dependency.
- Track Cargo.lock (pins the wrappers git dependency) for reproducible
builds.
- pg_regress: CREATE EXTENSION etcd_fdw (was a stale template name).1 parent 268054e commit 393cebf
6 files changed
Lines changed: 4208 additions & 152 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
3 | 3 | | |
4 | 4 | | |
5 | 5 | | |
6 | | - | |
7 | 6 | | |
8 | 7 | | |
9 | 8 | | |
0 commit comments