Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 48 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,54 @@ true until the next version shipped.

### Fixed

- Four secret-leak claims over the PG server log could pass having read nothing
(#1032).

`iceberg_rest.sh`, `iceberg_rest_server.sh` (twice) and `iceberg_rest_vended.sh`
each assert that a token or secret never reaches `$PGC_LOGFILE`, with
`grep -c "$SECRET" "$PGC_LOGFILE"` compared against `0`. Nothing in the tree made
any positive claim about that file: no suite asserted it exists, is readable, or
holds a single line.

THE HOLE IS EXACTLY ONE STATE, and the other three are already safe. Measured:

a real server log got=[0] passes
an EMPTY log got=[0] PASSES, having read nothing
a missing log got=[] fails
a log that LEAKS got=[1] fails

`grep -c` prints nothing for a file it cannot open, so a missing path, an unset
variable and an unreadable file all fail closed. A file that EXISTS AND IS EMPTY
prints `0`, which is the value the claim wants. Anything leaving the log present
and empty -- a rotation, a `log_destination` change, a truncating reuse path --
turns all four green and says nothing.

Each claim now carries its own premise immediately above it, so the two cannot
drift apart:

_ir_loglines="$(grep -c . "$PGC_LOGFILE" 2>/dev/null)" || _ir_loglines=0
check "premise: the PG server log holds lines to search" \
"$([ "${_ir_loglines:-0}" -gt 0 ] && echo yes || echo no)" "yes"

NOT the `grep -c . ... || echo 0` form: `grep -c` prints `0` AND exits 1 on an
empty file, so that yields two lines and turns the comparison into a shell error
rather than a comparison. The assignment form carries one value. Measured.

Removal proof, at suite level: pointing both reads at a present-and-empty file
gives `FAIL premise: the PG server log holds lines to search` while
`PASS the token never appears in the server (PG) log` still stands -- the premise
catching precisely what the claim cannot see.

A first attempt at that proof truncated `$PGC_LOGFILE` in place and did NOT
reproduce: the running postmaster wrote a line back within the same instant
(`lines immediately after truncation: 1`), so the mutation never created the
state it claimed to. Recorded because the invalid version looked like a passing
control.

The three suites already applied this discipline to their own request logs --
every absence claim over `$REST_LOG` and `$OLOG` sits beside a positive grep
returning `1`. The PG log was the one file they skipped.

- `native_upgrade_converge` staged its fixtures only when nothing was already
installed, so a leftover install script won over the committed fixture (#1090).

Expand Down
17 changes: 17 additions & 0 deletions test/iceberg_rest.sh
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,23 @@ q "SELECT pg_reload_conf()" >/dev/null
q "SELECT pgcolumnar.iceberg_rest_table_location('$CAT','db','events')" >/dev/null
q "ALTER SYSTEM SET log_statement='none'" >/dev/null
q "SELECT pg_reload_conf()" >/dev/null
# PREMISE FOR THE CLAIM BELOW, which can pass having read nothing (#1032).
# `grep -c` prints `0` for a file that EXISTS AND IS EMPTY. A missing or unreadable
# file prints NOTHING, so `"" != "0"` already fails the claim -- empty is the only
# hole, and it is the one a rotation, a `log_destination` change or a truncating
# reuse path would open. Measured, all four states:
#
# real log got=[0] passes empty log got=[0] PASSES having read nothing
# missing got=[] fails leaking got=[1] fails
#
# NOT `grep -c . ... || echo 0`: `grep -c` prints `0` AND exits 1 on an empty file,
# so that form yields TWO lines and turns the comparison into a shell error. The
# assignment form below carries one value.
#
# The request logs in this suite already have positive controls; the PG log did not.
_ir_loglines="$(grep -c . "$PGC_LOGFILE" 2>/dev/null)" || _ir_loglines=0
check "premise: the PG server log holds lines to search" \
"$([ "${_ir_loglines:-0}" -gt 0 ] && echo yes || echo no)" "yes"
check "the token never appears in the server (PG) log" \
"$(grep -c "$TOKEN" "$PGC_LOGFILE" 2>/dev/null)" "0"
check "the token value never appears in the catalog request log" \
Expand Down
34 changes: 34 additions & 0 deletions test/iceberg_rest_server.sh
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,23 @@ q "SELECT pg_reload_conf()" >/dev/null
q "SELECT pgcolumnar.iceberg_rest_table_location('cat','db','events')" >/dev/null
q "ALTER SYSTEM SET log_statement='none'" >/dev/null
q "SELECT pg_reload_conf()" >/dev/null
# PREMISE FOR THE CLAIM BELOW, which can pass having read nothing (#1032).
# `grep -c` prints `0` for a file that EXISTS AND IS EMPTY. A missing or unreadable
# file prints NOTHING, so `"" != "0"` already fails the claim -- empty is the only
# hole, and it is the one a rotation, a `log_destination` change or a truncating
# reuse path would open. Measured, all four states:
#
# real log got=[0] passes empty log got=[0] PASSES having read nothing
# missing got=[] fails leaking got=[1] fails
#
# NOT `grep -c . ... || echo 0`: `grep -c` prints `0` AND exits 1 on an empty file,
# so that form yields TWO lines and turns the comparison into a shell error. The
# assignment form below carries one value.
#
# The request logs in this suite already have positive controls; the PG log did not.
_irs_loglines="$(grep -c . "$PGC_LOGFILE" 2>/dev/null)" || _irs_loglines=0
check "premise: the PG server log holds lines to search, for the mapping token" \
"$([ "${_irs_loglines:-0}" -gt 0 ] && echo yes || echo no)" "yes"
check "the mapping token never appears in the PG server log" \
"$(grep -c "$TOKEN" "$PGC_LOGFILE" 2>/dev/null)" "0"

Expand Down Expand Up @@ -148,6 +165,23 @@ q "SELECT pg_reload_conf()" >/dev/null
q "SELECT pgcolumnar.iceberg_rest_table_location('ocat','db','events')" >/dev/null
q "ALTER SYSTEM SET log_statement='none'" >/dev/null
q "SELECT pg_reload_conf()" >/dev/null
# PREMISE FOR THE CLAIM BELOW, which can pass having read nothing (#1032).
# `grep -c` prints `0` for a file that EXISTS AND IS EMPTY. A missing or unreadable
# file prints NOTHING, so `"" != "0"` already fails the claim -- empty is the only
# hole, and it is the one a rotation, a `log_destination` change or a truncating
# reuse path would open. Measured, all four states:
#
# real log got=[0] passes empty log got=[0] PASSES having read nothing
# missing got=[] fails leaking got=[1] fails
#
# NOT `grep -c . ... || echo 0`: `grep -c` prints `0` AND exits 1 on an empty file,
# so that form yields TWO lines and turns the comparison into a shell error. The
# assignment form below carries one value.
#
# The request logs in this suite already have positive controls; the PG log did not.
_irs_loglines2="$(grep -c . "$PGC_LOGFILE" 2>/dev/null)" || _irs_loglines2=0
check "premise: the PG server log holds lines to search, for the client secret" \
"$([ "${_irs_loglines2:-0}" -gt 0 ] && echo yes || echo no)" "yes"
check "the client secret never appears in the PG server log" \
"$(grep -c "$OCSEC" "$PGC_LOGFILE" 2>/dev/null)" "0"

Expand Down
17 changes: 17 additions & 0 deletions test/iceberg_rest_vended.sh
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,23 @@ q "SELECT count(*) FROM pgcolumnar.iceberg_rest_scan('$CAT','db','t')
AS t(id bigint, region text, amount int)" >/dev/null
q "ALTER SYSTEM SET log_statement='none'" >/dev/null
q "SELECT pg_reload_conf()" >/dev/null
# PREMISE FOR THE CLAIM BELOW, which can pass having read nothing (#1032).
# `grep -c` prints `0` for a file that EXISTS AND IS EMPTY. A missing or unreadable
# file prints NOTHING, so `"" != "0"` already fails the claim -- empty is the only
# hole, and it is the one a rotation, a `log_destination` change or a truncating
# reuse path would open. Measured, all four states:
#
# real log got=[0] passes empty log got=[0] PASSES having read nothing
# missing got=[] fails leaking got=[1] fails
#
# NOT `grep -c . ... || echo 0`: `grep -c` prints `0` AND exits 1 on an empty file,
# so that form yields TWO lines and turns the comparison into a shell error. The
# assignment form below carries one value.
#
# The request logs in this suite already have positive controls; the PG log did not.
_irv_loglines="$(grep -c . "$PGC_LOGFILE" 2>/dev/null)" || _irv_loglines=0
check "premise: the PG server log holds lines to search" \
"$([ "${_irv_loglines:-0}" -gt 0 ] && echo yes || echo no)" "yes"
check "the vended secret never appears in the PG server log" \
"$(grep -c "$SECRET" "$PGC_LOGFILE" 2>/dev/null)" "0"
check "the vended secret never appears in the S3 request log" \
Expand Down
Loading