From 1fa8373931aeb98d175ac7988f1705b4a1c647d0 Mon Sep 17 00:00:00 2001
From: Sven Klemm <sven@timescale.com>
Date: Sun, 28 Aug 2022 19:18:16 +0200
Subject: [PATCH] Fix segfaults in policy check functions

---
 tsl/src/bgw_policy/compression_api.c          |  6 ++++++
 tsl/src/bgw_policy/continuous_aggregate_api.c |  5 +++++
 tsl/src/bgw_policy/reorder_api.c              |  5 +++++
 tsl/src/bgw_policy/retention_api.c            |  5 +++++
 tsl/test/expected/bgw_policy.out              | 11 +++++++++++
 tsl/test/sql/bgw_policy.sql                   | 10 ++++++++++
 6 files changed, 42 insertions(+)

diff --git a/tsl/src/bgw_policy/compression_api.c b/tsl/src/bgw_policy/compression_api.c
index a571ad99c..f143403b4 100644
--- a/tsl/src/bgw_policy/compression_api.c
+++ b/tsl/src/bgw_policy/compression_api.c
@@ -159,6 +159,12 @@ Datum
 policy_compression_check(PG_FUNCTION_ARGS)
 {
 	PolicyCompressionData policy_data;
+
+	if (PG_ARGISNULL(0))
+	{
+		ereport(ERROR, (errcode(ERRCODE_INTERNAL_ERROR), errmsg("config must not be NULL")));
+	}
+
 	policy_compression_read_and_validate_config(PG_GETARG_JSONB_P(0), &policy_data);
 	ts_cache_release(policy_data.hcache);
 
diff --git a/tsl/src/bgw_policy/continuous_aggregate_api.c b/tsl/src/bgw_policy/continuous_aggregate_api.c
index 1930cc5b7..d33998420 100644
--- a/tsl/src/bgw_policy/continuous_aggregate_api.c
+++ b/tsl/src/bgw_policy/continuous_aggregate_api.c
@@ -220,6 +220,11 @@ policy_refresh_cagg_proc(PG_FUNCTION_ARGS)
 Datum
 policy_refresh_cagg_check(PG_FUNCTION_ARGS)
 {
+	if (PG_ARGISNULL(0))
+	{
+		ereport(ERROR, (errcode(ERRCODE_INTERNAL_ERROR), errmsg("config must not be NULL")));
+	}
+
 	policy_refresh_cagg_read_and_validate_config(PG_GETARG_JSONB_P(0), NULL);
 
 	PG_RETURN_VOID();
diff --git a/tsl/src/bgw_policy/reorder_api.c b/tsl/src/bgw_policy/reorder_api.c
index 1f7cccc32..9830eceeb 100644
--- a/tsl/src/bgw_policy/reorder_api.c
+++ b/tsl/src/bgw_policy/reorder_api.c
@@ -111,6 +111,11 @@ policy_reorder_check(PG_FUNCTION_ARGS)
 {
 	TS_PREVENT_FUNC_IF_READ_ONLY();
 
+	if (PG_ARGISNULL(0))
+	{
+		ereport(ERROR, (errcode(ERRCODE_INTERNAL_ERROR), errmsg("config must not be NULL")));
+	}
+
 	policy_reorder_read_and_validate_config(PG_GETARG_JSONB_P(0), NULL);
 
 	PG_RETURN_VOID();
diff --git a/tsl/src/bgw_policy/retention_api.c b/tsl/src/bgw_policy/retention_api.c
index e9d30cdab..beba78560 100644
--- a/tsl/src/bgw_policy/retention_api.c
+++ b/tsl/src/bgw_policy/retention_api.c
@@ -45,6 +45,11 @@ policy_retention_check(PG_FUNCTION_ARGS)
 {
 	TS_PREVENT_FUNC_IF_READ_ONLY();
 
+	if (PG_ARGISNULL(0))
+	{
+		ereport(ERROR, (errcode(ERRCODE_INTERNAL_ERROR), errmsg("config must not be NULL")));
+	}
+
 	policy_retention_read_and_validate_config(PG_GETARG_JSONB_P(0), NULL);
 
 	PG_RETURN_VOID();
diff --git a/tsl/test/expected/bgw_policy.out b/tsl/test/expected/bgw_policy.out
index 6c939eaed..55feeb64a 100644
--- a/tsl/test/expected/bgw_policy.out
+++ b/tsl/test/expected/bgw_policy.out
@@ -719,3 +719,14 @@ select * from _timescaledb_config.bgw_job where id in (:retenion_id_missing_sche
  1010 | Compression Policy [1010] | @ 1 day            | @ 0         |          -1 | @ 1 hour     | _timescaledb_internal | policy_compression | default_perm_user_2 | t         |            10 | {"hypertable_id": 10, "compress_after": 600000}     | _timescaledb_internal | policy_compression_check
 (3 rows)
 
+-- test policy check functions with NULL args
+\set ON_ERROR_STOP 0
+SELECT _timescaledb_internal.policy_compression_check(NULL);
+ERROR:  config must not be NULL
+SELECT _timescaledb_internal.policy_refresh_continuous_aggregate_check(NULL);
+ERROR:  config must not be NULL
+SELECT _timescaledb_internal.policy_reorder_check(NULL);
+ERROR:  config must not be NULL
+SELECT _timescaledb_internal.policy_retention_check(NULL);
+ERROR:  config must not be NULL
+\set ON_ERROR_STOP 1
diff --git a/tsl/test/sql/bgw_policy.sql b/tsl/test/sql/bgw_policy.sql
index fca1a2e3a..1c9aeed7a 100644
--- a/tsl/test/sql/bgw_policy.sql
+++ b/tsl/test/sql/bgw_policy.sql
@@ -363,3 +363,13 @@ alter table test_missing_schedint_integer set (timescaledb.compress);
 select add_compression_policy('test_missing_schedint_integer', BIGINT '600000') as compression_id_integer \gset
 
 select * from _timescaledb_config.bgw_job where id in (:retenion_id_missing_schedint, :compression_id_missing_schedint, :compression_id_integer);
+
+-- test policy check functions with NULL args
+\set ON_ERROR_STOP 0
+SELECT _timescaledb_internal.policy_compression_check(NULL);
+SELECT _timescaledb_internal.policy_refresh_continuous_aggregate_check(NULL);
+SELECT _timescaledb_internal.policy_reorder_check(NULL);
+SELECT _timescaledb_internal.policy_retention_check(NULL);
+\set ON_ERROR_STOP 1
+
+