Skip to content
Permalink
Browse files Browse the repository at this point in the history
v4.5.1 Fix security vulnerability and id sub-partitioning. See CHANGE…
…LOG for more details.
  • Loading branch information
keithf4 committed May 11, 2021
1 parent f0c1b58 commit 0b6565a
Show file tree
Hide file tree
Showing 11 changed files with 2,206 additions and 21 deletions.
13 changes: 13 additions & 0 deletions CHANGELOG.txt
@@ -1,3 +1,16 @@
4.5.1
NEW FEATURES
============
-- Allow relation options set on the template table to be inherited on the child table. As of PG13 and earlier, relation options set on the parent are not being set on the child tables. Unknown if PG14 will handle this yet or not (Github PR #348).

BUG FIXES
=========
-- Fixed security issue that could allow arbitrary code execution using SECURITY DEFINER functions. Set explicit search_path to avoid this. Thanks to Github user @tapioaiven of Aiven Ltd for reporting the issue.

-- Fixed several bugs in sub-partitioning when using a mixture of epoch and regular integer partitioning in the same partition set (Github Issue #357).



4.5.0
NEW FEATURES
============
Expand Down
14 changes: 7 additions & 7 deletions META.json
@@ -1,9 +1,9 @@
{
"name": "pg_partman",
"abstract": "Extension to manage partitioned tables by time or ID",
"version": "4.5.0",
"version": "4.5.1",
"maintainer": [
"Keith Fiske <keith@omniti.com>"
"Keith Fiske <keith@keithf4.com>"
],
"license": "postgresql",
"generated_by": "Keith Fiske",
Expand All @@ -20,19 +20,19 @@
},
"provides": {
"pg_partman": {
"file": "sql/pg_partman--4.5.0.sql",
"file": "sql/pg_partman--4.5.1.sql",
"docfile": "doc/pg_partman.md",
"version": "4.5.0",
"version": "4.5.1",
"abstract": "Extension to manage partitioned tables by time or ID"
}
},
"resources": {
"bugtracker": {
"web": "https://github.com/keithf4/pg_partman/issues"
"web": "https://github.com/pgpartman/pg_partman/issues"
},
"repository": {
"url": "git://github.com/keithf4/pg_partman.git" ,
"web": "https://github.com/keithf4/pg_partman",
"url": "git://github.com/pgpartman/pg_partman.git" ,
"web": "https://github.com/pgpartman/pg_partman",
"type": "git"
}
},
Expand Down
2 changes: 1 addition & 1 deletion pg_partman.control
@@ -1,3 +1,3 @@
default_version = '4.5.0'
default_version = '4.5.1'
comment = 'Extension to manage partitioned tables by time or ID'
relocatable = false
1 change: 1 addition & 0 deletions sql/functions/check_name_length.sql
@@ -1,5 +1,6 @@
CREATE FUNCTION @extschema@.check_name_length (p_object_name text, p_suffix text DEFAULT NULL, p_table_partition boolean DEFAULT FALSE) RETURNS text
LANGUAGE plpgsql IMMUTABLE SECURITY DEFINER
SET search_path TO pg_catalog, pg_temp
AS $$
DECLARE
v_new_length int;
Expand Down
7 changes: 4 additions & 3 deletions sql/functions/create_parent.sql
Expand Up @@ -32,6 +32,7 @@ v_datetime_string text;
v_default_partition text;
v_higher_control_type text;
v_higher_parent_control text;
v_higher_parent_epoch text;
v_higher_parent_schema text := split_part(p_parent_table, '.', 1);
v_higher_parent_table text := split_part(p_parent_table, '.', 2);
v_id_interval bigint;
Expand Down Expand Up @@ -562,8 +563,8 @@ IF v_control_type = 'id' AND p_epoch = 'none' THEN
JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace
WHERE n.nspname = v_higher_parent_schema::name
AND c.relname = v_higher_parent_table::name
) SELECT n.nspname, c.relname, p.control
INTO v_higher_parent_schema, v_higher_parent_table, v_higher_parent_control
) SELECT n.nspname, c.relname, p.control, p.epoch
INTO v_higher_parent_schema, v_higher_parent_table, v_higher_parent_control, v_higher_parent_epoch
FROM pg_catalog.pg_class c
JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace
JOIN top_oid t ON c.oid = t.top_parent_oid
Expand All @@ -572,7 +573,7 @@ IF v_control_type = 'id' AND p_epoch = 'none' THEN
IF v_higher_parent_table IS NOT NULL THEN
SELECT general_type INTO v_higher_control_type
FROM @extschema@.check_control_type(v_higher_parent_schema, v_higher_parent_table, v_higher_parent_control);
IF v_higher_control_type <> 'id' THEN
IF v_higher_control_type <> 'id' or (v_higher_control_type = 'id' AND v_higher_parent_epoch <> 'none') THEN
-- The parent above the p_parent_table parameter is not partitioned by ID
-- so don't check for max values in parents that aren't partitioned by ID.
-- This avoids missing child tables in subpartition sets that have differing ID data
Expand Down
2 changes: 1 addition & 1 deletion sql/functions/create_sub_parent.sql
Expand Up @@ -176,7 +176,7 @@ LOOP
RAISE EXCEPTION 'Due to conflicting data boundaries between ISO weeks and any larger interval of time, pg_partman cannot support a sub-partition interval of weekly';
END IF;

