-
Notifications
You must be signed in to change notification settings - Fork 31
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Alternatives: Fix issues found by static analyzers #126
Conversation
Error: RESOURCE_LEAK (CWE-772): chkconfig-1.26/alternatives.c:328: alloc_fn: Storage is returned from allocation function "parseLine". chkconfig-1.26/alternatives.c:328: var_assign: Assigning: "line" = storage returned from "parseLine(&buf)". chkconfig-1.26/alternatives.c:331: leaked_storage: Variable "line" going out of scope leaks the storage it points to. 329| if (!line || *line != '/') { 330| fprintf(stderr, _("bad primary link in %s\n"), path); 331|-> return 1; 332| } 333|
This should be a no-op but it hardens the code and also makes static analyzers a bit more happy.
Error: RESOURCE_LEAK (CWE-772): chkconfig-1.26/alternatives.c:441: alloc_fn: Storage is returned from allocation function "parseLine". chkconfig-1.26/alternatives.c:441: var_assign: Assigning: "line" = storage returned from "parseLine(&buf)". chkconfig-1.26/alternatives.c:445: overwrite_var: Overwriting "line" in "line = parseLine(&buf)" leaks the storage that "line" points to. 443| 444| while (line) { 445|-> line = parseLine(&buf); 446| if (line && *line) { 447| fprintf(stderr, _("unexpected line in %s: %s\n"), path, line);
Error: RESOURCE_LEAK (CWE-772): chkconfig-1.26/alternatives.c:339: alloc_fn: Storage is returned from allocation function "parseLine". chkconfig-1.26/alternatives.c:339: var_assign: Assigning: "line" = storage returned from "parseLine(&buf)". chkconfig-1.26/alternatives.c:342: noescape: Resource "line" is not freed or pointed-to in "fprintf". [Note: The source code implementation of the function has been overridden by a builtin model.] chkconfig-1.26/alternatives.c:343: leaked_storage: Variable "line" going out of scope leaks the storage it points to. 341| if (*line == '/') { 342| fprintf(stderr, _("path %s unexpected in %s\n"), line, path); 343|-> return 1; 344| } 345|
Error: RESOURCE_LEAK (CWE-772): [#def1] [important] chkconfig-1.26/alternatives.c:312:5: alloc_fn: Storage is returned from allocation function "parseLine". chkconfig-1.26/alternatives.c:312:5: var_assign: Assigning: "line" = storage returned from "parseLine(&buf)". chkconfig-1.26/alternatives.c:318:5: noescape: Resource "line" is not freed or pointed-to in "strcmp". chkconfig-1.26/alternatives.c:320:12: noescape: Resource "line" is not freed or pointed-to in "strcmp". chkconfig-1.26/alternatives.c:324:9: leaked_storage: Variable "line" going out of scope leaks the storage it points to. 322| } else { 323| fprintf(stderr, _("bad mode on line 1 of %s\n"), path); 324|-> return 1; 325| } 326| free(line);
Error: STRING_NULL (CWE-170): [#def1] [important] chkconfig-1.26/alternatives.c:591:13: string_null_source: Function "readlink" does not terminate string "buf". [Note: The source code implementation of the function has been overridden by a builtin model.] chkconfig-1.26/alternatives.c:593:13: string_null: Passing unterminated string "buf" to "streq", which expects a null-terminated string. 591| readlink(l->facility, buf, sizeof(buf)); 592| 593|-> if(!streq(sl, buf)) { 594| unlink(l->facility); 595| Error: STRING_NULL (CWE-170): [#def2] [important] chkconfig-1.26/alternatives.c:609:9: string_null_source: Function "readlink" does not terminate string "buf". [Note: The source code implementation of the function has been overridden by a builtin model.] chkconfig-1.26/alternatives.c:611:9: string_null: Passing unterminated string "buf" to "streq", which expects a null-terminated string. 609| readlink(sl, buf, sizeof(buf)); 610| 611|-> if(!streq(l->target, buf)) { 612| if (unlink(sl) && errno != ENOENT) { 613| fprintf(stderr, _("failed to remove link %s: %s\n"), sl,
Error: RESOURCE_LEAK (CWE-772): [#def3] [important] chkconfig-1.26/alternatives.c:794:9: alloc_fn: Storage is returned from allocation function "malloc". chkconfig-1.26/alternatives.c:794:9: var_assign: Assigning: "newLinks" = storage returned from "malloc(24UL * template.numFollowers)". chkconfig-1.26/alternatives.c:798:9: identity_transfer: Passing "newLinks" as argument 1 to function "memset", which returns that argument. [Note: The source code implementation of the function has been overridden by a builtin model.] chkconfig-1.26/alternatives.c:798:9: noescape: Resource "newLinks" is not freed or pointed-to in "memset". [Note: The source code implementation of the function has been overridden by a builtin model.] chkconfig-1.26/alternatives.c:798:9: var_assign: Assigning: "newLinks" = storage returned from "memset(newLinks, 0, 24UL * template.numFollowers)". chkconfig-1.26/alternatives.c:817:21: leaked_storage: Variable "newLinks" going out of scope leaks the storage it points to. 815| set->alts[k].followers[i].title, 816| template.followers[j].facility, template.followers[j].title); 817|-> return 2; 818| } 819| newLinks[j] = set->alts[k].followers[i];
Error: RESOURCE_LEAK (CWE-772): [#def4] [important] chkconfig-1.26/alternatives.c:1255:5: alloc_fn: Storage is returned from allocation function "opendir". chkconfig-1.26/alternatives.c:1255:5: var_assign: Assigning: "dir" = storage returned from "opendir(stateDir)". chkconfig-1.26/alternatives.c:1259:5: noescape: Resource "dir" is not freed or pointed-to in "readdir". chkconfig-1.26/alternatives.c:1259:5: noescape: Resource "dir" is not freed or pointed-to in "readdir". chkconfig-1.26/alternatives.c:1267:5: noescape: Resource "dir" is not freed or pointed-to in "rewinddir". chkconfig-1.26/alternatives.c:1269:5: noescape: Resource "dir" is not freed or pointed-to in "readdir". chkconfig-1.26/alternatives.c:1274:13: leaked_storage: Variable "dir" going out of scope leaks the storage it points to. 1272| 1273| if (readConfig(&set, ent->d_name, altDir, stateDir, flags)) 1274|-> return 2; 1275| 1276| printf("%-*s\t%s\t%s\n", max_name, ent->d_name,
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
} | ||
|
||
groups = realloc(groups, sizeof(*groups) * (numGroups + 1)); | ||
groups[numGroups].title = line; | ||
groups[numGroups].title = strsteal(&line); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This can still leak if goto finish
happens before numGroups
is incremented.
} | ||
*end = '\0'; | ||
set->alts[set->numAlts].family = strdup(line); | ||
line = end + 1; | ||
set->alts[set->numAlts].family = strdup(ptr); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ditto. set->numAlts
is only incremented at the end. If goto finish
happens before that, the current, partially initialized, entry won't be freed.
Alternatives are properly covered by the test suite and it passes, so this portion should be safe to merge.