From 953d8e2e755703b50318a0c2710f7cbb34667b81 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Tue, 4 Jan 2011 17:56:40 +0100 Subject: [PATCH] [PATCH 3/3] config: fix segfault in cgconfigparser We now get: Program received signal SIGSEGV, Segmentation fault. cgroup_add_controller (cgroup=0x7ffff7f86010, name=0x606300 "cpuacct") at wrapper.c:70 70 cgroup->controller[cgroup->index] = controller; (gdb) where 0 cgroup_add_controller (cgroup=0x7ffff7f86010, name=0x606300 "cpuacct") at wrapper.c:70 1 0x00007ffff79806d4 in cgroup_config_parse_controller_options (controller=0x606300 "cpuacct", values=0x6085b0) at config.c:135 2 0x00007ffff79793ec in yyparse () at parse.y:97 3 0x00007ffff7980ee1 in cgroup_config_load_config (pathname=) at config.c:667 4 0x00000000004009f4 in main (argc=3, argv=0x7fffffffdf08) at cgconfig.c:67 It's because cgroup structure is unitialized. Especially its member index is not and later we access cgroup->controller[cgroup->index] with cgroup->index negative and kaboom, we explode. Use calloc and realloc+memset to avoid that. Signed-off-by: Jiri Slaby Signed-off-by: Balbir Singh --- src/config.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/config.c b/src/config.c index 513f95d8..23e1e430 100644 --- a/src/config.c +++ b/src/config.c @@ -88,10 +88,13 @@ int cgroup_config_insert_cgroup(char *cg_name) if (cgroup_table_index >= MAX_CGROUPS - 1) { struct cgroup *newblk; + unsigned int oldlen; + if (MAX_CGROUPS >= INT_MAX) { last_errno = ENOMEM; return 0; } + oldlen = MAX_CGROUPS; MAX_CGROUPS *= 2; newblk = realloc(config_cgroup_table, (MAX_CGROUPS * sizeof(struct cgroup))); @@ -99,6 +102,9 @@ int cgroup_config_insert_cgroup(char *cg_name) last_errno = ENOMEM; return 0; } + + memset(newblk + oldlen, 0, (MAX_CGROUPS - oldlen) * + sizeof(struct cgroup)); config_cgroup_table = newblk; cgroup_dbg("MAX_CGROUPS %d\n", MAX_CGROUPS); cgroup_dbg("reallocated config_cgroup_table to %p\n", config_cgroup_table); @@ -663,7 +669,7 @@ int cgroup_config_load_config(const char *pathname) return ECGOTHER; } - config_cgroup_table = malloc(MAX_CGROUPS * sizeof(struct cgroup)); + config_cgroup_table = calloc(MAX_CGROUPS, sizeof(struct cgroup)); if (yyparse() != 0) { cgroup_dbg("Failed to parse file %s\n", pathname); fclose(yyin); -- 2.47.2