Date: Mon, 9 Oct 2006 19:34:41 GMT From: Todd Miller <millert@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 107568 for review Message-ID: <200610091934.k99JYfDD093359@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=107568 Change 107568 by millert@millert_g5tower on 2006/10/09 19:34:16 Clean up buffer freeing by doing it once at the end of process_line(). Use memory more efficiently by only allocating as much as we need for each regex/type/context tuple instead of 3 * length(buffer). While here, use strok() instead of sscanf() since it is OK to modify to line_buf. Affected files ... .. //depot/projects/trustedbsd/sedarwin8/policies/sedarwin/libselinux/src/matchpathcon.c#3 edit Differences ... ==== //depot/projects/trustedbsd/sedarwin8/policies/sedarwin/libselinux/src/matchpathcon.c#3 (text+ko) ==== @@ -48,7 +48,6 @@ static int default_canoncon(const char *path, unsigned lineno, char **context) { -#ifdef notyet char *tmpcon; if (security_canonicalize_context_raw(*context, &tmpcon) < 0) { if (errno == ENOENT) @@ -62,7 +61,6 @@ } free(*context); *context = tmpcon; -#endif return 0; } @@ -444,11 +442,13 @@ static int process_line(const char *path, const char *prefix, char *line_buf, int pass, unsigned lineno) { - int items, len, regerr; + int items, len, regerr, ret; char *buf_p; char *regex, *type, *context; const char *reg_buf; char *anchored_regex; + + ret = 0; len = strlen(line_buf); if (line_buf[len - 1] == '\n') line_buf[len - 1] = 0; @@ -458,55 +458,35 @@ /* Skip comment lines and empty lines. */ if (*buf_p == '#' || *buf_p == 0) return 0; - /* XXXSEBSD - Allocate space for regex, type, and context. We do this only to - minimize diffs with stock SELinux code which uses %as in the - sscanf() format string rather than using something reasonable like - strtok() or strsep(). We additionally just assume that no substring - of line_buf can be longer than line_buf itself for this allocation. - */ - regex = (char *)malloc(strlen(line_buf) + 1); - if (regex == NULL) - return(-1); - type = (char *)malloc(strlen(line_buf) + 1); - if (type == NULL) - { - free(regex); - return(-1); - } - - context = (char *)malloc(strlen(line_buf) + 1); - if (context == NULL) - { - free(regex); - free(type); - return(-1); - } - - items = sscanf(line_buf, "%s %s %s", regex, type, context); + regex = strtok(buf_p, " \t"); + type = strtok(NULL, " \t"); + context = strtok(NULL, " \t"); + items = !!regex + !!type + !!context; if (items < 2) { myprintf("%s: line %d is missing fields, skipping\n", path, lineno); - free(regex); - free(type); - free(context); return 0; } else if (items == 2) { /* The type field is optional. */ - free(context); context = type; - type = 0; + type = NULL; + } + + regex = strdup(regex); + if (type != NULL) + type = strdup(type); + context = strdup(context); + if (!!regex + !!type + !!context != items) { + ret = -1; + goto finish; } reg_buf = regex; len = get_stem_from_spec(reg_buf); if (len && prefix && strncmp(prefix, regex, len)) { /* Stem of regex does not match requested prefix, discard. */ - free(regex); - free(type); - free(context); - return 0; + goto finish; } if (pass == 1) { @@ -519,10 +499,8 @@ len = strlen(reg_buf); cp = anchored_regex = malloc(len + 3); if (!anchored_regex) { - free(regex); - free(type); - free(context); - return -1; + ret = -1; + goto finish; } /* Create ^...$ regexp. */ *cp++ = '^'; @@ -550,10 +528,7 @@ path, lineno, anchored_regex, (errbuf ? errbuf : "out of memory")); free(anchored_regex); - free(regex); - free(type); - free(context); - return 0; + goto finish; } free(anchored_regex); @@ -566,10 +541,7 @@ if (type[0] != '-' || len != 2) { myprintf("%s: line %d has invalid file type %s\n", path, lineno, type); - free(regex); - free(type); - free(context); - return 0; + goto finish; } switch (type[1]) { case 'b': @@ -596,10 +568,7 @@ default: myprintf("%s: line %d has invalid file type %s\n", path, lineno, type); - free(regex); - free(type); - free(context); - return 0; + goto finish; } skip_type: @@ -607,20 +576,12 @@ if (myflags & MATCHPATHCON_VALIDATE) { if (myinvalidcon) { /* Old-style validation of context. */ - if (myinvalidcon(path, lineno, context)) { - free(regex); - free(type); - free(context); - return 0; - } + if (myinvalidcon(path, lineno, context)) + goto finish; } else { /* New canonicalization of context. */ - if (mycanoncon(path, lineno, &context)) { - free(regex); - free(type); - free(context); - return 0; - } + if (mycanoncon(path, lineno, &context)) + goto finish; } spec_arr[nspec].context_valid = 1; } @@ -631,16 +592,19 @@ /* Determine if specification has * any meta characters in the RE */ spec_hasMetaChars(&spec_arr[nspec]); + + /* Prevent stored strings from being freed */ + regex = NULL; + type = NULL; + context = NULL; } nspec++; - if (pass == 0) { - free(regex); - if (type) - free(type); - free(context); - } - return 0; +finish: + free(regex); + free(type); + free(context); + return ret; } int matchpathcon_init_prefix(const char *path, const char *prefix)
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200610091934.k99JYfDD093359>