From bbaf2939127ff765e121da1f68a2f77d45c43db9 Mon Sep 17 00:00:00 2001 From: "Todd C. Miller" Date: Mon, 21 Aug 2023 09:21:52 -0600 Subject: [PATCH] Add sudoers_ctx_free() and use it for freeing struct sudoers context. This replaces sudoers_user_ctx_free() and sudoers_runas_ctx_free(). --- MANIFEST | 1 + plugins/sudoers/Makefile.in | 81 ++++++++++++------ plugins/sudoers/cvtsudoers.c | 1 + plugins/sudoers/regress/fuzz/fuzz_sudoers.c | 27 +++--- plugins/sudoers/stubs.c | 14 +++- plugins/sudoers/sudoers.c | 75 +---------------- plugins/sudoers/sudoers.h | 3 + plugins/sudoers/sudoers_ctx_free.c | 92 +++++++++++++++++++++ plugins/sudoers/testsudoers.c | 35 ++++++-- plugins/sudoers/visudo.c | 1 + 10 files changed, 205 insertions(+), 125 deletions(-) create mode 100644 plugins/sudoers/sudoers_ctx_free.c diff --git a/MANIFEST b/MANIFEST index 26ea8216e..658d99729 100644 --- a/MANIFEST +++ b/MANIFEST @@ -1168,6 +1168,7 @@ plugins/sudoers/sudoers.c plugins/sudoers/sudoers.exp plugins/sudoers/sudoers.h plugins/sudoers/sudoers.in +plugins/sudoers/sudoers_ctx_free.c plugins/sudoers/sudoers_debug.c plugins/sudoers/sudoers_debug.h plugins/sudoers/sudoers_hooks.c diff --git a/plugins/sudoers/Makefile.in b/plugins/sudoers/Makefile.in index 737904ef7..1d30c109d 100644 --- a/plugins/sudoers/Makefile.in +++ b/plugins/sudoers/Makefile.in @@ -185,26 +185,26 @@ LIBPARSESUDOERS_IOBJS = $(LIBPARSESUDOERS_OBJS:.lo=.i) passwd.i SUDOERS_OBJS = $(AUTH_OBJS) audit.lo boottime.lo callbacks.lo check.lo \ check_util.lo display.lo editor.lo env.lo sudoers_hooks.lo \ - env_pattern.lo file.lo find_path.lo fmtsudoers.lo \ - gc.lo goodpath.lo group_plugin.lo interfaces.lo \ - iolog.lo iolog_path_escapes.lo locale.lo log_client.lo \ - logging.lo lookup.lo pivot.lo policy.lo prompt.lo \ - serialize_list.lo set_perms.lo starttime.lo \ - strlcpy_unesc.lo strvec_join.lo sudo_nss.lo sudoers.lo \ - timestamp.lo unesc_str.lo @SUDOERS_OBJS@ + env_pattern.lo file.lo find_path.lo fmtsudoers.lo \ + gc.lo goodpath.lo group_plugin.lo interfaces.lo iolog.lo \ + iolog_path_escapes.lo locale.lo log_client.lo logging.lo \ + lookup.lo pivot.lo policy.lo prompt.lo serialize_list.lo \ + set_perms.lo starttime.lo strlcpy_unesc.lo strvec_join.lo \ + sudo_nss.lo sudoers.lo sudoers_ctx_free.lo timestamp.lo \ + unesc_str.lo @SUDOERS_OBJS@ SUDOERS_IOBJS = $(SUDOERS_OBJS:.lo=.i) VISUDO_OBJS = check_aliases.o editor.lo find_path.lo gc.lo goodpath.lo \ - locale.lo stubs.o sudo_printf.o visudo.o + locale.lo stubs.o sudo_printf.o sudoers_ctx_free.lo visudo.o VISUDO_IOBJS = sudo_printf.i visudo.i CVTSUDOERS_OBJS = b64_encode.o cvtsudoers.o cvtsudoers_json.o cvtsudoers_csv.o \ cvtsudoers_ldif.o cvtsudoers_merge.o cvtsudoers_pwutil.o \ fmtsudoers.lo fmtsudoers_cvt.lo locale.lo parse_ldif.o \ - stubs.o sudo_printf.o ldap_util.lo testsudoers_pwutil.o \ - tsgetgrpw.o + stubs.o sudo_printf.o sudoers_ctx_free.lo ldap_util.lo \ + testsudoers_pwutil.o tsgetgrpw.o CVTSUDOERS_IOBJS = cvtsudoers.i cvtsudoers_csv.i cvtsudoers_json.i \ cvtsudoers_ldif.i cvtsudoers_merge.i cvtsudoers_pwutil.i @@ -214,9 +214,9 @@ REPLAY_OBJS = getdate.o sudoreplay.o REPLAY_IOBJS = $(REPLAY_OBJS:.o=.i) TEST_OBJS = check_util.lo fmtsudoers.lo fmtsudoers_cvt.lo group_plugin.lo \ - interfaces.lo ldap_util.lo locale.lo lookup.lo net_ifs.o \ - parse_ldif.o sudo_printf.o testsudoers.o testsudoers_pwutil.o \ - tsgetgrpw.o + interfaces.lo ldap_util.lo locale.lo lookup.lo net_ifs.o \ + parse_ldif.o sudo_printf.o sudoers_ctx_free.lo testsudoers.o \ + testsudoers_pwutil.o tsgetgrpw.o IOBJS = $(LIBPARSESUDOERS_IOBJS) $(SUDOERS_IOBJS) $(VISUDO_IOBJS) \ $(CVTSUDOERS_IOBJS) $(REPLAY_IOBJS) @@ -257,14 +257,15 @@ CHECK_SERIALIZE_LIST_OBJS = check_serialize_list.lo serialize_list.lo \ sudoers_debug.lo FUZZ_POLICY_OBJS = callbacks.lo editor.lo env.lo env_pattern.lo fuzz_policy.o \ - fuzz_stubs.o gc.lo iolog_path_escapes.lo locale.lo \ - policy.lo serialize_list.lo strlcpy_unesc.lo \ - strvec_join.lo sudoers.lo sudoers_hooks.lo + fuzz_stubs.o gc.lo iolog_path_escapes.lo locale.lo \ + policy.lo serialize_list.lo strlcpy_unesc.lo \ + strvec_join.lo sudoers.lo sudoers_ctx_free.lo \ + sudoers_hooks.lo FUZZ_POLICY_CORPUS = $(srcdir)/regress/corpus/seed/policy/policy.* FUZZ_SUDOERS_OBJS = check_aliases.o display.lo fuzz_stubs.o fuzz_sudoers.o \ - fmtsudoers.lo locale.lo lookup.lo + fmtsudoers.lo locale.lo lookup.lo sudoers_ctx_free.lo FUZZ_SUDOERS_CORPUS = $(top_builddir)/examples/sudoers \ $(srcdir)/regress/sudoers/test1.in \ @@ -921,22 +922,24 @@ bsm_audit.i: $(srcdir)/bsm_audit.c $(devdir)/def_data.h \ bsm_audit.plog: bsm_audit.i rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/bsm_audit.c --i-file $< --output-file $@ callbacks.lo: $(srcdir)/callbacks.c $(devdir)/def_data.h \ - $(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \ - $(incdir)/sudo_conf.h $(incdir)/sudo_debug.h \ - $(incdir)/sudo_eventlog.h $(incdir)/sudo_fatal.h \ - $(incdir)/sudo_gettext.h $(incdir)/sudo_plugin.h \ - $(incdir)/sudo_queue.h $(incdir)/sudo_util.h \ + $(incdir)/compat/getaddrinfo.h $(incdir)/compat/stdbool.h \ + $(incdir)/sudo_compat.h $(incdir)/sudo_conf.h \ + $(incdir)/sudo_debug.h $(incdir)/sudo_eventlog.h \ + $(incdir)/sudo_fatal.h $(incdir)/sudo_gettext.h \ + $(incdir)/sudo_iolog.h $(incdir)/sudo_plugin.h \ + $(incdir)/sudo_queue.h $(incdir)/sudo_util.h $(srcdir)/check.h \ $(srcdir)/defaults.h $(srcdir)/logging.h $(srcdir)/parse.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) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(HARDENING_CFLAGS) $(srcdir)/callbacks.c callbacks.i: $(srcdir)/callbacks.c $(devdir)/def_data.h \ - $(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \ - $(incdir)/sudo_conf.h $(incdir)/sudo_debug.h \ - $(incdir)/sudo_eventlog.h $(incdir)/sudo_fatal.h \ - $(incdir)/sudo_gettext.h $(incdir)/sudo_plugin.h \ - $(incdir)/sudo_queue.h $(incdir)/sudo_util.h \ + $(incdir)/compat/getaddrinfo.h $(incdir)/compat/stdbool.h \ + $(incdir)/sudo_compat.h $(incdir)/sudo_conf.h \ + $(incdir)/sudo_debug.h $(incdir)/sudo_eventlog.h \ + $(incdir)/sudo_fatal.h $(incdir)/sudo_gettext.h \ + $(incdir)/sudo_iolog.h $(incdir)/sudo_plugin.h \ + $(incdir)/sudo_queue.h $(incdir)/sudo_util.h $(srcdir)/check.h \ $(srcdir)/defaults.h $(srcdir)/logging.h $(srcdir)/parse.h \ $(srcdir)/sudo_nss.h $(srcdir)/sudoers.h \ $(srcdir)/sudoers_debug.h $(top_builddir)/config.h \ @@ -3028,6 +3031,30 @@ sudoers.i: $(srcdir)/sudoers.c $(devdir)/def_data.h \ $(CC) -E -o $@ $(CPPFLAGS) $< sudoers.plog: sudoers.i rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/sudoers.c --i-file $< --output-file $@ +sudoers_ctx_free.lo: $(srcdir)/sudoers_ctx_free.c $(devdir)/def_data.h \ + $(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \ + $(incdir)/sudo_conf.h $(incdir)/sudo_debug.h \ + $(incdir)/sudo_eventlog.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)/parse.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) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(HARDENING_CFLAGS) $(srcdir)/sudoers_ctx_free.c +sudoers_ctx_free.i: $(srcdir)/sudoers_ctx_free.c $(devdir)/def_data.h \ + $(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \ + $(incdir)/sudo_conf.h $(incdir)/sudo_debug.h \ + $(incdir)/sudo_eventlog.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)/parse.h $(srcdir)/sudo_nss.h \ + $(srcdir)/sudoers.h $(srcdir)/sudoers_debug.h \ + $(top_builddir)/config.h $(top_builddir)/pathnames.h + $(CC) -E -o $@ $(CPPFLAGS) $< +sudoers_ctx_free.plog: sudoers_ctx_free.i + rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/sudoers_ctx_free.c --i-file $< --output-file $@ sudoers_debug.lo: $(srcdir)/sudoers_debug.c $(devdir)/def_data.h \ $(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \ $(incdir)/sudo_conf.h $(incdir)/sudo_debug.h \ diff --git a/plugins/sudoers/cvtsudoers.c b/plugins/sudoers/cvtsudoers.c index ed15a9c78..7cab6cb99 100644 --- a/plugins/sudoers/cvtsudoers.c +++ b/plugins/sudoers/cvtsudoers.c @@ -455,6 +455,7 @@ main(int argc, char *argv[]) } done: + sudoers_ctx_free(&ctx); free_parse_tree(&merged_tree); while ((parse_tree = TAILQ_FIRST(&parse_trees)) != NULL) { TAILQ_REMOVE(&parse_trees, parse_tree, entries); diff --git a/plugins/sudoers/regress/fuzz/fuzz_sudoers.c b/plugins/sudoers/regress/fuzz/fuzz_sudoers.c index 22b9f30eb..7c3775771 100644 --- a/plugins/sudoers/regress/fuzz/fuzz_sudoers.c +++ b/plugins/sudoers/regress/fuzz/fuzz_sudoers.c @@ -285,14 +285,15 @@ LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) goto done; sudo_pw_delref(pw); - /* The minimum needed to perform matching (cmnd must be dynamic). */ - ctx.user.host = ctx.user.shost = ctx.runas.host = ctx.runas.shost = - (char *)"localhost"; + /* The minimum needed to perform matching. */ + ctx.user.host = ctx.user.shost = strdup("localhost"); + ctx.runas.host = ctx.runas.shost = strdup("localhost"); orig_cmnd = (char *)"/usr/bin/id"; ctx.user.cmnd = strdup(orig_cmnd); - if (ctx.user.cmnd == NULL) + ctx.user.cmnd_args = strdup("-u"); + if (ctx.user.host == NULL || ctx.runas.host == NULL || + ctx.user.cmnd == NULL || ctx.user.cmnd_args == NULL) goto done; - ctx.user.cmnd_args = (char *)"-u"; ctx.user.cmnd_base = sudo_basename(ctx.user.cmnd); time(&now); @@ -327,7 +328,10 @@ LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) int cmnd_status; /* Invoking user. */ - ctx.user.name = (char *)ud->user; + free(ctx.user.name); + ctx.user.name = strdup(ud->user); + if (ctx.user.name == NULL) + goto done; if (ctx.user.pw != NULL) sudo_pw_delref(ctx.user.pw); ctx.user.pw = sudo_getpwnam(ctx.user.name); @@ -405,16 +409,7 @@ done: fclose(fp); free_parse_tree(&parse_tree); reset_parser(); - if (ctx.user.pw != NULL) - sudo_pw_delref(ctx.user.pw); - if (ctx.runas.pw != NULL) - sudo_pw_delref(ctx.runas.pw); - if (ctx.runas.gr != NULL) - sudo_gr_delref(ctx.runas.gr); - free(ctx.user.cmnd); - free(ctx.runas.cmnd); - free(ctx.user.cmnd_list); - memset(&ctx, 0, sizeof(ctx)); + sudoers_ctx_free(&ctx); sudo_freepwcache(); sudo_freegrcache(); sudoers_setlocale(SUDOERS_LOCALE_USER, NULL); diff --git a/plugins/sudoers/stubs.c b/plugins/sudoers/stubs.c index 991495640..82d69d5a8 100644 --- a/plugins/sudoers/stubs.c +++ b/plugins/sudoers/stubs.c @@ -133,8 +133,18 @@ get_hostname(struct sudoers_context *ctx) if (ctx->user.host == NULL) sudo_fatalx(U_("%s: %s"), __func__, U_("unable to allocate memory")); } - ctx->runas.host = ctx->user.host; - ctx->runas.shost = ctx->user.shost; + + ctx->runas.host = strdup(ctx->user.host); + if (ctx->runas.host == NULL) + sudo_fatalx(U_("%s: %s"), __func__, U_("unable to allocate memory")); + if ((cp = strchr(ctx->runas.host, '.'))) { + *cp = '\0'; + if ((ctx->runas.shost = strdup(ctx->runas.host)) == NULL) + sudo_fatalx(U_("%s: %s"), __func__, U_("unable to allocate memory")); + *cp = '.'; + } else { + ctx->runas.shost = ctx->runas.host; + } debug_return; } diff --git a/plugins/sudoers/sudoers.c b/plugins/sudoers/sudoers.c index cc74e5ca5..4dd162da9 100644 --- a/plugins/sudoers/sudoers.c +++ b/plugins/sudoers/sudoers.c @@ -1487,77 +1487,6 @@ cb_runas_default(struct sudoers_context *ctx, const char *file, int line, debug_return_bool(true); } -/* - * Free memory allocated for struct sudoers_user_context. - */ -static void -sudoers_user_ctx_free(struct sudoers_user_context *user_ctx) -{ - debug_decl(sudoers_user_ctx_free, SUDOERS_DEBUG_PLUGIN); - - /* Free remaining references to password and group entries. */ - if (user_ctx->pw != NULL) - sudo_pw_delref(user_ctx->pw); - if (user_ctx->gid_list != NULL) - sudo_gidlist_delref(user_ctx->gid_list); - - /* Free dynamic contents of user_ctx. */ - free(user_ctx->cwd); - free(user_ctx->name); - if (user_ctx->ttypath != NULL) - free(user_ctx->ttypath); - else - free(user_ctx->tty); - if (user_ctx->shost != user_ctx->host) - free(user_ctx->shost); - free(user_ctx->host); - free(user_ctx->cmnd); - canon_path_free(user_ctx->cmnd_dir); - free(user_ctx->cmnd_args); - free(user_ctx->cmnd_list); - free(user_ctx->cmnd_saved); - free(user_ctx->source); - free(user_ctx->cmnd_stat); - - debug_return; -} - -/* - * Free memory allocated for struct sudoers_runas_context. - */ -static void -sudoers_runas_ctx_free(struct sudoers_runas_context *runas_ctx) -{ - debug_decl(sudoers_runas_ctx_free, SUDOERS_DEBUG_PLUGIN); - - /* Free remaining references to password and group entries. */ - if (runas_ctx->pw != NULL) - sudo_pw_delref(runas_ctx->pw); - if (runas_ctx->gr != NULL) - sudo_gr_delref(runas_ctx->gr); - if (runas_ctx->list_pw != NULL) - sudo_pw_delref(runas_ctx->list_pw); - - /* Free dynamic contents of runas_ctx-> */ - free(runas_ctx->cmnd); - if (runas_ctx->shost != runas_ctx->host) - free(runas_ctx->shost); - free(runas_ctx->host); -#ifdef HAVE_SELINUX - free(runas_ctx->role); - free(runas_ctx->type); -#endif -#ifdef HAVE_APPARMOR - free(runas_ctx->apparmor_profile); -#endif -#ifdef HAVE_PRIV_SET - free(runas_ctx->privs); - free(runas_ctx->limitprivs); -#endif - - debug_return; -} - /* * Cleanup hook for sudo_fatal()/sudo_fatalx() * Also called at policy close time. @@ -1585,8 +1514,7 @@ sudoers_cleanup(void) need_reinit = false; if (def_group_plugin) group_plugin_unload(); - sudoers_user_ctx_free(&sudoers_ctx.user); - sudoers_runas_ctx_free(&sudoers_ctx.runas); + sudoers_ctx_free(&sudoers_ctx); sudo_freepwcache(); sudo_freegrcache(); canon_path_free_cache(); @@ -1602,7 +1530,6 @@ sudoers_cleanup(void) NewArgv = NULL; NewArgc = 0; prev_user = NULL; - memset(&sudoers_ctx, 0, sizeof(sudoers_ctx)); debug_return; } diff --git a/plugins/sudoers/sudoers.h b/plugins/sudoers/sudoers.h index 5dc0fac18..3bdfa95a2 100644 --- a/plugins/sudoers/sudoers.h +++ b/plugins/sudoers/sudoers.h @@ -407,6 +407,9 @@ extern sudo_conv_t sudo_conv; extern sudo_printf_t sudo_printf; extern struct sudo_plugin_event * (*plugin_event_alloc)(void); +/* sudoers_ctx_free.c */ +void sudoers_ctx_free(struct sudoers_context *ctx); + /* sudoers_debug.c */ bool sudoers_debug_parse_flags(struct sudo_conf_debug_file_list *debug_files, const char *entry); bool sudoers_debug_register(const char *plugin_path, struct sudo_conf_debug_file_list *debug_files); diff --git a/plugins/sudoers/sudoers_ctx_free.c b/plugins/sudoers/sudoers_ctx_free.c new file mode 100644 index 000000000..5cf474d35 --- /dev/null +++ b/plugins/sudoers/sudoers_ctx_free.c @@ -0,0 +1,92 @@ +/* + * SPDX-License-Identifier: ISC + * + * Copyright (c) 2023 Todd C. Miller + * + * 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. + */ + +/* + * This is an open source non-commercial project. Dear PVS-Studio, please check it. + * PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com + */ + +#include + +#include +#include +#include + +#include "sudoers.h" + +/* + * Free memory allocated for struct sudoers_context. + */ +void +sudoers_ctx_free(struct sudoers_context *ctx) +{ + debug_decl(sudoers_ctx_free, SUDOERS_DEBUG_PLUGIN); + + /* Free remaining references to password and group entries. */ + if (ctx->user.pw != NULL) + sudo_pw_delref(ctx->user.pw); + if (ctx->user.gid_list != NULL) + sudo_gidlist_delref(ctx->user.gid_list); + + /* Free dynamic contents of user_ctx. */ + free(ctx->user.cwd); + free(ctx->user.name); + if (ctx->user.ttypath != NULL) + free(ctx->user.ttypath); + else + free(ctx->user.tty); + if (ctx->user.shost != ctx->user.host) + free(ctx->user.shost); + free(ctx->user.host); + free(ctx->user.cmnd); + canon_path_free(ctx->user.cmnd_dir); + free(ctx->user.cmnd_args); + free(ctx->user.cmnd_list); + free(ctx->user.cmnd_saved); + free(ctx->user.source); + free(ctx->user.cmnd_stat); + + /* Free remaining references to password and group entries. */ + if (ctx->runas.pw != NULL) + sudo_pw_delref(ctx->runas.pw); + if (ctx->runas.gr != NULL) + sudo_gr_delref(ctx->runas.gr); + if (ctx->runas.list_pw != NULL) + sudo_pw_delref(ctx->runas.list_pw); + + /* Free dynamic contents of ctx->runas. */ + free(ctx->runas.cmnd); + if (ctx->runas.shost != ctx->runas.host) + free(ctx->runas.shost); + free(ctx->runas.host); +#ifdef HAVE_SELINUX + free(ctx->runas.role); + free(ctx->runas.type); +#endif +#ifdef HAVE_APPARMOR + free(ctx->runas.apparmor_profile); +#endif +#ifdef HAVE_PRIV_SET + free(ctx->runas.privs); + free(ctx->runas.limitprivs); +#endif + + memset(ctx, 0, sizeof(*ctx)); + + debug_return; +} diff --git a/plugins/sudoers/testsudoers.c b/plugins/sudoers/testsudoers.c index 6987d9cd9..815ad14c5 100644 --- a/plugins/sudoers/testsudoers.c +++ b/plugins/sudoers/testsudoers.c @@ -151,7 +151,11 @@ main(int argc, char *argv[]) SET(test_ctx.settings.flags, RUNAS_GROUP_SPECIFIED); break; case 'h': - test_ctx.user.host = optarg; + test_ctx.user.host = strdup(optarg); + if (test_ctx.user.host == NULL) { + sudo_fatalx(U_("%s: %s"), __func__, + U_("unable to allocate memory")); + } break; case 'i': if (strcasecmp(optarg, "ldif") == 0) { @@ -245,12 +249,20 @@ main(int argc, char *argv[]) } else if (pwflag == 0) { usage(); } - test_ctx.user.name = argc ? *argv++ : (char *)"root"; + test_ctx.user.name = strdup(argc ? *argv++ : "root"); + if (test_ctx.user.name == NULL) { + sudo_fatalx(U_("%s: %s"), __func__, + U_("unable to allocate memory")); + } argc = 0; } else { if (argc > 2 && sudo_mode == MODE_LIST) sudo_mode = MODE_CHECK; - test_ctx.user.name = *argv++; + test_ctx.user.name = strdup(*argv++); + if (test_ctx.user.name == NULL) { + sudo_fatalx(U_("%s: %s"), __func__, + U_("unable to allocate memory")); + } argc--; if (orig_cmnd == NULL) { orig_cmnd = *argv++; @@ -264,7 +276,9 @@ main(int argc, char *argv[]) if (getcwd(cwdbuf, sizeof(cwdbuf)) == NULL) strlcpy(cwdbuf, "/", sizeof(cwdbuf)); - test_ctx.user.cwd = cwdbuf; + test_ctx.user.cwd = strdup(cwdbuf); + if (test_ctx.user.cwd == NULL) + sudo_fatalx(U_("%s: %s"), __func__, U_("unable to allocate memory")); if ((test_ctx.user.pw = sudo_getpwnam(test_ctx.user.name)) == NULL) sudo_fatalx(U_("unknown user %s"), test_ctx.user.name); @@ -283,8 +297,16 @@ main(int argc, char *argv[]) } else { test_ctx.user.shost = test_ctx.user.host; } - test_ctx.runas.host = test_ctx.user.host; - test_ctx.runas.shost = test_ctx.user.shost; + if ((test_ctx.runas.host = strdup(test_ctx.user.host)) == NULL) + sudo_fatalx(U_("%s: %s"), __func__, U_("unable to allocate memory")); + if ((p = strchr(test_ctx.runas.host, '.'))) { + *p = '\0'; + if ((test_ctx.runas.shost = strdup(test_ctx.runas.host)) == NULL) + sudo_fatalx(U_("%s: %s"), __func__, U_("unable to allocate memory")); + *p = '.'; + } else { + test_ctx.runas.shost = test_ctx.runas.host; + } /* Fill in test_ctx.user.cmnd_args from argv. */ if (argc > 0) { @@ -429,6 +451,7 @@ main(int argc, char *argv[]) } done: + sudoers_ctx_free(&test_ctx); sudo_freepwcache(); sudo_freegrcache(); sudo_debug_exit_int(__func__, __FILE__, __LINE__, sudo_debug_subsys, exitcode); diff --git a/plugins/sudoers/visudo.c b/plugins/sudoers/visudo.c index a0974de0c..aadad992d 100644 --- a/plugins/sudoers/visudo.c +++ b/plugins/sudoers/visudo.c @@ -338,6 +338,7 @@ main(int argc, char *argv[]) free(editor); done: + sudoers_ctx_free(&ctx); sudo_debug_exit_int(__func__, __FILE__, __LINE__, sudo_debug_subsys, exitcode); return exitcode; }