]> granicus.if.org Git - sudo/commitdiff
Add simple reference-counted string allocator and use it for passing
authorTodd C. Miller <Todd.Miller@courtesan.com>
Fri, 11 Nov 2016 23:18:27 +0000 (16:18 -0700)
committerTodd C. Miller <Todd.Miller@courtesan.com>
Fri, 11 Nov 2016 23:18:27 +0000 (16:18 -0700)
around references to the sudoers path.  This lets us avoid making
copies of the sudoers path for the errorfile as well as each Defaults
entry.

MANIFEST
plugins/sudoers/Makefile.in
plugins/sudoers/gram.c
plugins/sudoers/gram.y
plugins/sudoers/rcstr.c [new file with mode: 0644]
plugins/sudoers/sudoers.h
plugins/sudoers/toke.c
plugins/sudoers/toke.l
plugins/sudoers/visudo.c
plugins/sudoers/visudo_json.c

index 2803d1a30870d279c2a5dd03683c647554a967d7..564a1e4c26b59edf9c46738eb983867d0c502cce 100644 (file)
--- a/MANIFEST
+++ b/MANIFEST
@@ -357,6 +357,7 @@ plugins/sudoers/prompt.c
 plugins/sudoers/pwutil.c
 plugins/sudoers/pwutil.h
 plugins/sudoers/pwutil_impl.c
+plugins/sudoers/rcstr.c
 plugins/sudoers/redblack.c
 plugins/sudoers/redblack.h
 plugins/sudoers/regress/check_symbols/check_symbols.c
index 2a035a5b576e7ebcc16206267526b4bc42c12a16..1ee537faafe9c8c723937b868e3540c271e52226 100644 (file)
@@ -148,8 +148,8 @@ AUTH_OBJS = sudo_auth.lo @AUTH_OBJS@
 
 LIBPARSESUDOERS_OBJS = alias.lo audit.lo base64.lo defaults.lo hexchar.lo \
                       gram.lo match.lo match_addr.lo pwutil.lo pwutil_impl.lo \
-                      redblack.lo sudoers_debug.lo timestr.lo toke.lo \
-                      toke_util.lo
+                      rcstr.lo redblack.lo sudoers_debug.lo timestr.lo \
+                      toke.lo toke_util.lo
 
 SUDOERS_OBJS = $(AUTH_OBJS) boottime.lo check.lo editor.lo env.lo find_path.lo \
               gc.lo goodpath.lo group_plugin.lo interfaces.lo iolog.lo \
