This is an automated email from the ASF dual-hosted git repository. maxyang pushed a commit to branch main in repository https://gitbox.apache.org/repos/asf/cloudberry.git
commit 6264eba3929960b09991e34730731cab565d779d Author: Xing Guo <[email protected]> AuthorDate: Thu Apr 7 22:07:28 2022 +0800 Fix potential nullptr dereference issue. (#12780) The returned relation 'auxRel' of 'try_relation_open()' is not checked. Though it's safe to pass nullptr to 'calculate_total_relation_size()', 'relation_close()' needs a valid pointer. SQL to reproduce: ```sql CREATE TABLE ao_with_malformed_visimaprelid (a int) WITH (appendonly=true); -- Set visimaprelid record in the pg_appendonly table to a malformed value. SET allow_system_table_mods=true; UPDATE pg_appendonly SET visimaprelid=16383 WHERE relid=(SELECT oid FROM pg_class WHERE relname='ao_with_malformed_visimaprelid'); SELECT pg_table_size('ao_with_malformed_visimaprelid'); ``` --- src/backend/utils/adt/dbsize.c | 17 ++++++++++++++--- src/test/regress/expected/db_size_functions.out | 12 ++++++++++++ src/test/regress/init_file | 2 ++ src/test/regress/sql/db_size_functions.sql | 9 +++++++++ 4 files changed, 37 insertions(+), 3 deletions(-) diff --git a/src/backend/utils/adt/dbsize.c b/src/backend/utils/adt/dbsize.c index 2716b653d5..269ff8724b 100644 --- a/src/backend/utils/adt/dbsize.c +++ b/src/backend/utils/adt/dbsize.c @@ -656,9 +656,20 @@ calculate_table_size(Relation rel) if (!OidIsValid(auxRelIds[i])) continue; - auxRel = try_relation_open(auxRelIds[i], AccessShareLock, false); - size += calculate_total_relation_size(auxRel); - relation_close(auxRel, AccessShareLock); + if ((auxRel = try_relation_open(auxRelIds[i], AccessShareLock, false)) != NULL) + { + size += calculate_total_relation_size(auxRel); + relation_close(auxRel, AccessShareLock); + } + else + { + /* + * This error may occur when the auxiliary relations' records of + * the appendonly table are corrupted. + */ + elog(ERROR, "invalid auxiliary relation oid %u for appendonly relation '%s'", + auxRelIds[i], rel->rd_rel->relname.data); + } } } diff --git a/src/test/regress/expected/db_size_functions.out b/src/test/regress/expected/db_size_functions.out index 9c13160b1f..e45b84e5ea 100644 --- a/src/test/regress/expected/db_size_functions.out +++ b/src/test/regress/expected/db_size_functions.out @@ -311,6 +311,18 @@ select pg_total_relation_size('aocssizetest') = pg_table_size('aocssizetest'); t (1 row) +-- Test when the auxiliary relation of AO table is corrupted, the database will not PANIC. +create table ao_with_malformed_visimaprelid (a int) with (appendonly=true); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'a' as the Greenplum Database data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. +-- Set visimaprelid record in the pg_appendonly table to a malformed value. +set allow_system_table_mods=true; +update pg_appendonly + set visimaprelid=16383 + where relid=(select oid from pg_class where relname='ao_with_malformed_visimaprelid'); +select pg_table_size('ao_with_malformed_visimaprelid'); +ERROR: invalid auxiliary relation oid 16383 for appendonly relation 'ao_with_malformed_visimaprelid' (dbsize.c:610) +drop table ao_with_malformed_visimaprelid; -- Also test pg_relation_size() in a query that selects from pg_class. It is a -- very typical way to use the functions, so make sure it works. (A -- plausible difference to the above scenarios would be that the function diff --git a/src/test/regress/init_file b/src/test/regress/init_file index 1ab637b69b..82d43ca51c 100644 --- a/src/test/regress/init_file +++ b/src/test/regress/init_file @@ -171,5 +171,7 @@ m/ The shortest establish conn time: \d+\.\d+ ms, segindex: \d+,/ s/ The shortest establish conn time: \d+\.\d+ ms, segindex: \d+,/ The shortest establish conn time: xx\.xx ms, segindex: xx,/ m/ The longest establish conn time: \d+\.\d+ ms, segindex: \d+/ s/ The longest establish conn time: \d+\.\d+ ms, segindex: \d+/ The longest establish conn time: xx\.xx ms, segindex: xx/ +m/\(dbsize\.c\:\d+\)/ +s/\(dbsize\.c:\d+\)/\(dbsize\.c:XXX\)/ -- end_matchsubs diff --git a/src/test/regress/sql/db_size_functions.sql b/src/test/regress/sql/db_size_functions.sql index f5ec4ebfe8..63ef0a5f3d 100644 --- a/src/test/regress/sql/db_size_functions.sql +++ b/src/test/regress/sql/db_size_functions.sql @@ -96,6 +96,15 @@ select pg_table_size('aocssizetest') > pg_relation_size('aocssizetest'); select pg_total_relation_size('aocssizetest') between 1500000 and 3000000; -- 1884456 select pg_total_relation_size('aocssizetest') = pg_table_size('aocssizetest'); +-- Test when the auxiliary relation of AO table is corrupted, the database will not PANIC. +create table ao_with_malformed_visimaprelid (a int) with (appendonly=true); +-- Set visimaprelid record in the pg_appendonly table to a malformed value. +set allow_system_table_mods=true; +update pg_appendonly + set visimaprelid=16383 + where relid=(select oid from pg_class where relname='ao_with_malformed_visimaprelid'); +select pg_table_size('ao_with_malformed_visimaprelid'); +drop table ao_with_malformed_visimaprelid; -- Also test pg_relation_size() in a query that selects from pg_class. It is a -- very typical way to use the functions, so make sure it works. (A --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
