When ebtRulesAppend failed its realloc, it was free'ing the argv it had been send, but not the rules. The caller also didn't free the rules. This is kind of a lost cause, since it's a leak that only occurs after a failure to allocate memory, but the fix also gives the ebtRuleFree function a more accurate name (ebtRuleClear), and I was making a change to this code anyway, so I split out the bugfix for easy review. --- src/util/ebtables.c | 21 +++++++-------------- 1 file changed, 7 insertions(+), 14 deletions(-) diff --git a/src/util/ebtables.c b/src/util/ebtables.c index f1b2986..d3a8432 100644 --- a/src/util/ebtables.c +++ b/src/util/ebtables.c @@ -94,7 +94,7 @@ enum { }; static void -ebtRuleFree(ebtRule *rule) +ebtRuleClear(ebtRule *rule) { VIR_FREE(rule->rule); @@ -112,20 +112,13 @@ ebtRulesAppend(ebtRules *rules, const char **argv, int command_idx) { + ebtRule tmp = { .rule = rule, .argv = argv, .command_idx = command_idx }; + if (VIR_REALLOC_N(rules->rules, rules->nrules+1) < 0) { - int i = 0; - while (argv[i]) - VIR_FREE(argv[i++]); - VIR_FREE(argv); + ebtRuleClear(&tmp); return ENOMEM; } - - rules->rules[rules->nrules].rule = rule; - rules->rules[rules->nrules].argv = argv; - rules->rules[rules->nrules].command_idx = command_idx; - - rules->nrules++; - + rules->rules[rules->nrules++] = tmp; return 0; } @@ -142,7 +135,7 @@ ebtRulesRemove(ebtRules *rules, if (i >= rules->nrules) return EINVAL; - ebtRuleFree(&rules->rules[i]); + ebtRuleClear(&rules->rules[i]); memmove(&rules->rules[i], &rules->rules[i+1], @@ -163,7 +156,7 @@ ebtRulesFree(ebtRules *rules) if (rules->rules) { for (i = 0; i < rules->nrules; i++) - ebtRuleFree(&rules->rules[i]); + ebtRuleClear(&rules->rules[i]); VIR_FREE(rules->rules); -- 1.7.11.7 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list