From: Todd C. Miller Date: Wed, 17 Jun 2015 23:00:53 +0000 (-0600) Subject: Use non-exiting allocators in libsudo_util. X-Git-Tag: SUDO_1_8_14^2~81 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=5ce50a885c47cb0693555cda0dd4bf69076ad900;p=sudo Use non-exiting allocators in libsudo_util. --- diff --git a/include/sudo_conf.h b/include/sudo_conf.h index f916a71cc..468533e73 100644 --- a/include/sudo_conf.h +++ b/include/sudo_conf.h @@ -36,9 +36,9 @@ TAILQ_HEAD(sudo_conf_debug_file_list, sudo_debug_file); struct plugin_info { TAILQ_ENTRY(plugin_info) entries; - const char *path; - const char *symbol_name; - char * const * options; + char *path; + char *symbol_name; + char **options; unsigned int lineno; }; TAILQ_HEAD(plugin_info_list, plugin_info); @@ -51,7 +51,7 @@ struct sudo_conf_debug { TAILQ_HEAD(sudo_conf_debug_list, sudo_conf_debug); /* Read main sudo.conf file. */ -__dso_public void sudo_conf_read_v1(const char *conf_file, int conf_types); +__dso_public int sudo_conf_read_v1(const char *conf_file, int conf_types); #define sudo_conf_read(_a, _b) sudo_conf_read_v1((_a), (_b)) /* Accessor functions. */ diff --git a/include/sudo_lbuf.h b/include/sudo_lbuf.h index 4972905df..ab565e1aa 100644 --- a/include/sudo_lbuf.h +++ b/include/sudo_lbuf.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2010, 2011, 2013, 2014 + * Copyright (c) 2007, 2010, 2011, 2013-2015 * Todd C. Miller * * Permission to use, copy, modify, and distribute this software for any @@ -37,8 +37,8 @@ typedef int (*sudo_lbuf_output_t)(const char *); __dso_public void sudo_lbuf_init_v1(struct sudo_lbuf *lbuf, sudo_lbuf_output_t output, int indent, const char *continuation, int cols); __dso_public void sudo_lbuf_destroy_v1(struct sudo_lbuf *lbuf); -__dso_public void sudo_lbuf_append_v1(struct sudo_lbuf *lbuf, const char *fmt, ...) __printflike(2, 3); -__dso_public void sudo_lbuf_append_quoted_v1(struct sudo_lbuf *lbuf, const char *set, const char *fmt, ...) __printflike(3, 4); +__dso_public bool sudo_lbuf_append_v1(struct sudo_lbuf *lbuf, const char *fmt, ...) __printflike(2, 3); +__dso_public bool sudo_lbuf_append_quoted_v1(struct sudo_lbuf *lbuf, const char *set, const char *fmt, ...) __printflike(3, 4); __dso_public void sudo_lbuf_print_v1(struct sudo_lbuf *lbuf); #define sudo_lbuf_init(_a, _b, _c, _d, _e) sudo_lbuf_init_v1((_a), (_b), (_c), (_d), (_e)) diff --git a/lib/util/Makefile.in b/lib/util/Makefile.in index 6d9836bac..c84556df9 100644 --- a/lib/util/Makefile.in +++ b/lib/util/Makefile.in @@ -328,10 +328,9 @@ realclean: distclean cleandir: realclean # Autogenerated dependencies, do not modify -aix.lo: $(srcdir)/aix.c $(incdir)/compat/stdbool.h $(incdir)/sudo_alloc.h \ - $(incdir)/sudo_compat.h $(incdir)/sudo_debug.h $(incdir)/sudo_fatal.h \ - $(incdir)/sudo_gettext.h $(incdir)/sudo_queue.h $(incdir)/sudo_util.h \ - $(top_builddir)/config.h +aix.lo: $(srcdir)/aix.c $(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \ + $(incdir)/sudo_debug.h $(incdir)/sudo_fatal.h $(incdir)/sudo_gettext.h \ + $(incdir)/sudo_queue.h $(incdir)/sudo_util.h $(top_builddir)/config.h $(LIBTOOL) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(DEFS) $(srcdir)/aix.c alloc.lo: $(srcdir)/alloc.c $(incdir)/compat/stdbool.h $(incdir)/sudo_alloc.h \ $(incdir)/sudo_compat.h $(incdir)/sudo_fatal.h \ @@ -403,10 +402,10 @@ gettime.lo: $(srcdir)/gettime.c $(incdir)/compat/stdbool.h \ $(incdir)/sudo_util.h $(top_builddir)/config.h $(LIBTOOL) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(DEFS) $(srcdir)/gettime.c gidlist.lo: $(srcdir)/gidlist.c $(incdir)/compat/stdbool.h \ - $(incdir)/sudo_alloc.h $(incdir)/sudo_compat.h \ - $(incdir)/sudo_debug.h $(incdir)/sudo_fatal.h \ - $(incdir)/sudo_gettext.h $(incdir)/sudo_queue.h \ - $(incdir)/sudo_util.h $(top_builddir)/config.h + $(incdir)/sudo_compat.h $(incdir)/sudo_debug.h \ + $(incdir)/sudo_fatal.h $(incdir)/sudo_gettext.h \ + $(incdir)/sudo_queue.h $(incdir)/sudo_util.h \ + $(top_builddir)/config.h $(LIBTOOL) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(DEFS) $(srcdir)/gidlist.c glob.lo: $(srcdir)/glob.c $(incdir)/compat/charclass.h $(incdir)/compat/glob.h \ $(incdir)/sudo_compat.h $(top_builddir)/config.h @@ -429,9 +428,9 @@ key_val.lo: $(srcdir)/key_val.c $(incdir)/compat/stdbool.h \ $(incdir)/sudo_queue.h $(incdir)/sudo_util.h \ $(top_builddir)/config.h $(LIBTOOL) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(DEFS) $(srcdir)/key_val.c -lbuf.lo: $(srcdir)/lbuf.c $(incdir)/compat/stdbool.h $(incdir)/sudo_alloc.h \ - $(incdir)/sudo_compat.h $(incdir)/sudo_debug.h $(incdir)/sudo_lbuf.h \ - $(incdir)/sudo_queue.h $(top_builddir)/config.h +lbuf.lo: $(srcdir)/lbuf.c $(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \ + $(incdir)/sudo_debug.h $(incdir)/sudo_lbuf.h $(incdir)/sudo_queue.h \ + $(top_builddir)/config.h $(LIBTOOL) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(DEFS) $(srcdir)/lbuf.c locking.lo: $(srcdir)/locking.c $(incdir)/compat/stdbool.h \ $(incdir)/sudo_compat.h $(incdir)/sudo_debug.h \ @@ -545,19 +544,18 @@ strtonum.lo: $(srcdir)/strtonum.c $(incdir)/sudo_compat.h \ $(incdir)/sudo_gettext.h $(top_builddir)/config.h $(LIBTOOL) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(DEFS) $(srcdir)/strtonum.c sudo_conf.lo: $(srcdir)/sudo_conf.c $(incdir)/compat/stdbool.h \ - $(incdir)/sudo_alloc.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 $(top_builddir)/config.h \ - $(top_builddir)/pathnames.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 \ + $(top_builddir)/config.h $(top_builddir)/pathnames.h $(LIBTOOL) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(DEFS) $(srcdir)/sudo_conf.c sudo_debug.lo: $(srcdir)/sudo_debug.c $(incdir)/compat/stdbool.h \ - $(incdir)/sudo_alloc.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 $(top_builddir)/config.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 \ + $(top_builddir)/config.h $(LIBTOOL) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(DEFS) $(srcdir)/sudo_debug.c sudo_dso.lo: $(srcdir)/sudo_dso.c $(incdir)/sudo_compat.h $(incdir)/sudo_dso.h \ $(top_builddir)/config.h diff --git a/lib/util/aix.c b/lib/util/aix.c index dbf017288..632c7b053 100644 --- a/lib/util/aix.c +++ b/lib/util/aix.c @@ -36,7 +36,6 @@ #include "sudo_gettext.h" /* must be included before sudo_compat.h */ #include "sudo_compat.h" -#include "sudo_alloc.h" #include "sudo_fatal.h" #include "sudo_debug.h" #include "sudo_util.h" @@ -206,10 +205,14 @@ aix_prep_user_v1(char *user, const char *tty) debug_decl(aix_setauthdb, SUDO_DEBUG_UTIL) /* set usrinfo, like login(1) does */ - len = sudo_easprintf(&info, "NAME=%s%cLOGIN=%s%cLOGNAME=%s%cTTY=%s%c", + len = asprintf(&info, "NAME=%s%cLOGIN=%s%cLOGNAME=%s%cTTY=%s%c", user, '\0', user, '\0', user, '\0', tty ? tty : "", '\0'); + if (len == -1) { + sudo_warnx(U_("unable to allocate memory")); + debug_return_int(-1); + } (void)usrinfo(SETUINFO, info, len); - sudo_efree(info); + free(info); #ifdef HAVE_SETAUTHDB /* set administrative domain */ diff --git a/lib/util/gidlist.c b/lib/util/gidlist.c index 268062577..0a15863a7 100644 --- a/lib/util/gidlist.c +++ b/lib/util/gidlist.c @@ -33,7 +33,6 @@ #include "sudo_gettext.h" /* must be included before sudo_compat.h */ #include "sudo_compat.h" -#include "sudo_alloc.h" #include "sudo_fatal.h" #include "sudo_debug.h" #include "sudo_util.h" @@ -67,7 +66,11 @@ sudo_parse_gids_v1(const char *gidstr, const gid_t *basegid, GETGROUPS_T **gidsp ngids++; /* Allocate and fill in array. */ if (ngids != 0) { - gids = sudo_emallocarray(ngids, sizeof(GETGROUPS_T)); + gids = reallocarray(NULL, ngids, sizeof(GETGROUPS_T)); + if (gids == NULL) { + sudo_warnx(U_("unable to allocate memory")); + debug_return_int(-1); + } ngids = 0; if (basegid != NULL) gids[ngids++] = *basegid; diff --git a/lib/util/lbuf.c b/lib/util/lbuf.c index 204c560d2..6cda4b6d5 100644 --- a/lib/util/lbuf.c +++ b/lib/util/lbuf.c @@ -43,7 +43,6 @@ #include #include "sudo_compat.h" -#include "sudo_alloc.h" #include "sudo_debug.h" #include "sudo_lbuf.h" @@ -69,43 +68,52 @@ sudo_lbuf_destroy_v1(struct sudo_lbuf *lbuf) { debug_decl(sudo_lbuf_destroy, SUDO_DEBUG_UTIL) - sudo_efree(lbuf->buf); + free(lbuf->buf); lbuf->buf = NULL; debug_return; } -static void +static bool sudo_lbuf_expand(struct sudo_lbuf *lbuf, int extra) { if (lbuf->len + extra + 1 >= lbuf->size) { + char *new_buf; + int new_size = lbuf->size; + do { - lbuf->size += 256; - } while (lbuf->len + extra + 1 >= lbuf->size); - lbuf->buf = sudo_erealloc(lbuf->buf, lbuf->size); + new_size += 256; + } while (lbuf->len + extra + 1 >= new_size); + if ((new_buf = realloc(lbuf->buf, new_size)) == NULL) + return false; + lbuf->buf = new_buf; + lbuf->size = new_size; } + return true; } /* * Parse the format and append strings, only %s and %% escapes are supported. * Any characters in set are quoted with a backslash. */ -void +bool sudo_lbuf_append_quoted_v1(struct sudo_lbuf *lbuf, const char *set, const char *fmt, ...) { - va_list ap; - int len; + int len, saved_len = lbuf->len; + bool ret = false; char *cp, *s; + va_list ap; debug_decl(sudo_lbuf_append_quoted, SUDO_DEBUG_UTIL) va_start(ap, fmt); while (*fmt != '\0') { if (fmt[0] == '%' && fmt[1] == 's') { if ((s = va_arg(ap, char *)) == NULL) - goto done; + s = "(NULL)"; while ((cp = strpbrk(s, set)) != NULL) { len = (int)(cp - s); - sudo_lbuf_expand(lbuf, len + 2); + if (!sudo_lbuf_expand(lbuf, len + 2)) + goto done; memcpy(lbuf->buf + lbuf->len, s, len); lbuf->len += len; lbuf->buf[lbuf->len++] = '\\'; @@ -114,34 +122,41 @@ sudo_lbuf_append_quoted_v1(struct sudo_lbuf *lbuf, const char *set, const char * } if (*s != '\0') { len = strlen(s); - sudo_lbuf_expand(lbuf, len); + if (!sudo_lbuf_expand(lbuf, len)) + goto done; memcpy(lbuf->buf + lbuf->len, s, len); lbuf->len += len; } fmt += 2; continue; } - sudo_lbuf_expand(lbuf, 2); + if (!sudo_lbuf_expand(lbuf, 2)) + goto done; if (strchr(set, *fmt) != NULL) lbuf->buf[lbuf->len++] = '\\'; lbuf->buf[lbuf->len++] = *fmt++; } + ret = true; + done: + if (!ret) + lbuf->len = saved_len; if (lbuf->size != 0) lbuf->buf[lbuf->len] = '\0'; va_end(ap); - debug_return; + debug_return_bool(ret); } /* * Parse the format and append strings, only %s and %% escapes are supported. */ -void +bool sudo_lbuf_append_v1(struct sudo_lbuf *lbuf, const char *fmt, ...) { + int len, saved_len = lbuf->len; + bool ret = false; va_list ap; - int len; char *s; debug_decl(sudo_lbuf_append, SUDO_DEBUG_UTIL) @@ -149,23 +164,29 @@ sudo_lbuf_append_v1(struct sudo_lbuf *lbuf, const char *fmt, ...) while (*fmt != '\0') { if (fmt[0] == '%' && fmt[1] == 's') { if ((s = va_arg(ap, char *)) == NULL) - goto done; + s = "(NULL)"; len = strlen(s); - sudo_lbuf_expand(lbuf, len); + if (!sudo_lbuf_expand(lbuf, len)) + goto done; memcpy(lbuf->buf + lbuf->len, s, len); lbuf->len += len; fmt += 2; continue; } - sudo_lbuf_expand(lbuf, 1); + if (!sudo_lbuf_expand(lbuf, 1)) + goto done; lbuf->buf[lbuf->len++] = *fmt++; } + ret = true; + done: + if (!ret) + lbuf->len = saved_len; if (lbuf->size != 0) lbuf->buf[lbuf->len] = '\0'; va_end(ap); - debug_return; + debug_return_bool(ret); } static void diff --git a/lib/util/sudo_conf.c b/lib/util/sudo_conf.c index cc50ce15f..eb06d469e 100644 --- a/lib/util/sudo_conf.c +++ b/lib/util/sudo_conf.c @@ -51,7 +51,6 @@ #define SUDO_ERROR_WRAP 0 #include "sudo_compat.h" -#include "sudo_alloc.h" #include "sudo_fatal.h" #include "pathnames.h" #include "sudo_plugin.h" @@ -68,7 +67,7 @@ struct sudo_conf_table { const char *name; unsigned int namelen; - bool (*parser)(const char *entry, const char *conf_file, unsigned int lineno); + int (*parser)(const char *entry, const char *conf_file, unsigned int lineno); }; struct sudo_conf_path_table { @@ -77,10 +76,10 @@ struct sudo_conf_path_table { const char *pval; }; -static bool parse_debug(const char *entry, const char *conf_file, unsigned int lineno); -static bool parse_path(const char *entry, const char *conf_file, unsigned int lineno); -static bool parse_plugin(const char *entry, const char *conf_file, unsigned int lineno); -static bool parse_variable(const char *entry, const char *conf_file, unsigned int lineno); +static int parse_debug(const char *entry, const char *conf_file, unsigned int lineno); +static int parse_path(const char *entry, const char *conf_file, unsigned int lineno); +static int parse_plugin(const char *entry, const char *conf_file, unsigned int lineno); +static int parse_variable(const char *entry, const char *conf_file, unsigned int lineno); static struct sudo_conf_table sudo_conf_table[] = { { "Debug", sizeof("Debug") - 1, parse_debug }, @@ -90,10 +89,10 @@ static struct sudo_conf_table sudo_conf_table[] = { { NULL } }; -static bool set_var_disable_coredump(const char *entry, const char *conf_file, unsigned int); -static bool set_var_group_source(const char *entry, const char *conf_file, unsigned int); -static bool set_var_max_groups(const char *entry, const char *conf_file, unsigned int); -static bool set_var_probe_interfaces(const char *entry, const char *conf_file, unsigned int); +static int set_var_disable_coredump(const char *entry, const char *conf_file, unsigned int); +static int set_var_group_source(const char *entry, const char *conf_file, unsigned int); +static int set_var_max_groups(const char *entry, const char *conf_file, unsigned int); +static int set_var_probe_interfaces(const char *entry, const char *conf_file, unsigned int); static struct sudo_conf_table sudo_conf_var_table[] = { { "disable_coredump", sizeof("disable_coredump") - 1, set_var_disable_coredump }, @@ -139,11 +138,11 @@ static struct sudo_conf_data { /* * "Set variable_name value" */ -static bool +static int parse_variable(const char *entry, const char *conf_file, unsigned int lineno) { struct sudo_conf_table *var; - bool rval; + int rval; debug_decl(parse_variable, SUDO_DEBUG_UTIL) for (var = sudo_conf_var_table; var->name != NULL; var++) { @@ -156,18 +155,18 @@ parse_variable(const char *entry, const char *conf_file, unsigned int lineno) sudo_debug_printf(rval ? SUDO_DEBUG_INFO : SUDO_DEBUG_ERROR, "%s: %s:%u: Set %s %s", __func__, conf_file, lineno, var->name, entry); - debug_return_bool(rval); + debug_return_int(rval); } } sudo_debug_printf(SUDO_DEBUG_WARN, "%s: %s:%u: unknown setting %s", __func__, conf_file, lineno, entry); - debug_return_bool(false); + debug_return_int(false); } /* * "Path name /path/to/file" */ -static bool +static int parse_path(const char *entry, const char *conf_file, unsigned int lineno) { const char *name, *path; @@ -188,29 +187,33 @@ parse_path(const char *entry, const char *conf_file, unsigned int lineno) for (cur = sudo_conf_data.path_table; cur->pname != NULL; cur++) { if (strncasecmp(name, cur->pname, cur->pnamelen) == 0 && isblank((unsigned char)name[cur->pnamelen])) { - cur->pval = sudo_estrdup(path); + if ((cur->pval = strdup(path)) == NULL) { + sudo_warnx(U_("unable to allocate memory")); + debug_return_int(-1); + break; + } sudo_debug_printf(SUDO_DEBUG_INFO, "%s: %s:%u: Path %s %s", __func__, conf_file, lineno, cur->pname, cur->pval); - debug_return_bool(true); + debug_return_int(true); } } sudo_debug_printf(SUDO_DEBUG_WARN, "%s: %s:%u: unknown path %s", __func__, conf_file, lineno, entry); - debug_return_bool(false); + debug_return_int(false); bad: sudo_warnx(U_("invalid Path value `%s' in %s, line %u"), entry, conf_file, lineno); - debug_return_bool(false); + debug_return_int(false); } /* * "Debug program /path/to/log flags,..." */ -static bool +static int parse_debug(const char *progname, const char *conf_file, unsigned int lineno) { struct sudo_conf_debug *debug_spec; - struct sudo_debug_file *debug_file; + struct sudo_debug_file *debug_file = NULL; const char *path, *flags, *cp = progname; size_t pathlen, prognamelen; debug_decl(parse_debug, SUDO_DEBUG_UTIL) @@ -219,26 +222,26 @@ parse_debug(const char *progname, const char *conf_file, unsigned int lineno) while (*cp != '\0' && !isblank((unsigned char)*cp)) cp++; if (*cp == '\0') - debug_return_bool(false); /* not enough fields */ + debug_return_int(false); /* not enough fields */ prognamelen = (size_t)(cp - progname); do { cp++; } while (isblank((unsigned char)*cp)); if (*cp == '\0') - debug_return_bool(false); /* not enough fields */ + debug_return_int(false); /* not enough fields */ /* Parse path. */ path = cp; while (*cp != '\0' && !isblank((unsigned char)*cp)) cp++; if (*cp == '\0') - debug_return_bool(false); /* not enough fields */ + debug_return_int(false); /* not enough fields */ pathlen = (size_t)(cp - path); do { cp++; } while (isblank((unsigned char)*cp)); if (*cp == '\0') - debug_return_bool(false); /* not enough fields */ + debug_return_int(false); /* not enough fields */ /* Remainder is flags (freeform). */ flags = cp; @@ -251,26 +254,47 @@ parse_debug(const char *progname, const char *conf_file, unsigned int lineno) break; } if (debug_spec == NULL) { - debug_spec = sudo_emalloc(sizeof(*debug_spec)); - debug_spec->progname = sudo_estrndup(progname, prognamelen); + debug_spec = malloc(sizeof(*debug_spec)); + if (debug_spec == NULL) + goto oom; + debug_spec->progname = strndup(progname, prognamelen); + if (debug_spec->progname == NULL) { + free(debug_spec); + debug_spec = NULL; + goto oom; + } TAILQ_INIT(&debug_spec->debug_files); TAILQ_INSERT_TAIL(&sudo_conf_data.debugging, debug_spec, entries); } - debug_file = sudo_emalloc(sizeof(*debug_file)); - debug_file->debug_file = sudo_estrndup(path, pathlen); - debug_file->debug_flags = sudo_estrdup(flags); + debug_file = calloc(1, sizeof(*debug_file)); + if (debug_file == NULL) + goto oom; + debug_file->debug_file = strndup(path, pathlen); + if (debug_file->debug_file == NULL) + goto oom; + debug_file->debug_flags = strdup(flags); + if (debug_file->debug_flags == NULL) + goto oom; TAILQ_INSERT_TAIL(&debug_spec->debug_files, debug_file, entries); - debug_return_bool(true); + debug_return_int(true); +oom: + sudo_warnx(U_("unable to allocate memory")); + if (debug_file != NULL) { + free(debug_file->debug_file); + free(debug_file->debug_flags); + free(debug_file); + } + debug_return_int(-1); } /* * "Plugin symbol /path/to/log args..." */ -static bool +static int parse_plugin(const char *cp, const char *conf_file, unsigned int lineno) { - struct plugin_info *info; + struct plugin_info *info = NULL; const char *ep, *path, *symbol; char **options = NULL; size_t pathlen, symlen; @@ -279,7 +303,7 @@ parse_plugin(const char *cp, const char *conf_file, unsigned int lineno) /* Parse symbol. */ if (*cp == '\0') - debug_return_bool(false); /* not enough fields */ + debug_return_int(false); /* not enough fields */ symbol = cp; while (*cp != '\0' && !isblank((unsigned char)*cp)) cp++; @@ -289,7 +313,7 @@ parse_plugin(const char *cp, const char *conf_file, unsigned int lineno) /* Parse path. */ if (*cp == '\0') - debug_return_bool(false); /* not enough fields */ + debug_return_int(false); /* not enough fields */ path = cp; while (*cp != '\0' && !isblank((unsigned char)*cp)) cp++; @@ -298,36 +322,56 @@ parse_plugin(const char *cp, const char *conf_file, unsigned int lineno) cp++; /* Split options into an array if present. */ - /* XXX - consider as separate function */ + /* XXX - use sudo_strsplit */ if (*cp != '\0') { /* Count number of options and allocate array. */ for (ep = cp, nopts = 1; (ep = strpbrk(ep, " \t")) != NULL; nopts++) { while (isblank((unsigned char)*ep)) ep++; } - options = sudo_emallocarray(nopts + 1, sizeof(*options)); + options = reallocarray(NULL, nopts + 1, sizeof(*options)); + if (options == NULL) + goto oom; /* Fill in options array, there is at least one element. */ - for (nopts = 0; (ep = strpbrk(cp, " \t")) != NULL; ) { - options[nopts++] = sudo_estrndup(cp, (size_t)(ep - cp)); + for (nopts = 0; (ep = strpbrk(cp, " \t")) != NULL; nopts++) { + options[nopts] = strndup(cp, (size_t)(ep - cp)); + if (options[nopts] == NULL) + goto oom; while (isblank((unsigned char)*ep)) ep++; cp = ep; } - options[nopts++] = sudo_estrdup(cp); - options[nopts] = NULL; + options[nopts] = strdup(cp); + if (options[nopts] == NULL) + goto oom; + options[++nopts] = NULL; } - info = sudo_emalloc(sizeof(*info)); - info->symbol_name = sudo_estrndup(symbol, symlen); - info->path = sudo_estrndup(path, pathlen); + info = calloc(sizeof(*info), 1); + if (info == NULL) + goto oom; + info->symbol_name = strndup(symbol, symlen); + if (info->symbol_name == NULL) + goto oom; + info->path = strndup(path, pathlen); + if (info->path == NULL) + goto oom; info->options = options; info->lineno = lineno; TAILQ_INSERT_TAIL(&sudo_conf_data.plugins, info, entries); - debug_return_bool(true); + debug_return_int(true); +oom: + sudo_warnx(U_("unable to allocate memory")); + if (info != NULL) { + free(info->symbol_name); + free(info->path); + free(info); + } + debug_return_int(-1); } -static bool +static int set_var_disable_coredump(const char *strval, const char *conf_file, unsigned int lineno) { @@ -343,7 +387,7 @@ set_var_disable_coredump(const char *strval, const char *conf_file, debug_return_bool(true); } -static bool +static int set_var_group_source(const char *strval, const char *conf_file, unsigned int lineno) { @@ -363,7 +407,7 @@ set_var_group_source(const char *strval, const char *conf_file, debug_return_bool(true); } -static bool +static int set_var_max_groups(const char *strval, const char *conf_file, unsigned int lineno) { @@ -380,7 +424,7 @@ set_var_max_groups(const char *strval, const char *conf_file, debug_return_bool(true); } -static bool +static int set_var_probe_interfaces(const char *strval, const char *conf_file, unsigned int lineno) { @@ -499,17 +543,23 @@ sudo_conf_probe_interfaces_v1(void) /* * Reads in /etc/sudo.conf and populates sudo_conf_data. */ -void +int sudo_conf_read_v1(const char *conf_file, int conf_types) { struct stat sb; - FILE *fp; - char *line = NULL; - char *prev_locale = sudo_estrdup(setlocale(LC_ALL, NULL)); + FILE *fp = NULL; + int ret = false; + char *prev_locale, *line = NULL; unsigned int conf_lineno = 0; size_t linesize = 0; debug_decl(sudo_conf_read, SUDO_DEBUG_UTIL) + prev_locale = strdup(setlocale(LC_ALL, NULL)); + if (prev_locale == NULL) { + sudo_warnx(U_("unable to allocate memory")); + debug_return_int(-1); + } + /* Parse sudo.conf in the "C" locale. */ if (prev_locale[0] != 'C' || prev_locale[1] != '\0') setlocale(LC_ALL, "C"); @@ -564,7 +614,9 @@ sudo_conf_read_v1(const char *conf_file, int conf_types) cp += cur->namelen; while (isblank((unsigned char)*cp)) cp++; - cur->parser(cp, conf_file, conf_lineno); + ret = cur->parser(cp, conf_file, conf_lineno); + if (ret == -1) + goto done; } break; } @@ -575,13 +627,16 @@ sudo_conf_read_v1(const char *conf_file, int conf_types) conf_lineno, line); } } - fclose(fp); - free(line); + ret = true; done: + if (fp != NULL) + fclose(fp); + free(line); + /* Restore locale if needed. */ if (prev_locale[0] != 'C' || prev_locale[1] != '\0') setlocale(LC_ALL, prev_locale); - sudo_efree(prev_locale); - debug_return; + free(prev_locale); + debug_return_int(ret); } diff --git a/lib/util/sudo_debug.c b/lib/util/sudo_debug.c index 460dd457b..e9f1d51af 100644 --- a/lib/util/sudo_debug.c +++ b/lib/util/sudo_debug.c @@ -46,7 +46,6 @@ #include "sudo_gettext.h" /* must be included before sudo_compat.h */ #include "sudo_compat.h" -#include "sudo_alloc.h" #include "sudo_fatal.h" #include "sudo_plugin.h" #include "sudo_debug.h" @@ -134,15 +133,16 @@ static int sudo_debug_active_instance = -1; static void sudo_debug_free_output(struct sudo_debug_output *output) { - sudo_efree(output->filename); - sudo_efree(output->settings); + free(output->filename); + free(output->settings); if (output->fd != -1) close(output->fd); - sudo_efree(output); + free(output); } /* * Create a new output file for the specified debug instance. + * Returns NULL if the file cannot be opened or memory cannot be allocated. */ static struct sudo_debug_output * sudo_debug_new_output(struct sudo_debug_instance *instance, @@ -154,9 +154,17 @@ sudo_debug_new_output(struct sudo_debug_instance *instance, /* Create new output for the instance. */ /* XXX - reuse fd for existing filename? */ - output = sudo_emalloc(sizeof(*output)); - output->settings = sudo_emallocarray(instance->max_subsystem + 1, sizeof(int)); - output->filename = sudo_estrdup(debug_file->debug_file); + output = calloc(1, sizeof(*output)); + if (output == NULL) + goto bad; + output->fd = -1; + output->settings = reallocarray(NULL, instance->max_subsystem + 1, + sizeof(int)); + if (output->settings == NULL) + goto bad; + output->filename = strdup(debug_file->debug_file); + if (output->filename == NULL) + goto bad; output->fd = -1; /* Init per-subsystems settings to -1 since 0 is a valid priority. */ @@ -171,26 +179,32 @@ sudo_debug_new_output(struct sudo_debug_instance *instance, output->fd = open(output->filename, O_WRONLY|O_APPEND|O_CREAT, S_IRUSR|S_IWUSR); } - if (output->fd == -1) { - sudo_debug_free_output(output); - return NULL; - } + if (output->fd == -1) + goto bad; ignore_result(fchown(output->fd, (uid_t)-1, 0)); } (void)fcntl(output->fd, F_SETFD, FD_CLOEXEC); if (sudo_debug_fds_size < output->fd) { /* Bump fds size to the next multiple of 4 * NBBY. */ - const int new_size = round_nfds(output->fd); - sudo_debug_fds = sudo_erecalloc(sudo_debug_fds, - sudo_debug_fds_size / NBBY, new_size / NBBY, sizeof(char)); - sudo_debug_fds_size = new_size; + const int old_size = sudo_debug_fds_size / NBBY; + const int new_size = round_nfds(output->fd) / NBBY; + unsigned char *new_fds; + + new_fds = realloc(sudo_debug_fds, new_size); + if (new_fds == NULL) + goto bad; + memset(new_fds + old_size, 0, new_size - old_size); + sudo_debug_fds = new_fds; + sudo_debug_fds_size = new_size * NBBY; } sudo_setbit(sudo_debug_fds, output->fd); if (output->fd > sudo_debug_max_fd) sudo_debug_max_fd = output->fd; /* Parse Debug conf string. */ - buf = sudo_estrdup(debug_file->debug_flags); + buf = strdup(debug_file->debug_flags); + if (buf == NULL) + goto bad; for ((cp = strtok(buf, ",")); cp != NULL; (cp = strtok(NULL, ","))) { /* Should be in the form subsys@pri. */ subsys = cp; @@ -222,6 +236,11 @@ sudo_debug_new_output(struct sudo_debug_instance *instance, free(buf); return output; +bad: + sudo_warn_nodebug(NULL); + if (output != NULL) + sudo_debug_free_output(output); + return NULL; } /* @@ -294,8 +313,12 @@ sudo_debug_register_v1(const char *program, const char *const subsystems[], sudo_warnx_nodebug("%s: instance number mismatch: expected %d or %d, got %d", __func__, sudo_debug_last_instance + 1, free_idx, idx); return SUDO_DEBUG_INSTANCE_INITIALIZER; } - instance = sudo_emalloc(sizeof(*instance)); - instance->program = sudo_estrdup(program); + if ((instance = malloc(sizeof(*instance))) == NULL) + return SUDO_DEBUG_INSTANCE_INITIALIZER; + if ((instance->program = strdup(program)) == NULL) { + free(instance); + return SUDO_DEBUG_INSTANCE_INITIALIZER; + } instance->subsystems = subsystems; instance->subsystem_ids = ids; instance->max_subsystem = max_id; @@ -359,12 +382,12 @@ sudo_debug_deregister_v1(int idx) sudo_debug_instances[idx] = NULL; SLIST_FOREACH_SAFE(output, &instance->outputs, entries, next) { close(output->fd); - sudo_efree(output->filename); - sudo_efree(output->settings); - sudo_efree(output); + free(output->filename); + free(output->settings); + free(output); } - sudo_efree(instance->program); - sudo_efree(instance); + free(instance->program); + free(instance); if (idx == sudo_debug_last_instance) sudo_debug_last_instance--; @@ -606,7 +629,7 @@ sudo_debug_vprintf2_v1(const char *func, const char *file, int lineno, int level else sudo_debug_write2(output->fd, NULL, NULL, 0, buf, buflen, errcode); if (buf != static_buf) { - sudo_efree(buf); + free(buf); buf = static_buf; } } @@ -741,7 +764,7 @@ sudo_debug_execve2_v1(int level, const char *path, char *const argv[], char *con sudo_debug_write(output->fd, buf, buflen, 0); if (buf != static_buf) { - sudo_efree(buf); + free(buf); buf = static_buf; } }