2
0
mirror of https://github.com/sudo-project/sudo.git synced 2025-09-04 08:15:15 +00:00

Add max depth of 128 for the include stack to avoid loops.

Since yyerror() doesn't stop parsing, pass return values back to
yylex and call yyterminate() on error.
This commit is contained in:
Todd C. Miller
2004-09-28 00:47:30 +00:00
parent d1f1af2bce
commit 8c039eac93

105
parse.lex
View File

@@ -66,9 +66,9 @@ static int sawspace = 0;
static int arg_len = 0; static int arg_len = 0;
static int arg_size = 0; static int arg_size = 0;
static void fill __P((char *, int)); static int fill __P((char *, int));
static void fill_cmnd __P((char *, int)); static int fill_cmnd __P((char *, int));
static void fill_args __P((char *, int, int)); static int fill_args __P((char *, int, int));
static int buffer_frob __P((const char *)); static int buffer_frob __P((const char *));
extern void reset_aliases __P((void)); extern void reset_aliases __P((void));
extern void yyerror __P((const char *)); extern void yyerror __P((const char *));
@@ -106,7 +106,8 @@ DEFVAR [a-z_]+
<STARTDEFS>{DEFVAR} { <STARTDEFS>{DEFVAR} {
BEGIN INDEFS; BEGIN INDEFS;
LEXTRACE("DEFVAR "); LEXTRACE("DEFVAR ");
fill(yytext, yyleng); if (!fill(yytext, yyleng))
yyterminate();
return(DEFVAR); return(DEFVAR);
} }
@@ -134,13 +135,15 @@ DEFVAR [a-z_]+
\"([^\"]|\\\")+\" { \"([^\"]|\\\")+\" {
LEXTRACE("WORD(1) "); LEXTRACE("WORD(1) ");
fill(yytext + 1, yyleng - 2); if (!fill(yytext + 1, yyleng - 2))
yyterminate();
return(WORD); return(WORD);
} }
{ENVAR} { {ENVAR} {
LEXTRACE("WORD(2) "); LEXTRACE("WORD(2) ");
fill(yytext, yyleng); if (!fill(yytext, yyleng))
yyterminate();
return(WORD); return(WORD);
} }
} }
@@ -149,14 +152,16 @@ DEFVAR [a-z_]+
\\[\*\?\[\]\!] { \\[\*\?\[\]\!] {
/* quoted fnmatch glob char, pass verbatim */ /* quoted fnmatch glob char, pass verbatim */
LEXTRACE("QUOTEDCHAR "); LEXTRACE("QUOTEDCHAR ");
fill_args(yytext, 2, sawspace); if (!fill_args(yytext, 2, sawspace))
yyterminate();
sawspace = FALSE; sawspace = FALSE;
} }
\\[:\\,= \t#] { \\[:\\,= \t#] {
/* quoted sudoers special char, strip backslash */ /* quoted sudoers special char, strip backslash */
LEXTRACE("QUOTEDCHAR "); LEXTRACE("QUOTEDCHAR ");
fill_args(yytext + 1, 1, sawspace); if (!fill_args(yytext + 1, 1, sawspace))
yyterminate();
sawspace = FALSE; sawspace = FALSE;
} }
@@ -168,7 +173,8 @@ DEFVAR [a-z_]+
[^\\:, \t\n]+ { [^\\:, \t\n]+ {
LEXTRACE("ARG "); LEXTRACE("ARG ");
fill_args(yytext, yyleng, sawspace); if (!fill_args(yytext, yyleng, sawspace))
yyterminate();
sawspace = FALSE; sawspace = FALSE;
} /* a command line arg */ } /* a command line arg */
} }
@@ -182,7 +188,8 @@ DEFVAR [a-z_]+
continue; continue;
*ep = '\0'; *ep = '\0';
/* push current buffer and switch to include file */ /* push current buffer and switch to include file */
push_include(cp); if (!push_include(cp))
yyterminate();
LEXTRACE("INCLUDE\n"); LEXTRACE("INCLUDE\n");
BEGIN INITIAL; BEGIN INITIAL;
} }
@@ -209,7 +216,8 @@ DEFVAR [a-z_]+
} }
<INITIAL>^(Host|Cmnd|User|Runas)_Alias { <INITIAL>^(Host|Cmnd|User|Runas)_Alias {
fill(yytext, yyleng); if (!fill(yytext, yyleng))
yyterminate();
switch (*yytext) { switch (*yytext) {
case 'H': case 'H':
LEXTRACE("HOSTALIAS "); LEXTRACE("HOSTALIAS ");
@@ -261,26 +269,30 @@ TRACE[[:blank:]]*: {
\+{WORD} { \+{WORD} {
/* netgroup */ /* netgroup */
fill(yytext, yyleng); if (!fill(yytext, yyleng))
yyterminate();
LEXTRACE("NETGROUP "); LEXTRACE("NETGROUP ");
return(NETGROUP); return(NETGROUP);
} }
\%{WORD} { \%{WORD} {
/* UN*X group */ /* UN*X group */
fill(yytext, yyleng); if (!fill(yytext, yyleng))
yyterminate();
LEXTRACE("GROUP "); LEXTRACE("GROUP ");
return(USERGROUP); return(USERGROUP);
} }
{DOTTEDQUAD}(\/{DOTTEDQUAD})? { {DOTTEDQUAD}(\/{DOTTEDQUAD})? {
fill(yytext, yyleng); if (!fill(yytext, yyleng))
yyterminate();
LEXTRACE("NTWKADDR "); LEXTRACE("NTWKADDR ");
return(NTWKADDR); return(NTWKADDR);
} }
{DOTTEDQUAD}\/([12][0-9]*|3[0-2]*) { {DOTTEDQUAD}\/([12][0-9]*|3[0-2]*) {
fill(yytext, yyleng); if (!fill(yytext, yyleng))
yyterminate();
LEXTRACE("NTWKADDR "); LEXTRACE("NTWKADDR ");
return(NTWKADDR); return(NTWKADDR);
} }
@@ -296,7 +308,8 @@ TRACE[[:blank:]]*: {
LEXTRACE("ALL "); LEXTRACE("ALL ");
return(ALL); return(ALL);
} else { } else {
fill(yytext, yyleng); if (!fill(yytext, yyleng))
yyterminate();
LEXTRACE("ALIAS "); LEXTRACE("ALIAS ");
return(ALIAS); return(ALIAS);
} }
@@ -304,7 +317,8 @@ TRACE[[:blank:]]*: {
<GOTRUNAS>(#[0-9-]+|{WORD}) { <GOTRUNAS>(#[0-9-]+|{WORD}) {
/* username/uid that user can run command as */ /* username/uid that user can run command as */
fill(yytext, yyleng); if (!fill(yytext, yyleng))
yyterminate();
LEXTRACE("WORD(3) "); LEXTRACE("WORD(3) ");
return(WORD); return(WORD);
} }
@@ -316,25 +330,29 @@ TRACE[[:blank:]]*: {
sudoedit { sudoedit {
BEGIN GOTCMND; BEGIN GOTCMND;
LEXTRACE("COMMAND "); LEXTRACE("COMMAND ");
fill_cmnd(yytext, yyleng); if (!fill_cmnd(yytext, yyleng))
yyterminate();
} /* sudo -e */ } /* sudo -e */
\/(\\[\,:= \t#]|[^\,:=\\ \t\n#])+ { \/(\\[\,:= \t#]|[^\,:=\\ \t\n#])+ {
/* directories can't have args... */ /* directories can't have args... */
if (yytext[yyleng - 1] == '/') { if (yytext[yyleng - 1] == '/') {
LEXTRACE("COMMAND "); LEXTRACE("COMMAND ");
fill_cmnd(yytext, yyleng); if (!fill_cmnd(yytext, yyleng))
yyterminate();
return(COMMAND); return(COMMAND);
} else { } else {
BEGIN GOTCMND; BEGIN GOTCMND;
LEXTRACE("COMMAND "); LEXTRACE("COMMAND ");
fill_cmnd(yytext, yyleng); if (!fill_cmnd(yytext, yyleng))
yyterminate();
} }
} /* a pathname */ } /* a pathname */
<INITIAL,GOTDEFS>{WORD} { <INITIAL,GOTDEFS>{WORD} {
/* a word */ /* a word */
fill(yytext, yyleng); if (!fill(yytext, yyleng))
yyterminate();
LEXTRACE("WORD(4) "); LEXTRACE("WORD(4) ");
return(WORD); return(WORD);
} }
@@ -399,7 +417,7 @@ sudoedit {
} }
%% %%
static void static int
fill(s, len) fill(s, len)
char *s; char *s;
int len; int len;
@@ -409,7 +427,7 @@ fill(s, len)
yylval.string = (char *) malloc(len + 1); yylval.string = (char *) malloc(len + 1);
if (yylval.string == NULL) { if (yylval.string == NULL) {
yyerror("unable to allocate memory"); yyerror("unable to allocate memory");
return; return(FALSE);
} }
/* Copy the string and collapse any escaped characters. */ /* Copy the string and collapse any escaped characters. */
@@ -420,9 +438,10 @@ fill(s, len)
yylval.string[j] = s[i]; yylval.string[j] = s[i];
} }
yylval.string[j] = '\0'; yylval.string[j] = '\0';
return(TRUE);
} }
static void static int
fill_cmnd(s, len) fill_cmnd(s, len)
char *s; char *s;
int len; int len;
@@ -432,16 +451,17 @@ fill_cmnd(s, len)
yylval.command.cmnd = (char *) malloc(++len); yylval.command.cmnd = (char *) malloc(++len);
if (yylval.command.cmnd == NULL) { if (yylval.command.cmnd == NULL) {
yyerror("unable to allocate memory"); yyerror("unable to allocate memory");
return; return(FALSE);
} }
/* copy the string and NULL-terminate it (escapes handled by fnmatch) */ /* copy the string and NULL-terminate it (escapes handled by fnmatch) */
(void) strlcpy(yylval.command.cmnd, s, len); (void) strlcpy(yylval.command.cmnd, s, len);
yylval.command.args = NULL; yylval.command.args = NULL;
return(TRUE);
} }
static void static int
fill_args(s, len, addspace) fill_args(s, len, addspace)
char *s; char *s;
int len; int len;
@@ -468,7 +488,7 @@ fill_args(s, len, addspace)
if (yylval.command.args != NULL) if (yylval.command.args != NULL)
free(yylval.command.args); free(yylval.command.args);
yyerror("unable to allocate memory"); yyerror("unable to allocate memory");
return; return(FALSE);
} else } else
yylval.command.args = p; yylval.command.args = p;
} }
@@ -477,38 +497,49 @@ fill_args(s, len, addspace)
p = yylval.command.args + arg_len; p = yylval.command.args + arg_len;
if (addspace) if (addspace)
*p++ = ' '; *p++ = ' ';
if (strlcpy(p, s, arg_size - (p - yylval.command.args)) != len) if (strlcpy(p, s, arg_size - (p - yylval.command.args)) != len) {
yyerror("fill_args: buffer overflow"); /* paranoia */ yyerror("fill_args: buffer overflow"); /* paranoia */
return(FALSE);
}
arg_len = new_len; arg_len = new_len;
return(TRUE);
} }
#define MAX_INCLUDE_DEPTH 128
int int
buffer_frob(path) buffer_frob(path)
const char *path; const char *path;
{ {
static size_t maxbuf, nbuf; static size_t stacksize, depth;
static YY_BUFFER_STATE *bufstack; static YY_BUFFER_STATE *bufstack;
FILE *fp; FILE *fp;
if (path != NULL) { if (path != NULL) {
/* XXX - have maxdepth */
/* push */ /* push */
if (nbuf >= maxbuf) { if (depth >= stacksize) {
maxbuf += 16; if (depth > MAX_INCLUDE_DEPTH) {
if ((bufstack = realloc(bufstack, maxbuf)) == NULL) yyerror("too many levels of includes");
return(FALSE);
}
stacksize += 16;
if ((bufstack = realloc(bufstack, stacksize)) == NULL) {
yyerror("unable to allocate memory"); yyerror("unable to allocate memory");
return(FALSE);
}
} }
if ((fp = open_sudoers(path)) == NULL) if ((fp = open_sudoers(path)) == NULL) {
yyerror(path); yyerror(path);
bufstack[nbuf++] = YY_CURRENT_BUFFER; return(FALSE);
}
bufstack[depth++] = YY_CURRENT_BUFFER;
yy_switch_to_buffer(yy_create_buffer(fp, YY_BUF_SIZE)); yy_switch_to_buffer(yy_create_buffer(fp, YY_BUF_SIZE));
} else { } else {
/* pop */ /* pop */
if (nbuf == 0) if (depth == 0)
return(FALSE); return(FALSE);
fclose(YY_CURRENT_BUFFER->yy_input_file); fclose(YY_CURRENT_BUFFER->yy_input_file);
yy_delete_buffer(YY_CURRENT_BUFFER); yy_delete_buffer(YY_CURRENT_BUFFER);
yy_switch_to_buffer(bufstack[--nbuf]); yy_switch_to_buffer(bufstack[--depth]);
} }
return(TRUE); return(TRUE);
} }