Skip to content

Commit 92bee97

Browse files
RMTTmy-ship-it
authored andcommitted
io limit: fix double free (#16459)
io limit: fix double free. In 'alterResgroupCallback', the io_limit pointer of 'caps' and 'oldCaps' maybe point to the same location, so there is a double free potentially. In 'alterResgroupCallback', the 'oldCaps' will be filled in 'GetResGroupCapabilities', and the assign it to 'caps' via: caps = oldCaps To resolve this problem, the code should free the oldCaps.io_limit, and set it to NIL, when the io_limit has not been altered. So, if the io_limit has not been altered, caps.io_limit = oldCaps.io_limit = NIL. If io_limit has been altered, caps.io_limit != oldCaps.io_limit.
1 parent 6080221 commit 92bee97

3 files changed

Lines changed: 24 additions & 3 deletions

File tree

src/backend/commands/resgroupcmds.c

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -438,6 +438,12 @@ AlterResourceGroup(AlterResourceGroupStmt *stmt)
438438

439439
/* Load current resource group capabilities */
440440
GetResGroupCapabilities(pg_resgroupcapability_rel, groupid, &oldCaps);
441+
/* If io_limit not been altered, reset io_limit field to NIL */
442+
if (limitType != RESGROUP_LIMIT_TYPE_IO_LIMIT && oldCaps.io_limit != NIL)
443+
{
444+
cgroupOpsRoutine->freeio(oldCaps.io_limit);
445+
oldCaps.io_limit = NIL;
446+
}
441447
caps = oldCaps;
442448

443449
switch (limitType)
@@ -479,6 +485,8 @@ AlterResourceGroup(AlterResourceGroupStmt *stmt)
479485
}
480486

481487
validateCapabilities(pg_resgroupcapability_rel, groupid, &caps, false);
488+
AssertImply(limitType != RESGROUP_LIMIT_TYPE_IO_LIMIT, caps.io_limit == NIL);
489+
AssertImply(limitType == RESGROUP_LIMIT_TYPE_IO_LIMIT, caps.io_limit != NIL);
482490

483491
/* cpuset & cpu_max_percent can not coexist.
484492
* if cpuset is active, then cpu_max_percent must set to CPU_RATE_LIMIT_DISABLED,
@@ -1123,7 +1131,7 @@ alterResgroupCallback(XactEvent event, void *arg)
11231131
if (callbackCtx->caps.io_limit != NIL)
11241132
cgroupOpsRoutine->freeio(callbackCtx->caps.io_limit);
11251133

1126-
if (callbackCtx->caps.io_limit != NIL)
1134+
if (callbackCtx->oldCaps.io_limit != NIL)
11271135
cgroupOpsRoutine->freeio(callbackCtx->oldCaps.io_limit);
11281136

11291137
pfree(callbackCtx);

src/test/isolation2/input/resgroup/resgroup_io_limit.source

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,8 @@ ALTER RESOURCE GROUP rg_test_group5 SET io_limit 'rg_io_limit_ts_1:rbps=1000,wbp
5656

5757
SELECT check_cgroup_io_max('rg_test_group5', 'rg_io_limit_ts_1', 'rbps=1048576000 wbps=1048576000 riops=max wiops=max');
5858

59+
ALTER RESOURCE GROUP rg_test_group5 SET concurrency 1;
60+
5961
SELECT check_clear_io_max('rg_test_group5');
6062

6163
-- fault injector
@@ -67,11 +69,13 @@ SELECT groupid, groupname, cpuset FROM gp_toolkit.gp_resgroup_config WHERE group
6769

6870
SELECT gp_inject_fault('create_resource_group_fail', 'reset', 1);
6971

70-
-- start_ignore
7172
-- view
73+
-- start_ignore
7274
SELECT * from gp_toolkit.gp_resgroup_iostats_per_host;
7375
-- end_ignore
7476

77+
SELECT count(*) > 0 as r from gp_toolkit.gp_resgroup_iostats_per_host;
78+
7579
-- clean
7680
DROP RESOURCE GROUP rg_test_group1;
7781
DROP RESOURCE GROUP rg_test_group2;

src/test/isolation2/output/resgroup/resgroup_io_limit.source

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,9 @@ SELECT check_cgroup_io_max('rg_test_group5', 'rg_io_limit_ts_1', 'rbps=104857600
107107
t
108108
(1 row)
109109

110+
ALTER RESOURCE GROUP rg_test_group5 SET concurrency 1;
111+
ALTER
112+
110113
SELECT check_clear_io_max('rg_test_group5');
111114
check_clear_io_max
112115
--------------------
@@ -134,8 +137,8 @@ SELECT gp_inject_fault('create_resource_group_fail', 'reset', 1);
134137
Success:
135138
(1 row)
136139

137-
-- start_ignore
138140
-- view
141+
-- start_ignore
139142
SELECT * from gp_toolkit.gp_resgroup_iostats_per_host;
140143
rsgname | hostname | tablespace | rbps | wbps | riops | wiops
141144
----------------+----------+------------------+------+------+-------+-------
@@ -147,6 +150,12 @@ SELECT * from gp_toolkit.gp_resgroup_iostats_per_host;
147150
(5 rows)
148151
-- end_ignore
149152

153+
SELECT count(*) > 0 as r from gp_toolkit.gp_resgroup_iostats_per_host;
154+
r
155+
------
156+
t
157+
(1 row)
158+
150159
-- clean
151160
DROP RESOURCE GROUP rg_test_group1;
152161
DROP

0 commit comments

Comments
 (0)