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:
105
parse.lex
105
parse.lex
@@ -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);
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user