@@ -918,6 +918,14 @@ pwutil_impl.lo: $(srcdir)/pwutil_impl.c $(devdir)/def_data.h \
                 $(top_builddir)/pathnames.h
        $(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c $(CPPFLAGS) $(CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/pwutil_impl.c
 pwutil_impl.o: pwutil_impl.lo
+rcstr.lo: $(srcdir)/rcstr.c $(devdir)/def_data.h $(incdir)/compat/stdbool.h \
+          $(incdir)/sudo_compat.h $(incdir)/sudo_conf.h $(incdir)/sudo_debug.h \
+          $(incdir)/sudo_fatal.h $(incdir)/sudo_gettext.h \
+          $(incdir)/sudo_plugin.h $(incdir)/sudo_queue.h $(incdir)/sudo_util.h \
+          $(srcdir)/defaults.h $(srcdir)/logging.h $(srcdir)/sudo_nss.h \
+          $(srcdir)/sudoers.h $(srcdir)/sudoers_debug.h \
+          $(top_builddir)/config.h $(top_builddir)/pathnames.h
+       $(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c $(CPPFLAGS) $(CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/rcstr.c
 redblack.lo: $(srcdir)/redblack.c $(devdir)/def_data.h \
              $(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
              $(incdir)/sudo_conf.h $(incdir)/sudo_debug.h \
index ef2b279c1973c29da0b55c18f08a4f6cd1229ad2..896cb0b0d8bbf0b19a07c4a44e0e8f7ac2eabdab 100644 (file)
@@ -702,11 +702,8 @@ sudoerserror(const char *s)
     /* Save the line the first error occurred on. */
     if (errorlineno == -1) {
        errorlineno = sudolineno;
-       free(errorfile);
-       errorfile = strdup(sudoers);
-       if (errorfile == NULL)
-           sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
-               "unable to allocate memory");
+       rcstr_delref(errorfile);
+       errorfile = rcstr_addref(sudoers);
     }
     if (sudoers_warnings && s != NULL) {
        LEXTRACE("<*> ");
@@ -744,13 +741,7 @@ new_default(char *var, char *val, short op)
     d->op = op;
     /* d->binding = NULL */
     d->lineno = last_token == COMMENT ? sudolineno - 1 : sudolineno;
-    d->file = strdup(sudoers);
-    if (d->file == NULL) {
-       sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
-           "unable to allocate memory");
-       free(d);
-       debug_return_ptr(NULL);
-    }
+    d->file = rcstr_addref(sudoers);
     HLTQ_INIT(d, entries);
 
     debug_return_ptr(d);
@@ -981,10 +972,9 @@ init_parser(const char *path, bool quiet)
            free_members(d->binding);
            free(d->binding);
        }
-       /* no need to free sd_un */
+       rcstr_delref(d->file);
        free(d->var);
        free(d->val);
-       free(d->file);
        free(d);
     }
     TAILQ_INIT(&defaults);
@@ -996,9 +986,9 @@ init_parser(const char *path, bool quiet)
        ret = false;
     }
 
-    free(sudoers);
+    rcstr_delref(sudoers);
     if (path != NULL) {
-       if ((sudoers = strdup(path)) == NULL) {
+       if ((sudoers = rcstr_dup(path)) == NULL) {
            sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
            ret = false;
        }
@@ -1008,13 +998,13 @@ init_parser(const char *path, bool quiet)
 
     parse_error = false;
     errorlineno = -1;
-    free(errorfile);
+    rcstr_delref(errorfile);
     errorfile = NULL;
     sudoers_warnings = !quiet;
 
     debug_return_bool(ret);
 }
-#line 965 "gram.c"
+#line 955 "gram.c"
 /* allocate initial stack or double stack size, up to YYMAXDEPTH */
 #if defined(__cplusplus) || defined(__STDC__)
 static int yygrowstack(void)
@@ -2097,7 +2087,7 @@ case 115:
                            }
                        }
 break;
-#line 2048 "gram.c"
+#line 2038 "gram.c"
     }
     yyssp -= yym;
     yystate = *yyssp;
index 70e24f78e716d3c59de7be8f56d7f2f33084c84b..c58aeeb098961ae4cc25d9532f2303f3e3d6903a 100644 (file)
@@ -858,11 +858,8 @@ sudoerserror(const char *s)
     /* Save the line the first error occurred on. */
     if (errorlineno == -1) {
        errorlineno = sudolineno;
-       free(errorfile);
-       errorfile = strdup(sudoers);
-       if (errorfile == NULL)
-           sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
-               "unable to allocate memory");
+       rcstr_delref(errorfile);
+       errorfile = rcstr_addref(sudoers);
     }
     if (sudoers_warnings && s != NULL) {
        LEXTRACE("<*> ");
@@ -900,13 +897,7 @@ new_default(char *var, char *val, short op)
     d->op = op;
     /* d->binding = NULL */
     d->lineno = last_token == COMMENT ? sudolineno - 1 : sudolineno;
-    d->file = strdup(sudoers);
-    if (d->file == NULL) {
-       sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
-           "unable to allocate memory");
-       free(d);
-       debug_return_ptr(NULL);
-    }
+    d->file = rcstr_addref(sudoers);
     HLTQ_INIT(d, entries);
 
     debug_return_ptr(d);
@@ -1137,10 +1128,9 @@ init_parser(const char *path, bool quiet)
            free_members(d->binding);
            free(d->binding);
        }
-       /* no need to free sd_un */
+       rcstr_delref(d->file);
        free(d->var);
        free(d->val);
-       free(d->file);
        free(d);
     }
     TAILQ_INIT(&defaults);
@@ -1152,9 +1142,9 @@ init_parser(const char *path, bool quiet)
        ret = false;
     }
 
