]> git.ipfire.org Git - thirdparty/libcgroup.git/commitdiff
[PATCH 3/3] config: fix segfault in cgconfigparser
authorJiri Slaby <jslaby@suse.cz>
Tue, 4 Jan 2011 16:56:40 +0000 (17:56 +0100)
committerBalbir Singh <balbir@linux.vnet.ibm.com>
Wed, 5 Jan 2011 15:32:41 +0000 (21:02 +0530)
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=<value optimized out>) 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 <jslaby@suse.cz>
Signed-off-by: Balbir Singh <balbir@linux.vnet.ibm.com>
src/config.c

index 513f95d835834a979afe9f3f430b89235408c415..23e1e430d419e58b7b1195da3c0c9c3eebbfbb22 100644 (file)
@@ -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);