ELSIF v_control_parent_type = 'id' AND v_control_sub_type = 'id' THEN
ELSIF v_control_parent_type = 'id' AND v_control_sub_type = 'id' AND v_parent_epoch = 'none' AND p_epoch = 'none' THEN
IF p_interval::bigint >= v_parent_interval::bigint THEN
EXECUTE format('SELECT set_config(%L, %L, %L)', 'search_path', v_old_search_path, 'false');
RAISE EXCEPTION 'Sub-partition interval cannot be greater than or equal to the given parent interval';
Expand Down
30 changes: 22 additions & 8 deletions sql/functions/inherit_template_properties.sql
Expand Up @@ -14,6 +14,7 @@ v_inherit_fk boolean;
v_parent_index_list record;
v_parent_oid oid;
v_parent_table text;
v_relopt record;
v_sql text;
v_template_oid oid;
v_template_schemaname text;
Expand Down Expand Up @@ -119,14 +120,14 @@ IF current_setting('server_version_num')::int >= 100000 THEN

IF v_parent_index_list.indisprimary AND v_index_list.indisprimary THEN
IF v_parent_index_list.indkey_names = v_index_list.indkey_names THEN
RAISE DEBUG 'Ignoring duplicate primary key on template table: % ', v_index_list.indkey_names;
RAISE DEBUG 'inherit_template_properties: Ignoring duplicate primary key on template table: % ', v_index_list.indkey_names;
v_dupe_found := true;
CONTINUE; -- only continue within this nested loop
END IF;
END IF;

IF v_parent_index_list.statement = v_index_list.statement THEN
RAISE DEBUG 'Ignoring duplicate index on template table: %', v_index_list.statement;
RAISE DEBUG 'inherit_template_properties: Ignoring duplicate index on template table: %', v_index_list.statement;
v_dupe_found := true;
CONTINUE; -- only continue within this nested loop
END IF;
Expand All @@ -147,7 +148,7 @@ IF current_setting('server_version_num')::int >= 100000 THEN
IF v_index_list.tablespace_name IS NOT NULL THEN
v_sql := v_sql || format(' USING INDEX TABLESPACE %I', v_index_list.tablespace_name);
END IF;
RAISE DEBUG 'Create pk: %', v_sql;
RAISE DEBUG 'inherit_template_properties: Create pk: %', v_sql;
EXECUTE v_sql;
ELSE
-- statement column should be just the portion of the index definition that defines what it actually is
Expand All @@ -156,7 +157,7 @@ IF current_setting('server_version_num')::int >= 100000 THEN
v_sql := v_sql || format(' TABLESPACE %I', v_index_list.tablespace_name);
END IF;

RAISE DEBUG 'Create index: %', v_sql;
RAISE DEBUG 'inherit_template_properties: Create index: %', v_sql;
EXECUTE v_sql;