-    free(sudoers);
+    rcstr_delref(sudoers);
     if (path != NULL) {
-       if ((sudoers = strdup(path)) == NULL) {
+       if ((sudoers = rcstr_dup(path)) == NULL) {
            sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
            ret = false;
        }
@@ -1164,7 +1154,7 @@ init_parser(const char *path, bool quiet)
 
     parse_error = false;
     errorlineno = -1;
-    free(errorfile);
+    rcstr_delref(errorfile);
     errorfile = NULL;
     sudoers_warnings = !quiet;
 
diff --git a/plugins/sudoers/rcstr.c b/plugins/sudoers/rcstr.c
new file mode 100644 (file)
index 0000000..e3f461b
--- /dev/null
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 2016 Todd C. Miller <Todd.Miller@courtesan.com>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <config.h>
+
+#include <sys/types.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdbool.h>
+#ifdef HAVE_STRING_H
+# include <string.h>
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif /* HAVE_STRINGS_H */
+
+#include "sudoers.h"
+
+/* Trivial reference-counted strings. */
+struct rcstr {
+    int refcnt;
+    char str[1];       /* actually bigger */
+};
+
+/*
+ * Allocate a reference-counted string and copy src to it.
+ * Returns the newly-created string with a refcnt of 1.
+ */
+char *
+rcstr_dup(const char *src)
+{
+    size_t len = strlen(src);
+    char *dst;
+    debug_decl(rcstr_dup, SUDOERS_DEBUG_UTIL)
+
+    dst = rcstr_alloc(len);
+    memcpy(dst, src, len);
+    dst[len] = '\0';
+    debug_return_ptr(dst);
+}
+
+char *
+rcstr_alloc(size_t len)
+{
+    struct rcstr *rcs;
+    debug_decl(rcstr_dup, SUDOERS_DEBUG_UTIL)
+
+    /* Note: sizeof(struct rcstr) includes space for the NUL */
+    rcs = malloc(sizeof(struct rcstr) + len);
+    if (rcs == NULL)
+       return NULL;
+
+    rcs->refcnt = 1;
+    rcs->str[0] = '\0';
+    debug_return_ptr(rcs->str);
+}
+
+char *
+rcstr_addref(const char *s)
+{
+    struct rcstr *rcs;
+    debug_decl(rcstr_dup, SUDOERS_DEBUG_UTIL)
+
+    if (s == NULL)
+       debug_return_ptr(NULL);
+
+    rcs = __containerof(s, struct rcstr, str);
+    rcs->refcnt++;
+    debug_return_ptr(rcs->str);
+}
+
+void
+rcstr_delref(const char *s)
+{
+    struct rcstr *rcs;
+    debug_decl(rcstr_dup, SUDOERS_DEBUG_UTIL)
+
+    if (s != NULL) {
+       rcs = __containerof(s, struct rcstr, str);
+       if (--rcs->refcnt == 0) {
+           rcs->str[0] = '\0';
+           free(rcs);
+       }
+    }
+    debug_return;
+}
index 65952a5442af0fb52a2f592b3beb03ccb104dcfe..1971ac82a90f270f9db1b02efe98c66be6cadc97 100644 (file)
@@ -403,4 +403,10 @@ bool sudoers_gc_add(enum sudoers_gc_types type, void *ptr);
 bool sudoers_gc_remove(enum sudoers_gc_types type, void *ptr);
 void sudoers_gc_init(void);
 
+/* rcstr.c */
+char *rcstr_dup(const char *src);
+char *rcstr_alloc(size_t len);
+char *rcstr_addref(const char *s);
+void rcstr_delref(const char *s);
+
 #endif /* SUDOERS_SUDOERS_H */
index c23da7c9aebccd5cd8e67baf9ce70b7823c17cf6..e5b4d9750c6d3ae9066f369fed713267d9fb58c8 100644 (file)
@@ -4068,6 +4068,7 @@ read_dir_files(const char *dirpath, struct path_list ***pathsp)
     while ((dent = readdir(dir)) != NULL) {
        struct path_list *pl;
        struct stat sb;
+       size_t len;
        char *path;
 
        /* Ignore files that end in '~' or have a '.' in them. */
@@ -4075,15 +4076,17 @@ read_dir_files(const char *dirpath, struct path_list ***pathsp)
            || strchr(dent->d_name, '.') != NULL) {
            continue;
        }
-       if (asprintf(&path, "%s/%s", dirpath, dent->d_name) == -1)
+       len = strlen(dirpath) + 1 + NAMLEN(dent);
+       if ((path = rcstr_alloc(len)) == NULL)
            goto oom;
+       (void)snprintf(path, len + 1, "%s/%s", dirpath, dent->d_name);
        if (stat(path, &sb) != 0 || !S_ISREG(sb.st_mode)) {
-           free(path);
+           rcstr_delref(path);
            continue;
        }
        pl = malloc(sizeof(*pl));
        if (pl == NULL) {
-           free(path);
+           rcstr_delref(path);
            goto oom;
        }
        pl->path = path;
@@ -4092,7 +4095,7 @@ read_dir_files(const char *dirpath, struct path_list ***pathsp)
            max_paths <<= 1;
            tmp = reallocarray(paths, max_paths, sizeof(*paths));
            if (tmp == NULL) {
-               free(path);
+               rcstr_delref(path);
                free(pl);
                goto oom;
            }
@@ -4115,7 +4118,7 @@ bad:
     if (dir != NULL)
        closedir(dir);
     for (i = 0; i < count; i++) {
-       free(paths[i]->path);
+       rcstr_delref(paths[i]->path);
        free(paths[i]);
     }
     free(paths);
@@ -4165,10 +4168,10 @@ init_lexer(void)
        idepth--;
        while ((pl = SLIST_FIRST(&istack[idepth].more)) != NULL) {
            SLIST_REMOVE_HEAD(&istack[idepth].more, entries);
-           free(pl->path);
+           rcstr_delref(pl->path);
            free(pl);
        }
-       free(istack[idepth].path);
+       rcstr_delref(istack[idepth].path);
        if (idepth && !istack[idepth].keepopen)
            fclose(istack[idepth].bs->yy_input_file);
        sudoers_delete_buffer(istack[idepth].bs);
@@ -4251,13 +4254,13 @@ push_include_int(char *path, bool isdir)
        count = switch_dir(&istack[idepth], path);
        if (count <= 0) {
            /* switch_dir() called sudoerserror() for us */
-           free(path);
+           rcstr_delref(path);
            debug_return_bool(count ? false : true);
        }
 
        /* Parse the first dir entry we can open, leave the rest for later. */
        do {
-           free(path);
+           rcstr_delref(path);
            if ((pl = SLIST_FIRST(&istack[idepth].more)) == NULL) {
                /* Unable to open any files in include dir, not an error. */
                debug_return_bool(true);
@@ -4274,7 +4277,7 @@ push_include_int(char *path, bool isdir)
        }
     }
     /* Push the old (current) file and open the new one. */
-    istack[idepth].path = sudoers; /* push old path */
+    istack[idepth].path = sudoers; /* push old path (and its ref) */
     istack[idepth].bs = YY_CURRENT_BUFFER;
     istack[idepth].lineno = sudolineno;
     istack[idepth].keepopen = keepopen;
@@ -4309,7 +4312,7 @@ pop_include(void)
        SLIST_REMOVE_HEAD(&istack[idepth - 1].more, entries);
        fp = open_sudoers(pl->path, false, &keepopen);
        if (fp != NULL) {
-           free(sudoers);
+           rcstr_delref(sudoers);
            sudoers = pl->path;
            sudolineno = 1;
            sudoers_switch_to_buffer(sudoers_create_buffer(fp, YY_BUF_SIZE));
@@ -4317,14 +4320,14 @@ pop_include(void)
            break;
        }
        /* Unable to open path in include dir, go to next one. */
-       free(pl->path);
+       rcstr_delref(pl->path);
        free(pl);
     }
     /* If no path list, just pop the last dir on the stack. */
     if (pl == NULL) {
        idepth--;
        sudoers_switch_to_buffer(istack[idepth].bs);
-       free(sudoers);
+       rcstr_delref(sudoers);
        sudoers = istack[idepth].path;
        sudolineno = istack[idepth].lineno;
        keepopen = istack[idepth].keepopen;
@@ -4365,7 +4368,7 @@ parse_include(char *base)
 
     /* Make a copy of the fully-qualified path and return it. */
     len += (int)(ep - cp);
-    path = pp = malloc(len + dirlen + 1);
+    path = pp = rcstr_alloc(len + dirlen);
     if (path == NULL) {
        sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
        sudoerserror(NULL);
index a98fef0dc662b53dcc2777bc5071019cf19189d3..b63edd07313f4fe19ff7424e780b50bf046043c0 100644 (file)
@@ -785,6 +785,7 @@ read_dir_files(const char *dirpath, struct path_list ***pathsp)
     while ((dent = readdir(dir)) != NULL) {
        struct path_list *pl;
        struct stat sb;
+       size_t len;
        char *path;
 
        /* Ignore files that end in '~' or have a '.' in them. */
@@ -792,15 +793,17 @@ read_dir_files(const char *dirpath, struct path_list ***pathsp)
            || strchr(dent->d_name, '.') != NULL) {
            continue;
        }
-       if (asprintf(&path, "%s/%s", dirpath, dent->d_name) == -1)
+       len = strlen(dirpath) + 1 + NAMLEN(dent);
+       if ((path = rcstr_alloc(len)) == NULL)
            goto oom;
+       (void)snprintf(path, len + 1, "%s/%s", dirpath, dent->d_name);
        if (stat(path, &sb) != 0 || !S_ISREG(sb.st_mode)) {
-           free(path);
+           rcstr_delref(path);
            continue;
        }
        pl = malloc(sizeof(*pl));
        if (pl == NULL) {
-           free(path);
+           rcstr_delref(path);
            goto oom;
        }
        pl->path = path;
@@ -809,7 +812,7 @@ read_dir_files(const char *dirpath, struct path_list ***pathsp)
            max_paths <<= 1;
            tmp = reallocarray(paths, max_paths, sizeof(*paths));
            if (tmp == NULL) {
-               free(path);
+               rcstr_delref(path);
                free(pl);
                goto oom;
            }
@@ -832,7 +835,7 @@ bad:
     if (dir != NULL)
        closedir(dir);
     for (i = 0; i < count; i++) {
-       free(paths[i]->path);
+       rcstr_delref(paths[i]->path);
        free(paths[i]);
     }
     free(paths);
@@ -882,10 +885,10 @@ init_lexer(void)
        idepth--;
        while ((pl = SLIST_FIRST(&istack[idepth].more)) != NULL) {
            SLIST_REMOVE_HEAD(&istack[idepth].more, entries);
-           free(pl->path);
+           rcstr_delref(pl->path);
            free(pl);
        }
-       free(istack[idepth].path);
+       rcstr_delref(istack[idepth].path);
        if (idepth && !istack[idepth].keepopen)
            fclose(istack[idepth].bs->yy_input_file);
        sudoers_delete_buffer(istack[idepth].bs);
@@ -968,13 +971,13 @@ push_include_int(char *path, bool isdir)
        count = switch_dir(&istack[idepth], path);
        if (count <= 0) {
            /* switch_dir() called sudoerserror() for us */
-           free(path);
+           rcstr_delref(path);
            debug_return_bool(count ? false : true);
        }
 
        /* Parse the first dir entry we can open, leave the rest for later. */
        do {
-           free(path);
+           rcstr_delref(path);
            if ((pl = SLIST_FIRST(&istack[idepth].more)) == NULL) {
                /* Unable to open any files in include dir, not an error. */
                debug_return_bool(true);
@@ -991,7 +994,7 @@ push_include_int(char *path, bool isdir)
        }
     }
     /* Push the old (current) file and open the new one. */
-    istack[idepth].path = sudoers; /* push old path */
+    istack[idepth].path = sudoers; /* push old path (and its ref) */
     istack[idepth].bs = YY_CURRENT_BUFFER;
     istack[idepth].lineno = sudolineno;
     istack[idepth].keepopen = keepopen;
@@ -1026,7 +1029,7 @@ pop_include(void)
        SLIST_REMOVE_HEAD(&istack[idepth - 1].more, entries);
        fp = open_sudoers(pl->path, false, &keepopen);
        if (fp != NULL) {
-           free(sudoers);
+           rcstr_delref(sudoers);
            sudoers = pl->path;
            sudolineno = 1;
            sudoers_switch_to_buffer(sudoers_create_buffer(fp, YY_BUF_SIZE));
@@ -1034,14 +1037,14 @@ pop_include(void)
            break;
        }
        /* Unable to open path in include dir, go to next one. */
-       free(pl->path);
+       rcstr_delref(pl->path);
        free(pl);
     }
     /* If no path list, just pop the last dir on the stack. */
     if (pl == NULL) {
        idepth--;
        sudoers_switch_to_buffer(istack[idepth].bs);
-       free(sudoers);
+       rcstr_delref(sudoers);
        sudoers = istack[idepth].path;
        sudolineno = istack[idepth].lineno;
        keepopen = istack[idepth].keepopen;
@@ -1082,7 +1085,7 @@ parse_include(char *base)
 
     /* Make a copy of the fully-qualified path and return it. */
     len += (int)(ep - cp);
-    path = pp = malloc(len + dirlen + 1);
+    path = pp = rcstr_alloc(len + dirlen);
     if (path == NULL) {
        sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
        sudoerserror(NULL);
index f33c1db34095c09a5b18904d856c8386a5da5b7b..c7bf710fd5e2e0f614f2b24989d9889c0bf95442 100644 (file)
@@ -562,22 +562,20 @@ check_defaults_and_aliases(bool strict, bool quiet)
 
     if (!check_defaults(quiet)) {
        struct defaults *d;
-       free(errorfile);
+       rcstr_delref(errorfile);
        errorfile = NULL;
        /* XXX - should edit all files with errors */
        TAILQ_FOREACH(d, &defaults, entries) {
            if (d->error) {
-               /* Defaults parse error, adopt the file name. */
-               errorfile = d->file;
+               /* Defaults parse error, set errorfile/errorlineno. */
+               errorfile = rcstr_addref(d->file);
                errorlineno = d->lineno;
-               d->file = NULL;
-               d->error = false; /* paranoia */
                break;
            }
        }
        parse_error = true;
     } else if (check_aliases(strict, quiet) != 0) {
-       free(errorfile);
+       rcstr_delref(errorfile);
        errorfile = NULL;       /* don't know which file */
        parse_error = true;
     }
@@ -618,8 +616,8 @@ reparse_sudoers(char *editor, int editor_argc, char **editor_argv,
            sudo_warnx(U_("unabled to parse temporary file (%s), unknown error"),
                sp->tpath);
            parse_error = true;
-           free(errorfile);
-           if ((errorfile = strdup(sp->path)) == NULL)
+           rcstr_delref(errorfile);
+           if ((errorfile = rcstr_dup(sp->path)) == NULL)
                sudo_fatalx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
        }
        fclose(sudoersin);
@@ -959,8 +957,8 @@ check_syntax(const char *sudoers_file, bool quiet, bool strict, bool oldperms)
        if (!quiet)
            sudo_warnx(U_("failed to parse %s file, unknown error"), sudoers_file);
        parse_error = true;
-       free(errorfile);
-       if ((errorfile = strdup(sudoers_file)) == NULL)
+       rcstr_delref(errorfile);
+       if ((errorfile = rcstr_dup(sudoers_file)) == NULL)
            sudo_fatalx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
     }
     if (!parse_error) {
index dd2ced273c9c2baa7a902d4e2b3f8609444ea47e..d21bf90f50804e36e87ac1a2049e135cce021b06 100644 (file)
@@ -1030,8 +1030,8 @@ export_sudoers(const char *sudoers_path, const char *export_path,
        if (!quiet)
            sudo_warnx(U_("failed to parse %s file, unknown error"), sudoers_path);
        parse_error = true;
-       free(errorfile);
-       if ((errorfile = strdup(sudoers_path)) == NULL)
+       rcstr_delref(errorfile);
+       if ((errorfile = rcstr_dup(sudoers_path)) == NULL)
            sudo_fatalx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
     }
     ret = !parse_error;