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.
This commit is contained in:
Todd C. Miller
2016-10-31 15:21:18 -06:00
parent a3a545e416
commit 5a8b60e4b4
5 changed files with 32 additions and 14 deletions

View File

@@ -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;

View File

@@ -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);

View File

@@ -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;

View File

@@ -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);

View File

@@ -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;