END IF;
Expand All @@ -176,7 +177,7 @@ IF current_setting('server_version_num')::int >= 100000 AND current_setting('ser
AND contype = 'f'
LOOP
v_sql := format('ALTER TABLE %I.%I ADD %s', v_child_schema, v_child_tablename, v_fk_list.constraint_def);
RAISE DEBUG 'Create FK: %', v_sql;
RAISE DEBUG 'inherit_template_properties: Create FK: %', v_sql;
EXECUTE v_sql;
END LOOP;
END IF;
Expand All @@ -186,7 +187,7 @@ END IF;
-- Tablespace inheritance on PG11 and earlier
IF current_setting('server_version_num')::int < 120000 AND v_template_tablespace IS NOT NULL THEN
v_sql := format('ALTER TABLE %I.%I SET TABLESPACE %I', v_child_schema, v_child_tablename, v_template_tablespace);
RAISE DEBUG 'Alter tablespace: %', v_sql;
RAISE DEBUG 'inherit_template_properties: Alter tablespace: %', v_sql;
EXECUTE v_sql;
END IF;

Expand All @@ -206,14 +207,27 @@ AND c.relname = v_child_tablename::name;

IF v_template_unlogged = 'u' AND v_child_unlogged = 'p' THEN
v_sql := format ('ALTER TABLE %I.%I SET UNLOGGED', v_child_schema, v_child_tablename);
RAISE DEBUG 'Alter UNLOGGED: %', v_sql;
RAISE DEBUG 'inherit_template_properties: Alter UNLOGGED: %', v_sql;
EXECUTE v_sql;
ELSIF v_template_unlogged = 'p' AND v_child_unlogged = 'u' THEN
v_sql := format ('ALTER TABLE %I.%I SET LOGGED', v_child_schema, v_child_tablename);
RAISE DEBUG 'Alter UNLOGGED: %', v_sql;
RAISE DEBUG 'inherit_template_properties: Alter UNLOGGED: %', v_sql;
EXECUTE v_sql;
END IF;

-- Relation options are not being inherited for PG <= 13
FOR v_relopt IN
SELECT unnest(reloptions) as value
FROM pg_catalog.pg_class
WHERE oid = v_template_oid
LOOP
v_sql := format('ALTER TABLE %I.%I SET (%s)'
, v_child_schema
, v_child_tablename
, v_relopt.value);
RAISE DEBUG 'inherit_template_properties: Set relopts: %', v_sql;
EXECUTE v_sql;
END LOOP;
RETURN true;

END
Expand Down
3 changes: 3 additions & 0 deletions sql/tables/tables.sql
Expand Up @@ -142,6 +142,7 @@ CHECK (@extschema@.check_automatic_maintenance_value(sub_automatic_maintenance))
*/
CREATE FUNCTION @extschema@.check_epoch_type (p_type text) RETURNS boolean
LANGUAGE plpgsql IMMUTABLE SECURITY DEFINER
SET search_path TO pg_catalog, pg_temp
AS $$
DECLARE
v_result boolean;
Expand All @@ -165,6 +166,7 @@ CHECK (@extschema@.check_epoch_type(sub_epoch));
*/
CREATE OR REPLACE FUNCTION @extschema@.check_partition_type (p_type text) RETURNS boolean
LANGUAGE plpgsql IMMUTABLE SECURITY DEFINER
SET search_path TO pg_catalog, pg_temp
AS $$
DECLARE
v_result boolean;
Expand All @@ -174,6 +176,7 @@ BEGIN
END
$$;


ALTER TABLE @extschema@.part_config
ADD CONSTRAINT part_config_type_check
CHECK (@extschema@.check_partition_type(partition_type));
Expand Down
@@ -1,6 +1,6 @@
-- ########## TIME DAILY TESTS ##########
-- Other tests:
-- Test using default template table. Initial child tables will have no indexes. New tables after template has indexes added should.
-- Test generated always columns

\set ON_ERROR_ROLLBACK 1
\set ON_ERROR_STOP true
Expand Down

0 comments on commit 0b6565a

Please sign in to comment.