aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlan Jenkins <alan-jenkins@tuffmail.co.uk>2010-02-26 14:48:27 +0000
committerAlan Jenkins <alan-jenkins@tuffmail.co.uk>2010-03-02 09:10:14 +0000
commiteb1e17254348d2c9b209439826306327663e1c14 (patch)
tree2656052f20e49b9f351737c146667169fb13fe53
parent4ad092b0bf31c28ccd5c03a7d86e93eba688044b (diff)
downloadmodule-init-tools-eb1e17254348d2c9b209439826306327663e1c14.tar.gz
modprobe: clean up minor memory leaks
- "struct module" - use of setenv() - internal node leak in index_search() and index_searchwild() - some of the more obscure modprobe options, which were bypassing the cleanup code in main() I can see only one more leak (which occurred during the softdep work): - the contents of "struct modprobe_conf"
-rw-r--r--index.c15
-rw-r--r--modprobe.c46
2 files changed, 47 insertions, 14 deletions
diff --git a/index.c b/index.c
index d656c0f..a97ba1d 100644
--- a/index.c
+++ b/index.c
@@ -624,6 +624,7 @@ char *index_search(struct index_file *in, const char *key)
static char *index_search__node(struct index_node_f *node, const char *key, int i)
{
+ char *value;
struct index_node_f *child;
int ch;
int j;
@@ -640,10 +641,13 @@ static char *index_search__node(struct index_node_f *node, const char *key, int
i += j;
if (key[i] == '\0') {
- if (node->values)
- return strdup(node->values[0].value);
- else
+ if (node->values) {
+ value = strdup(node->values[0].value);
+ index_close(node);
+ return value;
+ } else {
return NULL;
+ }
}
child = index_readchild(node, key[i]);
@@ -784,9 +788,10 @@ static void index_searchwild__all(struct index_node_f *node, int j,
if (node->values) {
if (fnmatch(buf_str(buf), subkey, 0) == 0)
index_searchwild__allvalues(node, out);
+ } else {
+ index_close(node);
}
- index_close(node);
buf_popchars(buf, pushed);
}
@@ -797,4 +802,6 @@ static void index_searchwild__allvalues(struct index_node_f *node,
for (v = node->values; v != NULL; v = v->next)
add_value(out, v->value, v->priority);
+
+ index_close(node);
}
diff --git a/modprobe.c b/modprobe.c
index eec02c5..8a9c2a2 100644
--- a/modprobe.c
+++ b/modprobe.c
@@ -145,6 +145,12 @@ static void add_module(char *filename, int namelen, struct list_head *list)
list_add_tail(&mod->list, list);
}
+static void free_module(struct module *mod)
+{
+ free(mod->modname);
+ free(mod);
+}
+
/* Compare len chars of a to b, with _ and - equivalent. */
static int modname_equal(const char *a, const char *b, unsigned int len)
{
@@ -453,6 +459,19 @@ add_alias(const char *modname, struct module_alias *aliases)
return new;
}
+static void free_aliases(struct module_alias *alias_list)
+{
+ while (alias_list) {
+ struct module_alias *alias;
+
+ alias = alias_list;
+ alias_list = alias_list->next;
+
+ free(alias->module);
+ free(alias);
+ }
+}
+
/* Link in a new blacklist line from the config file. */
static struct module_blacklist *
add_blacklist(const char *modname, struct module_blacklist *blacklist)
@@ -1081,6 +1100,7 @@ static void add_to_env_var(const char *option)
char *newenv;
nofail_asprintf(&newenv, "%s %s", oldenv, option);
setenv("MODPROBE_OPTIONS", newenv, 1);
+ free(newenv);
} else
setenv("MODPROBE_OPTIONS", option, 1);
}
@@ -1159,12 +1179,14 @@ static void do_command(const char *modname,
info("%s %s\n", type, replaced_cmd);
if (dry_run)
- return;
+ goto out;
setenv("MODPROBE_MODULE", modname, 1);
ret = system(replaced_cmd);
if (ret == -1 || WEXITSTATUS(ret))
error("Error running %s command for %s\n", type, modname);
+
+out:
free(replaced_cmd);
}
@@ -1342,6 +1364,7 @@ static int insmod(struct list_head *list,
close_file(fd);
out_optstring:
free(optstring);
+ free_module(mod);
return rc;
}
@@ -1415,6 +1438,7 @@ static void rmmod(struct list_head *list,
rmmod(list, NULL, softdeps, commands, "",
configname, dirname, warn, flags);
}
+ free_module(mod);
return;
nonexistent_module:
@@ -1501,6 +1525,7 @@ int do_modprobe(const char *modulename,
{
char *modname;
struct modprobe_conf conf = {};
+ struct module_alias *filtered_aliases;
LIST_HEAD(list);
int failed = 0;
@@ -1547,17 +1572,17 @@ int do_modprobe(const char *modulename,
}
}
- conf.aliases = apply_blacklist(conf.aliases, conf.blacklist);
+ filtered_aliases = apply_blacklist(conf.aliases, conf.blacklist);
if(flags & mit_resolve_alias) {
- struct module_alias *aliases = conf.aliases;
+ struct module_alias *aliases = filtered_aliases;
for(; aliases; aliases=aliases->next)
printf("%s\n", aliases->module);
goto out;
}
- if (conf.aliases) {
+ if (filtered_aliases) {
errfn_t err = error;
- struct module_alias *aliases = conf.aliases;
+ struct module_alias *aliases = filtered_aliases;
/* More than one alias? Don't bail out on failure. */
if (aliases->next)
@@ -1587,6 +1612,7 @@ int do_modprobe(const char *modulename,
}
out:
free(modname);
+ free_aliases(filtered_aliases);
return failed;
}
@@ -1745,7 +1771,8 @@ int main(int argc, char *argv[])
if (optind+1 < argc)
fatal("Can't have multiple wildcards\n");
/* fprintf(stderr, "man find\n"); return 1; */
- return do_wildcard(dirname, type, argv[optind]?:"*");
+ failed = do_wildcard(dirname, type, argv[optind]?:"*");
+ goto out;
}
if (type)
fatal("-t only supported with -l");
@@ -1763,9 +1790,7 @@ int main(int argc, char *argv[])
read_aliases(aliasfilename, "", 1, &conf.aliases);
read_aliases(symfilename, "", 1, &conf.aliases);
- free(dirname);
- free(aliasfilename);
- exit(0);
+ goto out;
}
if ((flags & mit_remove) || all) {
@@ -1787,9 +1812,10 @@ int main(int argc, char *argv[])
configname, dirname, error, flags);
}
+
+out:
if (logging)
closelog();
-
free(dirname);
free(cmdline_opts);