Add sudoers_ctx_free() and use it for freeing struct sudoers context.

This replaces sudoers_user_ctx_free() and sudoers_runas_ctx_free().
This commit is contained in:
Todd C. Miller
2023-08-21 09:21:52 -06:00
parent 2440174954
commit bbaf293912
10 changed files with 205 additions and 125 deletions

View File

@@ -1168,6 +1168,7 @@ plugins/sudoers/sudoers.c
plugins/sudoers/sudoers.exp plugins/sudoers/sudoers.exp
plugins/sudoers/sudoers.h plugins/sudoers/sudoers.h
plugins/sudoers/sudoers.in plugins/sudoers/sudoers.in
plugins/sudoers/sudoers_ctx_free.c
plugins/sudoers/sudoers_debug.c plugins/sudoers/sudoers_debug.c
plugins/sudoers/sudoers_debug.h plugins/sudoers/sudoers_debug.h
plugins/sudoers/sudoers_hooks.c plugins/sudoers/sudoers_hooks.c

View File

@@ -185,26 +185,26 @@ LIBPARSESUDOERS_IOBJS = $(LIBPARSESUDOERS_OBJS:.lo=.i) passwd.i
SUDOERS_OBJS = $(AUTH_OBJS) audit.lo boottime.lo callbacks.lo check.lo \ SUDOERS_OBJS = $(AUTH_OBJS) audit.lo boottime.lo callbacks.lo check.lo \
check_util.lo display.lo editor.lo env.lo sudoers_hooks.lo \ check_util.lo display.lo editor.lo env.lo sudoers_hooks.lo \
env_pattern.lo file.lo find_path.lo fmtsudoers.lo \ env_pattern.lo file.lo find_path.lo fmtsudoers.lo \
gc.lo goodpath.lo group_plugin.lo interfaces.lo \ gc.lo goodpath.lo group_plugin.lo interfaces.lo iolog.lo \
iolog.lo iolog_path_escapes.lo locale.lo log_client.lo \ iolog_path_escapes.lo locale.lo log_client.lo logging.lo \
logging.lo lookup.lo pivot.lo policy.lo prompt.lo \ lookup.lo pivot.lo policy.lo prompt.lo serialize_list.lo \
serialize_list.lo set_perms.lo starttime.lo \ set_perms.lo starttime.lo strlcpy_unesc.lo strvec_join.lo \
strlcpy_unesc.lo strvec_join.lo sudo_nss.lo sudoers.lo \ sudo_nss.lo sudoers.lo sudoers_ctx_free.lo timestamp.lo \
timestamp.lo unesc_str.lo @SUDOERS_OBJS@ unesc_str.lo @SUDOERS_OBJS@
SUDOERS_IOBJS = $(SUDOERS_OBJS:.lo=.i) SUDOERS_IOBJS = $(SUDOERS_OBJS:.lo=.i)
VISUDO_OBJS = check_aliases.o editor.lo find_path.lo gc.lo goodpath.lo \ 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 VISUDO_IOBJS = sudo_printf.i visudo.i
CVTSUDOERS_OBJS = b64_encode.o cvtsudoers.o cvtsudoers_json.o cvtsudoers_csv.o \ CVTSUDOERS_OBJS = b64_encode.o cvtsudoers.o cvtsudoers_json.o cvtsudoers_csv.o \
cvtsudoers_ldif.o cvtsudoers_merge.o cvtsudoers_pwutil.o \ cvtsudoers_ldif.o cvtsudoers_merge.o cvtsudoers_pwutil.o \
fmtsudoers.lo fmtsudoers_cvt.lo locale.lo parse_ldif.o \ fmtsudoers.lo fmtsudoers_cvt.lo locale.lo parse_ldif.o \
stubs.o sudo_printf.o ldap_util.lo testsudoers_pwutil.o \ stubs.o sudo_printf.o sudoers_ctx_free.lo ldap_util.lo \
tsgetgrpw.o testsudoers_pwutil.o tsgetgrpw.o
CVTSUDOERS_IOBJS = cvtsudoers.i cvtsudoers_csv.i cvtsudoers_json.i \ CVTSUDOERS_IOBJS = cvtsudoers.i cvtsudoers_csv.i cvtsudoers_json.i \
cvtsudoers_ldif.i cvtsudoers_merge.i cvtsudoers_pwutil.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) REPLAY_IOBJS = $(REPLAY_OBJS:.o=.i)
TEST_OBJS = check_util.lo fmtsudoers.lo fmtsudoers_cvt.lo group_plugin.lo \ 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 \ interfaces.lo ldap_util.lo locale.lo lookup.lo net_ifs.o \
parse_ldif.o sudo_printf.o testsudoers.o testsudoers_pwutil.o \ parse_ldif.o sudo_printf.o sudoers_ctx_free.lo testsudoers.o \
tsgetgrpw.o testsudoers_pwutil.o tsgetgrpw.o
IOBJS = $(LIBPARSESUDOERS_IOBJS) $(SUDOERS_IOBJS) $(VISUDO_IOBJS) \ IOBJS = $(LIBPARSESUDOERS_IOBJS) $(SUDOERS_IOBJS) $(VISUDO_IOBJS) \
$(CVTSUDOERS_IOBJS) $(REPLAY_IOBJS) $(CVTSUDOERS_IOBJS) $(REPLAY_IOBJS)
@@ -257,14 +257,15 @@ CHECK_SERIALIZE_LIST_OBJS = check_serialize_list.lo serialize_list.lo \
sudoers_debug.lo sudoers_debug.lo
FUZZ_POLICY_OBJS = callbacks.lo editor.lo env.lo env_pattern.lo fuzz_policy.o \ 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 \ fuzz_stubs.o gc.lo iolog_path_escapes.lo locale.lo \
policy.lo serialize_list.lo strlcpy_unesc.lo \ policy.lo serialize_list.lo strlcpy_unesc.lo \
strvec_join.lo sudoers.lo sudoers_hooks.lo strvec_join.lo sudoers.lo sudoers_ctx_free.lo \
sudoers_hooks.lo
FUZZ_POLICY_CORPUS = $(srcdir)/regress/corpus/seed/policy/policy.* FUZZ_POLICY_CORPUS = $(srcdir)/regress/corpus/seed/policy/policy.*
FUZZ_SUDOERS_OBJS = check_aliases.o display.lo fuzz_stubs.o fuzz_sudoers.o \ 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 \ FUZZ_SUDOERS_CORPUS = $(top_builddir)/examples/sudoers \
$(srcdir)/regress/sudoers/test1.in \ $(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 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 $@ 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 \ callbacks.lo: $(srcdir)/callbacks.c $(devdir)/def_data.h \
$(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \ $(incdir)/compat/getaddrinfo.h $(incdir)/compat/stdbool.h \
$(incdir)/sudo_conf.h $(incdir)/sudo_debug.h \ $(incdir)/sudo_compat.h $(incdir)/sudo_conf.h \
$(incdir)/sudo_eventlog.h $(incdir)/sudo_fatal.h \ $(incdir)/sudo_debug.h $(incdir)/sudo_eventlog.h \
$(incdir)/sudo_gettext.h $(incdir)/sudo_plugin.h \ $(incdir)/sudo_fatal.h $(incdir)/sudo_gettext.h \
$(incdir)/sudo_queue.h $(incdir)/sudo_util.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)/defaults.h $(srcdir)/logging.h $(srcdir)/parse.h \
$(srcdir)/sudo_nss.h $(srcdir)/sudoers.h \ $(srcdir)/sudo_nss.h $(srcdir)/sudoers.h \
$(srcdir)/sudoers_debug.h $(top_builddir)/config.h \ $(srcdir)/sudoers_debug.h $(top_builddir)/config.h \
$(top_builddir)/pathnames.h $(top_builddir)/pathnames.h
$(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(HARDENING_CFLAGS) $(srcdir)/callbacks.c $(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 \ callbacks.i: $(srcdir)/callbacks.c $(devdir)/def_data.h \
$(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \ $(incdir)/compat/getaddrinfo.h $(incdir)/compat/stdbool.h \
$(incdir)/sudo_conf.h $(incdir)/sudo_debug.h \ $(incdir)/sudo_compat.h $(incdir)/sudo_conf.h \
$(incdir)/sudo_eventlog.h $(incdir)/sudo_fatal.h \ $(incdir)/sudo_debug.h $(incdir)/sudo_eventlog.h \
$(incdir)/sudo_gettext.h $(incdir)/sudo_plugin.h \ $(incdir)/sudo_fatal.h $(incdir)/sudo_gettext.h \
$(incdir)/sudo_queue.h $(incdir)/sudo_util.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)/defaults.h $(srcdir)/logging.h $(srcdir)/parse.h \
$(srcdir)/sudo_nss.h $(srcdir)/sudoers.h \ $(srcdir)/sudo_nss.h $(srcdir)/sudoers.h \
$(srcdir)/sudoers_debug.h $(top_builddir)/config.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) $< $(CC) -E -o $@ $(CPPFLAGS) $<
sudoers.plog: sudoers.i 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 $@ 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 \ sudoers_debug.lo: $(srcdir)/sudoers_debug.c $(devdir)/def_data.h \
$(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \ $(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
$(incdir)/sudo_conf.h $(incdir)/sudo_debug.h \ $(incdir)/sudo_conf.h $(incdir)/sudo_debug.h \

View File

@@ -455,6 +455,7 @@ main(int argc, char *argv[])
} }
done: done:
sudoers_ctx_free(&ctx);
free_parse_tree(&merged_tree); free_parse_tree(&merged_tree);
while ((parse_tree = TAILQ_FIRST(&parse_trees)) != NULL) { while ((parse_tree = TAILQ_FIRST(&parse_trees)) != NULL) {
TAILQ_REMOVE(&parse_trees, parse_tree, entries); TAILQ_REMOVE(&parse_trees, parse_tree, entries);

View File

@@ -285,14 +285,15 @@ LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
goto done; goto done;
sudo_pw_delref(pw); sudo_pw_delref(pw);
/* The minimum needed to perform matching (cmnd must be dynamic). */ /* The minimum needed to perform matching. */
ctx.user.host = ctx.user.shost = ctx.runas.host = ctx.runas.shost = ctx.user.host = ctx.user.shost = strdup("localhost");
(char *)"localhost"; ctx.runas.host = ctx.runas.shost = strdup("localhost");
orig_cmnd = (char *)"/usr/bin/id"; orig_cmnd = (char *)"/usr/bin/id";
ctx.user.cmnd = strdup(orig_cmnd); 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; goto done;
ctx.user.cmnd_args = (char *)"-u";
ctx.user.cmnd_base = sudo_basename(ctx.user.cmnd); ctx.user.cmnd_base = sudo_basename(ctx.user.cmnd);
time(&now); time(&now);
@@ -327,7 +328,10 @@ LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
int cmnd_status; int cmnd_status;
/* Invoking user. */ /* 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) if (ctx.user.pw != NULL)
sudo_pw_delref(ctx.user.pw); sudo_pw_delref(ctx.user.pw);
ctx.user.pw = sudo_getpwnam(ctx.user.name); ctx.user.pw = sudo_getpwnam(ctx.user.name);
@@ -405,16 +409,7 @@ done:
fclose(fp); fclose(fp);
free_parse_tree(&parse_tree); free_parse_tree(&parse_tree);
reset_parser(); reset_parser();
if (ctx.user.pw != NULL) sudoers_ctx_free(&ctx);
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));
sudo_freepwcache(); sudo_freepwcache();
sudo_freegrcache(); sudo_freegrcache();
sudoers_setlocale(SUDOERS_LOCALE_USER, NULL); sudoers_setlocale(SUDOERS_LOCALE_USER, NULL);

View File

@@ -133,8 +133,18 @@ get_hostname(struct sudoers_context *ctx)
if (ctx->user.host == NULL) if (ctx->user.host == NULL)
sudo_fatalx(U_("%s: %s"), __func__, U_("unable to allocate memory")); 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; debug_return;
} }

View File

@@ -1487,77 +1487,6 @@ cb_runas_default(struct sudoers_context *ctx, const char *file, int line,
debug_return_bool(true); 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() * Cleanup hook for sudo_fatal()/sudo_fatalx()
* Also called at policy close time. * Also called at policy close time.
@@ -1585,8 +1514,7 @@ sudoers_cleanup(void)
need_reinit = false; need_reinit = false;
if (def_group_plugin) if (def_group_plugin)
group_plugin_unload(); group_plugin_unload();
sudoers_user_ctx_free(&sudoers_ctx.user); sudoers_ctx_free(&sudoers_ctx);
sudoers_runas_ctx_free(&sudoers_ctx.runas);
sudo_freepwcache(); sudo_freepwcache();
sudo_freegrcache(); sudo_freegrcache();
canon_path_free_cache(); canon_path_free_cache();
@@ -1602,7 +1530,6 @@ sudoers_cleanup(void)
NewArgv = NULL; NewArgv = NULL;
NewArgc = 0; NewArgc = 0;
prev_user = NULL; prev_user = NULL;
memset(&sudoers_ctx, 0, sizeof(sudoers_ctx));
debug_return; debug_return;
} }

View File

@@ -407,6 +407,9 @@ extern sudo_conv_t sudo_conv;
extern sudo_printf_t sudo_printf; extern sudo_printf_t sudo_printf;
extern struct sudo_plugin_event * (*plugin_event_alloc)(void); extern struct sudo_plugin_event * (*plugin_event_alloc)(void);
/* sudoers_ctx_free.c */
void sudoers_ctx_free(struct sudoers_context *ctx);
/* sudoers_debug.c */ /* sudoers_debug.c */
bool sudoers_debug_parse_flags(struct sudo_conf_debug_file_list *debug_files, const char *entry); 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); bool sudoers_debug_register(const char *plugin_path, struct sudo_conf_debug_file_list *debug_files);

View File

@@ -0,0 +1,92 @@
/*
* SPDX-License-Identifier: ISC
*
* Copyright (c) 2023 Todd C. Miller <Todd.Miller@sudo.ws>
*
* 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 <config.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#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;
}

View File

@@ -151,7 +151,11 @@ main(int argc, char *argv[])
SET(test_ctx.settings.flags, RUNAS_GROUP_SPECIFIED); SET(test_ctx.settings.flags, RUNAS_GROUP_SPECIFIED);
break; break;
case 'h': 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; break;
case 'i': case 'i':
if (strcasecmp(optarg, "ldif") == 0) { if (strcasecmp(optarg, "ldif") == 0) {
@@ -245,12 +249,20 @@ main(int argc, char *argv[])
} else if (pwflag == 0) { } else if (pwflag == 0) {
usage(); 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; argc = 0;
} else { } else {
if (argc > 2 && sudo_mode == MODE_LIST) if (argc > 2 && sudo_mode == MODE_LIST)
sudo_mode = MODE_CHECK; 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--; argc--;
if (orig_cmnd == NULL) { if (orig_cmnd == NULL) {
orig_cmnd = *argv++; orig_cmnd = *argv++;
@@ -264,7 +276,9 @@ main(int argc, char *argv[])
if (getcwd(cwdbuf, sizeof(cwdbuf)) == NULL) if (getcwd(cwdbuf, sizeof(cwdbuf)) == NULL)
strlcpy(cwdbuf, "/", sizeof(cwdbuf)); 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) if ((test_ctx.user.pw = sudo_getpwnam(test_ctx.user.name)) == NULL)
sudo_fatalx(U_("unknown user %s"), test_ctx.user.name); sudo_fatalx(U_("unknown user %s"), test_ctx.user.name);
@@ -283,8 +297,16 @@ main(int argc, char *argv[])
} else { } else {
test_ctx.user.shost = test_ctx.user.host; test_ctx.user.shost = test_ctx.user.host;
} }
test_ctx.runas.host = test_ctx.user.host; if ((test_ctx.runas.host = strdup(test_ctx.user.host)) == NULL)
test_ctx.runas.shost = test_ctx.user.shost; 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. */ /* Fill in test_ctx.user.cmnd_args from argv. */
if (argc > 0) { if (argc > 0) {
@@ -429,6 +451,7 @@ main(int argc, char *argv[])
} }
done: done:
sudoers_ctx_free(&test_ctx);
sudo_freepwcache(); sudo_freepwcache();
sudo_freegrcache(); sudo_freegrcache();
sudo_debug_exit_int(__func__, __FILE__, __LINE__, sudo_debug_subsys, exitcode); sudo_debug_exit_int(__func__, __FILE__, __LINE__, sudo_debug_subsys, exitcode);

View File

@@ -338,6 +338,7 @@ main(int argc, char *argv[])
free(editor); free(editor);
done: done:
sudoers_ctx_free(&ctx);
sudo_debug_exit_int(__func__, __FILE__, __LINE__, sudo_debug_subsys, exitcode); sudo_debug_exit_int(__func__, __FILE__, __LINE__, sudo_debug_subsys, exitcode);
return exitcode; return exitcode;
} }