From: Todd C. Miller Date: Mon, 31 Oct 2016 21:21:18 +0000 (-0600) Subject: Make a copy of the current sudoers path when assigning errorfile. X-Git-Tag: SUDO_1_8_19^2~77 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=5a8b60e4b4666f98cc27909dc3027757a00c7ba6;p=sudo Make a copy of the current sudoers path when assigning errorfile. Fixes a potential use after free in visudo when there is an error in one of the include files. --- diff --git a/plugins/sudoers/gram.c b/plugins/sudoers/gram.c index 97230fc09..7743bf8df 100644 --- a/plugins/sudoers/gram.c +++ b/plugins/sudoers/gram.c @@ -93,7 +93,7 @@ bool sudoers_warnings = true; bool parse_error = false; int errorlineno = -1; -const char *errorfile = NULL; +char *errorfile = NULL; struct defaults_list defaults = TAILQ_HEAD_INITIALIZER(defaults); struct userspec_list userspecs = TAILQ_HEAD_INITIALIZER(userspecs); @@ -702,7 +702,11 @@ sudoerserror(const char *s) /* Save the line the first error occurred on. */ if (errorlineno == -1) { errorlineno = sudolineno; - errorfile = sudoers; + free(errorfile); + errorfile = strdup(sudoers); + if (errorfile == NULL) + sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO, + "unable to allocate memory"); } if (sudoers_warnings && s != NULL) { LEXTRACE("<*> "); @@ -983,12 +987,13 @@ init_parser(const char *path, bool quiet) parse_error = false; errorlineno = -1; - errorfile = sudoers; + free(errorfile); + errorfile = NULL; sudoers_warnings = !quiet; debug_return_bool(ret); } -#line 939 "gram.c" +#line 944 "gram.c" /* allocate initial stack or double stack size, up to YYMAXDEPTH */ #if defined(__cplusplus) || defined(__STDC__) static int yygrowstack(void) @@ -2081,7 +2086,7 @@ case 115: } } break; -#line 2032 "gram.c" +#line 2037 "gram.c" } yyssp -= yym; yystate = *yyssp; diff --git a/plugins/sudoers/gram.y b/plugins/sudoers/gram.y index a1e7819f5..542678618 100644 --- a/plugins/sudoers/gram.y +++ b/plugins/sudoers/gram.y @@ -55,7 +55,7 @@ bool sudoers_warnings = true; bool parse_error = false; int errorlineno = -1; -const char *errorfile = NULL; +char *errorfile = NULL; struct defaults_list defaults = TAILQ_HEAD_INITIALIZER(defaults); struct userspec_list userspecs = TAILQ_HEAD_INITIALIZER(userspecs); @@ -868,7 +868,11 @@ sudoerserror(const char *s) /* Save the line the first error occurred on. */ if (errorlineno == -1) { errorlineno = sudolineno; - errorfile = sudoers; + free(errorfile); + errorfile = strdup(sudoers); + if (errorfile == NULL) + sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO, + "unable to allocate memory"); } if (sudoers_warnings && s != NULL) { LEXTRACE("<*> "); @@ -1149,7 +1153,8 @@ init_parser(const char *path, bool quiet) parse_error = false; errorlineno = -1; - errorfile = sudoers; + free(errorfile); + errorfile = NULL; sudoers_warnings = !quiet; debug_return_bool(ret); diff --git a/plugins/sudoers/sudoers.h b/plugins/sudoers/sudoers.h index 73bf5cc88..65952a544 100644 --- a/plugins/sudoers/sudoers.h +++ b/plugins/sudoers/sudoers.h @@ -266,7 +266,7 @@ int pam_prep_user(struct passwd *); /* gram.y */ int sudoersparse(void); extern char *login_style; -extern const char *errorfile; +extern char *errorfile; extern int errorlineno; extern bool parse_error; extern bool sudoers_warnings; diff --git a/plugins/sudoers/visudo.c b/plugins/sudoers/visudo.c index a0326b614..dec95da1f 100644 --- a/plugins/sudoers/visudo.c +++ b/plugins/sudoers/visudo.c @@ -585,7 +585,9 @@ 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; - errorfile = sp->path; + free(errorfile); + if ((errorfile = strdup(sp->path)) == NULL) + sudo_fatalx(U_("%s: %s"), __func__, U_("unable to allocate memory")); } fclose(sudoersin); if (!parse_error) { @@ -593,7 +595,8 @@ reparse_sudoers(char *editor, int editor_argc, char **editor_argv, if (!check_defaults(SETDEF_ALL, quiet) || check_aliases(strict, quiet) != 0) { parse_error = true; - errorfile = NULL; + free(errorfile); + errorfile = NULL; /* don't know which file */ } } sudoers_setlocale(oldlocale, NULL); @@ -925,14 +928,17 @@ 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; - errorfile = sudoers_file; + free(errorfile); + if ((errorfile = strdup(sudoers_file)) == NULL) + sudo_fatalx(U_("%s: %s"), __func__, U_("unable to allocate memory")); } if (!parse_error) { (void) update_defaults(SETDEF_GENERIC|SETDEF_HOST|SETDEF_USER, true); if (!check_defaults(SETDEF_ALL, quiet) || check_aliases(strict, quiet) != 0) { parse_error = true; - errorfile = NULL; + free(errorfile); + errorfile = NULL; /* don't know which file */ } } sudoers_setlocale(oldlocale, NULL); diff --git a/plugins/sudoers/visudo_json.c b/plugins/sudoers/visudo_json.c index 16c188ac6..21d19c187 100644 --- a/plugins/sudoers/visudo_json.c +++ b/plugins/sudoers/visudo_json.c @@ -1030,7 +1030,9 @@ 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; - errorfile = sudoers_path; + free(errorfile); + if ((errorfile = strdup(sudoers_path)) == NULL) + sudo_fatalx(U_("%s: %s"), __func__, U_("unable to allocate memory")); } ret = !parse_error;