Package: debianutils Version: 2.30 Severity: important Tags: patch Hi,
I was playing with run-parts and run it with valgrind. ==18789== LEAK SUMMARY: ==18789== definitely lost: 11,040 bytes in 46 blocks. ==18789== indirectly lost: 139,840 bytes in 1,343 blocks. ==18789== possibly lost: 0 bytes in 0 blocks. ==18789== still reachable: 32 bytes in 1 blocks. ==18789== suppressed: 0 bytes in 0 blocks. I have enclosed a patch that fixes it and explains (a bit) what I have changed. Regards, -- Franck Joncourt http://debian.org - http://smhteam.info/wiki/
From: Franck Joncourt <franck.m...@dthconnex.com> Subject: [PATCH] fixes/memory_leak The compiled patterns are created at init time only once through the regex_compile_pattern function and freed at the end with the regex_clean function. The args variable is also freed if used. Using valgrind with the following arguments against run-parts showed: valgrind -v --leak-check=yes --show-reachable=yes run_parts --test ==18789== LEAK SUMMARY: ==18789== definitely lost: 11,040 bytes in 46 blocks. ==18789== indirectly lost: 139,840 bytes in 1,343 blocks. ==18789== possibly lost: 0 bytes in 0 blocks. ==18789== still reachable: 32 bytes in 1 blocks. ==18789== suppressed: 0 bytes in 0 blocks. and now: ==18810== All heap blocks were freed -- no leaks are possible. Signed-off-by: Franck Joncourt <franck.m...@dthconnex.com> --- run-parts.c | 172 +++++++++++++++++++++++++++++++++++++++++++++++------------ 1 files changed, 137 insertions(+), 35 deletions(-) diff --git a/run-parts.c b/run-parts.c index c5de5f8..0e10f40 100644 --- a/run-parts.c +++ b/run-parts.c @@ -49,6 +49,13 @@ int argcount = 0, argsize = 0; char **args = 0; char *custom_ere; +regex_t hierre, tradre, excsre, classicalre, customre; + +static char* regex_get_error (int errcode, regex_t *compiled); +static void regex_compile_pattern (void); +static void regex_clean(void); + +void * Xmalloc (size_t size); void error(char *format, ...) { @@ -133,41 +140,26 @@ void add_argument(char *newarg) /* True or false? Is this a valid filename? */ int valid_name(const struct dirent *d) { - char *c = d->d_name; - regex_t hierre, tradre, excsre, classicalre, customre; + char *s; + unsigned int retval; - /* The regcomps should be moved to program init */ - if (regex_mode == RUNPARTS_ERE) { - if (regcomp(&customre, custom_ere, REG_EXTENDED | REG_NOSUB)) { - error("custom regex failure"); - exit(1); - } - return !regexec(&customre, c, 0, NULL, 0); - } - else if (regex_mode == RUNPARTS_LSBSYSINIT) { - - if (regcomp - (&hierre, "^_?([a-z0-9_.]+-)+[a-z0-9]+$", REG_EXTENDED | REG_NOSUB) - || regcomp(&excsre, "^[a-z0-9-].*dpkg-(old|dist|new|tmp)$", - REG_EXTENDED | REG_NOSUB) - || regcomp(&tradre, "^[a-z0-9][a-z0-9-]*$", REG_NOSUB)) { - error("regex failure"); - exit(1); - } + s = (char *)&(d->d_name); - if (!regexec(&hierre, c, 0, NULL, 0)) - return regexec(&excsre, c, 0, NULL, 0); + if (regex_mode == RUNPARTS_ERE) + retval = !regexec(&customre, s, 0, NULL, 0); - return !regexec(&tradre, c, 0, NULL, 0); - } - else { - if (regcomp(&classicalre, "^[a-zA-Z0-9_-]+$", REG_EXTENDED | REG_NOSUB)) { - error("regex failure"); - exit(1); - } - return !regexec(&classicalre, c, 0, NULL, 0); - } + else if (regex_mode == RUNPARTS_LSBSYSINIT) { + + if (!regexec(&hierre, s, 0, NULL, 0)) + retval = regexec(&excsre, s, 0, NULL, 0); + + else + retval = !regexec(&tradre, s, 0, NULL, 0); + + } else + retval = !regexec(&classicalre, s, 0, NULL, 0); + return retval; } /* Execute a file */ @@ -393,6 +385,7 @@ void run_parts(char *dirname) /* Process options */ int main(int argc, char *argv[]) { + custom_ere = NULL; umask(022); add_argument(0); @@ -452,15 +445,124 @@ int main(int argc, char *argv[]) error("missing operand"); fprintf(stderr, "Try `run-parts --help' for more information.\n"); exit(1); - } - if (list_mode && test_mode) { + } else if (list_mode && test_mode) { error("--list and --test can not be used together"); fprintf(stderr, "Try `run-parts --help' for more information.\n"); exit(1); + + } else { + + regex_compile_pattern(); + run_parts(argv[optind]); + regex_clean(); + + free(args); + free(custom_ere); + + return exitstatus; } +} + +/* + * Compile patterns used by the application + * + * In order for a string to be matched by a pattern, this pattern must be + * compiled with the regcomp function. If an error occurs, the application + * exits and displays the error. + */ +static void +regex_compile_pattern (void) +{ + int err; + regex_t *pt_regex; + + if (regex_mode == RUNPARTS_ERE) { + + if ((err = regcomp(&customre, custom_ere, + REG_EXTENDED | REG_NOSUB)) != 0) + pt_regex = &customre; + + } else if (regex_mode == RUNPARTS_LSBSYSINIT) { + + if ( (err = regcomp(&hierre, "^_?([a-z0-9_.]+-)+[a-z0-9]+$", + REG_EXTENDED | REG_NOSUB)) != 0) + pt_regex = &hierre; - run_parts(argv[optind]); + else if ( (err = regcomp(&excsre, "^[a-z0-9-].*dpkg-(old|dist|new|tmp)$", + REG_EXTENDED | REG_NOSUB)) != 0) + pt_regex = &excsre; + + else if ( (err = regcomp(&tradre, "^[a-z0-9][a-z0-9-]*$", REG_NOSUB)) + != 0) + pt_regex = &tradre; + + } else if ( (err = regcomp(&classicalre, "^[a-zA-Z0-9_-]+$", + REG_EXTENDED | REG_NOSUB)) != 0) + pt_regex = &classicalre; + + if (err != 0) { + fprintf(stderr, "Unable to build regexp: %s", \ + regex_get_error(err, pt_regex)); + exit(1); + } +} + +/* + * Get a regex error. + * + * This function allocates a buffer to store the regex error description. + * If a buffer cannot be allocated, then the use of xmalloc will end the + * program. + * + * @errcode: return error code from a one of the regex functions + * @compiled: compile pattern which causes the failure + * + * It returns a pointer on the current regex error description. + */ +static char * +regex_get_error ( + int errcode, regex_t *compiled) +{ + size_t length; + char *buf; + + length = regerror(errcode, compiled, NULL, 0); + buf = Xmalloc(length); + + regerror(errcode, compiled, buf, length); + + return buf; +} + +/* + * Clean the compiled patterns according to the current regex_mode + */ +static void +regex_clean (void) +{ + if (regex_mode == RUNPARTS_ERE) + regfree(&customre); + + else if (regex_mode == RUNPARTS_LSBSYSINIT) { + regfree(&hierre); + regfree(&excsre); + regfree(&tradre); + + } else + regfree(&classicalre); +} + +void * +Xmalloc ( + size_t size) +{ + register void *value = malloc(size); + + if (value == 0) { + error("Virtual memory exhausted\n"); + exit(1); + } - return exitstatus; + return value; } -- tg: (7f841de..) fixes/memory_leak (depends on: master)
signature.asc
Description: OpenPGP digital signature