Browse code

cfg framework: mem leak in del_group_inst is corrected

cfg_del_group_inst() did not free the strings that were
set within the group instance. When the group instance was
deleted, the strings left allocated.

Miklos Tirpak authored on 04/01/2011 10:14:30
Showing 1 changed files
... ...
@@ -1521,6 +1521,8 @@ int cfg_del_group_inst(cfg_ctx_t *ctx, str *group_name, unsigned int group_id)
1521 1521
 	cfg_block_t	*block = NULL;
1522 1522
 	void		**replaced = NULL;
1523 1523
 	cfg_group_inst_t	*new_array = NULL, *group_inst;
1524
+	cfg_mapping_t	*var;
1525
+	int		i, num;
1524 1526
 
1525 1527
 	/* verify the context even if we do not need it now
1526 1528
 	to make sure that a cfg driver has called the function
... ...
@@ -1571,13 +1573,41 @@ int cfg_del_group_inst(cfg_ctx_t *ctx, str *group_name, unsigned int group_id)
1571 1573
 		/* prepare the array of the replaced strings,
1572 1574
 		and replaced group instances,
1573 1575
 		they will be freed when the old block is freed */
1574
-		replaced = (void **)shm_malloc(sizeof(void *) * 2);
1576
+
1577
+		/* count the number of strings that has to be freed */
1578
+		num = 0;
1579
+		for (i = 0; i < group->num; i++) {
1580
+			var = &group->mapping[i];
1581
+			if (CFG_VAR_TEST(group_inst, var)
1582
+				&& ((CFG_VAR_TYPE(var) == CFG_VAR_STRING) || (CFG_VAR_TYPE(var) == CFG_VAR_STR))
1583
+				&& (*(char **)(group_inst->vars + var->offset) != NULL)
1584
+			)
1585
+				num++;
1586
+		}
1587
+
1588
+		replaced = (void **)shm_malloc(sizeof(void *) * (num + 2));
1575 1589
 		if (!replaced) {
1576 1590
 			LOG(L_ERR, "ERROR: cfg_del_group_inst(): not enough shm memory\n");
1577 1591
 			goto error;
1578 1592
 		}
1579
-		replaced[0] = CFG_GROUP_META(*cfg_global, group)->array;
1580
-		replaced[1] = NULL;
1593
+
1594
+		if (num) {
1595
+			/* There was at least one string to free, go though the list again */
1596
+			num = 0;
1597
+			for (i = 0; i < group->num; i++) {
1598
+				var = &group->mapping[i];
1599
+				if (CFG_VAR_TEST(group_inst, var)
1600
+					&& ((CFG_VAR_TYPE(var) == CFG_VAR_STRING) || (CFG_VAR_TYPE(var) == CFG_VAR_STR))
1601
+					&& (*(char **)(group_inst->vars + var->offset) != NULL)
1602
+				) {
1603
+					replaced[num] = *(char **)(group_inst->vars + var->offset);
1604
+					num++;
1605
+				}
1606
+			}
1607
+		}
1608
+
1609
+		replaced[num] = CFG_GROUP_META(*cfg_global, group)->array;
1610
+		replaced[num+1] = NULL;
1581 1611
 	}
1582 1612
 	/* replace the global config with the new one */
1583 1613
 	cfg_install_global(block, replaced, NULL, NULL);