Skip to content

Commit

Permalink
Lock down search_path in SPI calls
Browse files Browse the repository at this point in the history
  • Loading branch information
svenklemm committed Feb 1, 2023
1 parent f75a51d commit 789bb26
Show file tree
Hide file tree
Showing 7 changed files with 43 additions and 8 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ accidentally triggering the load of a previous DB version.**
* #4926 Fix corruption when inserting into compressed chunks
* #5218 Add role-level security to job error log
* #5214 Fix use of prepared statement in async module
* #5259 Lock down search_path in SPI calls

## 2.9.2 (2023-01-26)

Expand Down
10 changes: 8 additions & 2 deletions src/hypertable.c
Original file line number Diff line number Diff line change
Expand Up @@ -2901,10 +2901,16 @@ ts_hypertable_get_open_dim_max_value(const Hypertable *ht, int dimension_index,
if (NULL == dim)
elog(ERROR, "invalid open dimension index %d", dimension_index);

/* Query for the last bucket in the materialized hypertable */
/*
* Query for the last bucket in the materialized hypertable.
* Since this might be run as part of a parallel operation
* we cannot use SET search_path here to lock down the
* search_path and instead have to fully schema-qualify
* everything.
*/
command = makeStringInfo();
appendStringInfo(command,
"SELECT max(%s) FROM %s.%s",
"SELECT pg_catalog.max(%s) FROM %s.%s",
quote_identifier(NameStr(dim->fd.column_name)),
quote_identifier(NameStr(ht->fd.schema_name)),
quote_identifier(NameStr(ht->fd.table_name)));
Expand Down
5 changes: 5 additions & 0 deletions src/telemetry/replication.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,11 @@ ts_telemetry_replication_info_gather(void)
if (SPI_connect() != SPI_OK_CONNECT)
return info;

/* Lock down search_path */
res = SPI_exec("SET LOCAL search_path TO pg_catalog, pg_temp", 0);
if (res < 0)
ereport(ERROR, (errcode(ERRCODE_INTERNAL_ERROR), (errmsg("could not set search_path"))));

res = SPI_execute("SELECT cast(count(pid) as int) from pg_catalog.pg_stat_get_wal_senders() "
"WHERE pid is not null",
true, /* read_only */
Expand Down
10 changes: 4 additions & 6 deletions src/telemetry/telemetry.c
Original file line number Diff line number Diff line change
Expand Up @@ -359,8 +359,8 @@ add_errors_by_sqlerrcode(JsonbParseState *parse_state)
if (SPI_connect() != SPI_OK_CONNECT)
elog(ERROR, "could not connect to SPI");

/* SPI calls must be qualified otherwise they are unsafe */
res = SPI_exec("SET search_path TO pg_catalog, pg_temp", 0);
/* Lock down search_path */
res = SPI_exec("SET LOCAL search_path TO pg_catalog, pg_temp", 0);
if (res < 0)
ereport(ERROR, (errcode(ERRCODE_INTERNAL_ERROR), (errmsg("could not set search_path"))));

Expand Down Expand Up @@ -398,7 +398,6 @@ add_errors_by_sqlerrcode(JsonbParseState *parse_state)
old_context = MemoryContextSwitchTo(spi_context);
}

res = SPI_exec("RESET search_path", 0);
res = SPI_finish();

Assert(res == SPI_OK_FINISH);
Expand Down Expand Up @@ -462,8 +461,8 @@ add_job_stats_by_job_type(JsonbParseState *parse_state)
if (SPI_connect() != SPI_OK_CONNECT)
elog(ERROR, "could not connect to SPI");

/* SPI calls must be qualified otherwise they are unsafe */
res = SPI_exec("SET search_path TO pg_catalog, pg_temp", 0);
/* Lock down search_path */
res = SPI_exec("SET LOCAL search_path TO pg_catalog, pg_temp", 0);
if (res < 0)
ereport(ERROR, (errcode(ERRCODE_INTERNAL_ERROR), (errmsg("could not set search_path"))));

Expand Down Expand Up @@ -525,7 +524,6 @@ add_job_stats_by_job_type(JsonbParseState *parse_state)
add_job_stats_internal(parse_state, TextDatumGetCString(jobtype_datum), &stats);
old_context = MemoryContextSwitchTo(spi_context);
}
res = SPI_exec("RESET search_path", 0);
res = SPI_finish();
Assert(res == SPI_OK_FINISH);
}
Expand Down
5 changes: 5 additions & 0 deletions tsl/src/continuous_aggs/materialize.c
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,11 @@ continuous_agg_update_materialization(SchemaAndName partial_view,
if (res != SPI_OK_CONNECT)
elog(ERROR, "could not connect to SPI in materializer");

/* Lock down search_path */
res = SPI_exec("SET LOCAL search_path TO pg_catalog, pg_temp", 0);
if (res < 0)
ereport(ERROR, (errcode(ERRCODE_INTERNAL_ERROR), (errmsg("could not set search_path"))));

/* pin the start of new_materialization to the end of new_materialization,
* we are not allowed to materialize beyond that point
*/
Expand Down
5 changes: 5 additions & 0 deletions tsl/src/continuous_aggs/refresh.c
Original file line number Diff line number Diff line change
Expand Up @@ -717,6 +717,11 @@ continuous_agg_refresh_internal(const ContinuousAgg *cagg,
if ((rc = SPI_connect_ext(SPI_OPT_NONATOMIC) != SPI_OK_CONNECT))
elog(ERROR, "SPI_connect failed: %s", SPI_result_code_string(rc));

/* Lock down search_path */
rc = SPI_exec("SET LOCAL search_path TO pg_catalog, pg_temp", 0);
if (rc < 0)
ereport(ERROR, (errcode(ERRCODE_INTERNAL_ERROR), (errmsg("could not set search_path"))));

/* Like regular materialized views, require owner to refresh. */
if (!pg_class_ownercheck(cagg->relid, GetUserId()))
aclcheck_error(ACLCHECK_NOT_OWNER,
Expand Down
15 changes: 15 additions & 0 deletions tsl/src/reorder.c
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,11 @@ tsl_copy_or_move_chunk_proc(FunctionCallInfo fcinfo, bool delete_on_src_node)
if ((rc = SPI_connect_ext(nonatomic ? SPI_OPT_NONATOMIC : 0)) != SPI_OK_CONNECT)
elog(ERROR, "SPI_connect failed: %s", SPI_result_code_string(rc));

/* Lock down search_path */
rc = SPI_exec("SET LOCAL search_path TO pg_catalog, pg_temp", 0);
if (rc < 0)
ereport(ERROR, (errcode(ERRCODE_INTERNAL_ERROR), (errmsg("could not set search_path"))));

/* perform the actual distributed chunk move after a few sanity checks */
chunk_copy(chunk_id, src_node_name, dst_node_name, op_id, delete_on_src_node);

Expand Down Expand Up @@ -328,6 +333,11 @@ tsl_subscription_exec(PG_FUNCTION_ARGS)
if (SPI_connect() != SPI_OK_CONNECT)
elog(ERROR, "could not connect to SPI");

/* Lock down search_path */
res = SPI_exec("SET LOCAL search_path TO pg_catalog, pg_temp", 0);
if (res < 0)
ereport(ERROR, (errcode(ERRCODE_INTERNAL_ERROR), (errmsg("could not set search_path"))));

res = SPI_execute(subscription_cmd, false /* read_only */, 0 /*count*/);

if (res < 0)
Expand Down Expand Up @@ -365,6 +375,11 @@ tsl_copy_chunk_cleanup_proc(PG_FUNCTION_ARGS)
if ((rc = SPI_connect_ext(nonatomic ? SPI_OPT_NONATOMIC : 0)) != SPI_OK_CONNECT)
elog(ERROR, "SPI_connect failed: %s", SPI_result_code_string(rc));

/* Lock down search_path */
rc = SPI_exec("SET LOCAL search_path TO pg_catalog, pg_temp", 0);
if (rc < 0)
ereport(ERROR, (errcode(ERRCODE_INTERNAL_ERROR), (errmsg("could not set search_path"))));

/* perform the cleanup/repair depending on the stage */
chunk_copy_cleanup(operation_id);

Expand Down

0 comments on commit 789bb26

Please sign in to comment.