This commit is contained in:
Victor M. Alvarez
2017-11-21 19:33:57 +01:00
parent 2b9dc37bb4
commit ef44bab295
9 changed files with 221 additions and 152 deletions
+4 -61
View File
@@ -56,7 +56,7 @@ static void _yr_compiler_default_include_free(
const char* callback_result_ptr,
void* user_data)
{
if(callback_result_ptr != NULL)
if (callback_result_ptr != NULL)
{
yr_free((void*)callback_result_ptr);
}
@@ -73,14 +73,7 @@ const char* _yr_compiler_default_include_callback(
struct stat stbuf;
#endif
#ifdef _MSC_VER
char* b = NULL;
#endif
char* s = NULL;
char* f;
char* file_buffer;
char buffer[1024];
#ifdef _MSC_VER
long file_size;
@@ -90,62 +83,11 @@ const char* _yr_compiler_default_include_callback(
int fd = -1;
if (calling_rule_filename != NULL)
strlcpy(buffer, calling_rule_filename, sizeof(buffer));
else
buffer[0] = '\0';
s = strrchr(buffer, '/');
#ifdef _MSC_VER
b = strrchr(buffer, '\\'); // in Windows both path delimiters are accepted
#endif
#ifdef _MSC_VER
if (s != NULL || b != NULL)
_sopen_s(&fd, include_name, _O_RDONLY, _SH_DENYRW, _S_IREAD);
#else
if (s != NULL)
fd = open(include_name, O_RDONLY);
#endif
{
#ifdef _MSC_VER
f = (b > s) ? (b + 1) : (s + 1);
#else
f = s + 1;
#endif
strlcpy(f, include_name, sizeof(buffer) - (f - buffer));
f = buffer;
// SECURITY: Potential for directory traversal here.
#ifdef _MSC_VER
_sopen_s(&fd, f, _O_RDONLY, _SH_DENYRW, _S_IREAD);
#else
fd = open(f, O_RDONLY);
#endif
// if include file was not found relative to current source file,
// try to open it with path as specified by user (maybe user wrote
// a full path)
if (fd == -1)
{
f = (char*) include_name;
}
}
else
{
f = (char*) include_name;
}
if (fd == -1)
{
// SECURITY: Potential for directory traversal here.
#ifdef _MSC_VER
_sopen_s(&fd, f, _O_RDONLY, _SH_DENYRW, _S_IREAD);
#else
fd = open(f, O_RDONLY);
#endif
}
if (fd == -1)
return NULL;
@@ -220,6 +162,7 @@ YR_API int yr_compiler_create(
new_compiler->errors = 0;
new_compiler->callback = NULL;
new_compiler->include_callback = _yr_compiler_default_include_callback;
new_compiler->incl_clbk_user_data = NULL;
new_compiler->include_free = _yr_compiler_default_include_free;
new_compiler->last_error = ERROR_SUCCESS;
new_compiler->last_error_line = 0;
+142 -84
View File
@@ -1010,11 +1010,25 @@ with noyywrap then we can remove this pragma.
#define snprintf _snprintf
#endif
#line 1013 "lexer.c"
static int is_absolute_path(
char* path)
{
if (path == NULL)
return FALSE;
#if defined(_WIN32) || defined(__CYGWIN__)
return strlen(path) > 2 &&
path[1] == ':' && (path[2] == '/' || path[2] == '\\');
#else
return strlen(path) > 0 && path[0] == '/';
#endif
}
#line 1027 "lexer.c"
#define YY_NO_UNISTD_H 1
#define YY_NO_INPUT 1
#line 1017 "lexer.c"
#line 1031 "lexer.c"
#define INITIAL 0
#define str 1
@@ -1290,10 +1304,10 @@ YY_DECL
}
{
#line 144 "lexer.l"
#line 158 "lexer.l"
#line 1296 "lexer.c"
#line 1310 "lexer.c"
while ( /*CONSTCOND*/1 ) /* loops until end-of-file is reached */
{
@@ -1360,208 +1374,208 @@ do_action: /* This label is used only to access EOF actions. */
case 1:
YY_RULE_SETUP
#line 146 "lexer.l"
#line 160 "lexer.l"
{ return _DOT_DOT_; }
YY_BREAK
case 2:
YY_RULE_SETUP
#line 147 "lexer.l"
#line 161 "lexer.l"
{ return _LT_; }
YY_BREAK
case 3:
YY_RULE_SETUP
#line 148 "lexer.l"
#line 162 "lexer.l"
{ return _GT_; }
YY_BREAK
case 4:
YY_RULE_SETUP
#line 149 "lexer.l"
#line 163 "lexer.l"
{ return _LE_; }
YY_BREAK
case 5:
YY_RULE_SETUP
#line 150 "lexer.l"
#line 164 "lexer.l"
{ return _GE_; }
YY_BREAK
case 6:
YY_RULE_SETUP
#line 151 "lexer.l"
#line 165 "lexer.l"
{ return _EQ_; }
YY_BREAK
case 7:
YY_RULE_SETUP
#line 152 "lexer.l"
#line 166 "lexer.l"
{ return _NEQ_; }
YY_BREAK
case 8:
YY_RULE_SETUP
#line 153 "lexer.l"
#line 167 "lexer.l"
{ return _SHIFT_LEFT_; }
YY_BREAK
case 9:
YY_RULE_SETUP
#line 154 "lexer.l"
#line 168 "lexer.l"
{ return _SHIFT_RIGHT_; }
YY_BREAK
case 10:
YY_RULE_SETUP
#line 155 "lexer.l"
#line 169 "lexer.l"
{ return _PRIVATE_; }
YY_BREAK
case 11:
YY_RULE_SETUP
#line 156 "lexer.l"
#line 170 "lexer.l"
{ return _GLOBAL_; }
YY_BREAK
case 12:
YY_RULE_SETUP
#line 157 "lexer.l"
#line 171 "lexer.l"
{ return _RULE_; }
YY_BREAK
case 13:
YY_RULE_SETUP
#line 158 "lexer.l"
#line 172 "lexer.l"
{ return _META_; }
YY_BREAK
case 14:
YY_RULE_SETUP
#line 159 "lexer.l"
#line 173 "lexer.l"
{ return _STRINGS_; }
YY_BREAK
case 15:
YY_RULE_SETUP
#line 160 "lexer.l"
#line 174 "lexer.l"
{ return _ASCII_; }
YY_BREAK
case 16:
YY_RULE_SETUP
#line 161 "lexer.l"
#line 175 "lexer.l"
{ return _WIDE_; }
YY_BREAK
case 17:
YY_RULE_SETUP
#line 162 "lexer.l"
#line 176 "lexer.l"
{ return _FULLWORD_; }
YY_BREAK
case 18:
YY_RULE_SETUP
#line 163 "lexer.l"
#line 177 "lexer.l"
{ return _NOCASE_; }
YY_BREAK
case 19:
YY_RULE_SETUP
#line 164 "lexer.l"
#line 178 "lexer.l"
{ return _CONDITION_; }
YY_BREAK
case 20:
YY_RULE_SETUP
#line 165 "lexer.l"
#line 179 "lexer.l"
{ return _TRUE_; }
YY_BREAK
case 21:
YY_RULE_SETUP
#line 166 "lexer.l"
#line 180 "lexer.l"
{ return _FALSE_; }
YY_BREAK
case 22:
YY_RULE_SETUP
#line 167 "lexer.l"
#line 181 "lexer.l"
{ return _NOT_; }
YY_BREAK
case 23:
YY_RULE_SETUP
#line 168 "lexer.l"
#line 182 "lexer.l"
{ return _AND_; }
YY_BREAK
case 24:
YY_RULE_SETUP
#line 169 "lexer.l"
#line 183 "lexer.l"
{ return _OR_; }
YY_BREAK
case 25:
YY_RULE_SETUP
#line 170 "lexer.l"
#line 184 "lexer.l"
{ return _AT_; }
YY_BREAK
case 26:
YY_RULE_SETUP
#line 171 "lexer.l"
#line 185 "lexer.l"
{ return _IN_; }
YY_BREAK
case 27:
YY_RULE_SETUP
#line 172 "lexer.l"
#line 186 "lexer.l"
{ return _OF_; }
YY_BREAK
case 28:
YY_RULE_SETUP
#line 173 "lexer.l"
#line 187 "lexer.l"
{ return _THEM_; }
YY_BREAK
case 29:
YY_RULE_SETUP
#line 174 "lexer.l"
#line 188 "lexer.l"
{ return _FOR_; }
YY_BREAK
case 30:
YY_RULE_SETUP
#line 175 "lexer.l"
#line 189 "lexer.l"
{ return _ALL_; }
YY_BREAK
case 31:
YY_RULE_SETUP
#line 176 "lexer.l"
#line 190 "lexer.l"
{ return _ANY_; }
YY_BREAK
case 32:
YY_RULE_SETUP
#line 177 "lexer.l"
#line 191 "lexer.l"
{ return _ENTRYPOINT_; }
YY_BREAK
case 33:
YY_RULE_SETUP
#line 178 "lexer.l"
#line 192 "lexer.l"
{ return _FILESIZE_; }
YY_BREAK
case 34:
YY_RULE_SETUP
#line 179 "lexer.l"
#line 193 "lexer.l"
{ return _MATCHES_; }
YY_BREAK
case 35:
YY_RULE_SETUP
#line 180 "lexer.l"
#line 194 "lexer.l"
{ return _CONTAINS_; }
YY_BREAK
case 36:
YY_RULE_SETUP
#line 181 "lexer.l"
#line 195 "lexer.l"
{ return _IMPORT_; }
YY_BREAK
case 37:
YY_RULE_SETUP
#line 184 "lexer.l"
#line 198 "lexer.l"
{ BEGIN(comment); }
YY_BREAK
case 38:
YY_RULE_SETUP
#line 185 "lexer.l"
#line 199 "lexer.l"
{ BEGIN(INITIAL); }
YY_BREAK
case 39:
/* rule 39 can match eol */
YY_RULE_SETUP
#line 186 "lexer.l"
#line 200 "lexer.l"
{ /* skip comments */ }
YY_BREAK
case 40:
YY_RULE_SETUP
#line 189 "lexer.l"
#line 203 "lexer.l"
{ /* skip single-line comments */ }
YY_BREAK
case 41:
YY_RULE_SETUP
#line 192 "lexer.l"
#line 206 "lexer.l"
{
yyextra->lex_buf_ptr = yyextra->lex_buf;
yyextra->lex_buf_len = 0;
@@ -1571,33 +1585,76 @@ YY_RULE_SETUP
case 42:
/* rule 42 can match eol */
YY_RULE_SETUP
#line 199 "lexer.l"
#line 213 "lexer.l"
{ yytext_to_buffer; }
YY_BREAK
case 43:
YY_RULE_SETUP
#line 202 "lexer.l"
#line 216 "lexer.l"
{
if (compiler->include_callback != NULL)
{
#ifdef _MSC_VER
char* b = NULL;
#endif
char* s = NULL;
char* f;
char buffer[1024];
const char* included_rules;
char* current_file_name;
char* include_path;
*yyextra->lex_buf_ptr = '\0'; // null-terminate included file path
// move path of current source file into buffer
current_file_name = yr_compiler_get_current_file_name(compiler);
if (current_file_name == NULL ||
compiler->include_callback != _yr_compiler_default_include_callback ||
is_absolute_path(yyextra->lex_buf))
{
include_path = yyextra->lex_buf;
}
else
{
strlcpy(buffer, current_file_name, sizeof(buffer));
s = strrchr(buffer, '/');
#ifdef _MSC_VER
b = strrchr(buffer, '\\'); // in Windows both path delimiters are accepted
#endif
#ifdef _MSC_VER
if (s != NULL || b != NULL)
#else
if (s != NULL)
#endif
{
#ifdef _MSC_VER
f = (b > s) ? (b + 1) : (s + 1);
#else
f = s + 1;
#endif
strlcpy(f, yyextra->lex_buf, sizeof(buffer) - (f - buffer));
include_path = buffer;
}
else
{
include_path = yyextra->lex_buf;
}
}
included_rules = compiler->include_callback(
yyextra->lex_buf,
include_path,
current_file_name,
compiler->current_namespace->name,
compiler->incl_clbk_user_data);
if (included_rules != NULL)
{
int error_code = _yr_compiler_push_file_name(compiler, yyextra->lex_buf);
int error_code = _yr_compiler_push_file_name(compiler, include_path);
if (error_code != ERROR_SUCCESS)
{
@@ -1665,7 +1722,7 @@ case YY_STATE_EOF(str):
case YY_STATE_EOF(regexp):
case YY_STATE_EOF(include):
case YY_STATE_EOF(comment):
#line 286 "lexer.l"
#line 343 "lexer.l"
{
YR_COMPILER* compiler = yyget_extra(yyscanner);
@@ -1681,7 +1738,7 @@ case YY_STATE_EOF(comment):
YY_BREAK
case 44:
YY_RULE_SETUP
#line 300 "lexer.l"
#line 357 "lexer.l"
{
yylval->c_string = yr_strdup(yytext);
@@ -1694,7 +1751,7 @@ YY_RULE_SETUP
YY_BREAK
case 45:
YY_RULE_SETUP
#line 311 "lexer.l"
#line 368 "lexer.l"
{
yylval->c_string = yr_strdup(yytext);
@@ -1707,7 +1764,7 @@ YY_RULE_SETUP
YY_BREAK
case 46:
YY_RULE_SETUP
#line 322 "lexer.l"
#line 379 "lexer.l"
{
yylval->c_string = yr_strdup(yytext);
@@ -1726,7 +1783,7 @@ YY_RULE_SETUP
YY_BREAK
case 47:
YY_RULE_SETUP
#line 339 "lexer.l"
#line 396 "lexer.l"
{
yylval->c_string = yr_strdup(yytext);
@@ -1745,7 +1802,7 @@ YY_RULE_SETUP
YY_BREAK
case 48:
YY_RULE_SETUP
#line 356 "lexer.l"
#line 413 "lexer.l"
{
yylval->c_string = yr_strdup(yytext);
@@ -1764,7 +1821,7 @@ YY_RULE_SETUP
YY_BREAK
case 49:
YY_RULE_SETUP
#line 373 "lexer.l"
#line 430 "lexer.l"
{
char* text = yytext;
@@ -1805,7 +1862,7 @@ YY_RULE_SETUP
YY_BREAK
case 50:
YY_RULE_SETUP
#line 412 "lexer.l"
#line 469 "lexer.l"
{
if (strlen(yytext) > 128)
@@ -1821,7 +1878,7 @@ YY_RULE_SETUP
YY_BREAK
case 51:
YY_RULE_SETUP
#line 426 "lexer.l"
#line 483 "lexer.l"
{
char *endptr;
@@ -1864,7 +1921,7 @@ YY_RULE_SETUP
YY_BREAK
case 52:
YY_RULE_SETUP
#line 466 "lexer.l"
#line 523 "lexer.l"
{
yylval->double_ = atof(yytext);
return _DOUBLE_;
@@ -1872,7 +1929,7 @@ YY_RULE_SETUP
YY_BREAK
case 53:
YY_RULE_SETUP
#line 471 "lexer.l"
#line 528 "lexer.l"
{
char *endptr;
@@ -1891,7 +1948,7 @@ YY_RULE_SETUP
YY_BREAK
case 54:
YY_RULE_SETUP
#line 487 "lexer.l"
#line 544 "lexer.l"
{
char *endptr;
@@ -1910,7 +1967,7 @@ YY_RULE_SETUP
YY_BREAK
case 55:
YY_RULE_SETUP
#line 504 "lexer.l"
#line 561 "lexer.l"
{ /* saw closing quote - all done */
alloc_sized_string(s, yyextra->lex_buf_len);
@@ -1926,7 +1983,7 @@ YY_RULE_SETUP
YY_BREAK
case 56:
YY_RULE_SETUP
#line 518 "lexer.l"
#line 575 "lexer.l"
{
lex_check_space_ok("\t", yyextra->lex_buf_len, LEX_BUF_SIZE);
@@ -1936,7 +1993,7 @@ YY_RULE_SETUP
YY_BREAK
case 57:
YY_RULE_SETUP
#line 526 "lexer.l"
#line 583 "lexer.l"
{
lex_check_space_ok("\n", yyextra->lex_buf_len, LEX_BUF_SIZE);
@@ -1946,7 +2003,7 @@ YY_RULE_SETUP
YY_BREAK
case 58:
YY_RULE_SETUP
#line 534 "lexer.l"
#line 591 "lexer.l"
{
lex_check_space_ok("\"", yyextra->lex_buf_len, LEX_BUF_SIZE);
@@ -1956,7 +2013,7 @@ YY_RULE_SETUP
YY_BREAK
case 59:
YY_RULE_SETUP
#line 542 "lexer.l"
#line 599 "lexer.l"
{
lex_check_space_ok("\\", yyextra->lex_buf_len, LEX_BUF_SIZE);
@@ -1966,7 +2023,7 @@ YY_RULE_SETUP
YY_BREAK
case 60:
YY_RULE_SETUP
#line 550 "lexer.l"
#line 607 "lexer.l"
{
int result;
@@ -1979,13 +2036,13 @@ YY_RULE_SETUP
YY_BREAK
case 61:
YY_RULE_SETUP
#line 561 "lexer.l"
#line 618 "lexer.l"
{ yytext_to_buffer; }
YY_BREAK
case 62:
/* rule 62 can match eol */
YY_RULE_SETUP
#line 564 "lexer.l"
#line 621 "lexer.l"
{
syntax_error("unterminated string");
}
@@ -1993,14 +2050,14 @@ YY_RULE_SETUP
case 63:
/* rule 63 can match eol */
YY_RULE_SETUP
#line 569 "lexer.l"
#line 626 "lexer.l"
{
syntax_error("illegal escape sequence");
}
YY_BREAK
case 64:
YY_RULE_SETUP
#line 574 "lexer.l"
#line 631 "lexer.l"
{
if (yyextra->lex_buf_len > 0)
@@ -2028,7 +2085,7 @@ YY_RULE_SETUP
YY_BREAK
case 65:
YY_RULE_SETUP
#line 600 "lexer.l"
#line 657 "lexer.l"
{
lex_check_space_ok("/", yyextra->lex_buf_len, LEX_BUF_SIZE);
@@ -2038,7 +2095,7 @@ YY_RULE_SETUP
YY_BREAK
case 66:
YY_RULE_SETUP
#line 608 "lexer.l"
#line 665 "lexer.l"
{
lex_check_space_ok("\\.", yyextra->lex_buf_len, LEX_BUF_SIZE);
@@ -2053,20 +2110,20 @@ YY_RULE_SETUP
YY_BREAK
case 67:
YY_RULE_SETUP
#line 621 "lexer.l"
#line 678 "lexer.l"
{ yytext_to_buffer; }
YY_BREAK
case 68:
/* rule 68 can match eol */
YY_RULE_SETUP
#line 624 "lexer.l"
#line 681 "lexer.l"
{
syntax_error("unterminated regular expression");
}
YY_BREAK
case 69:
YY_RULE_SETUP
#line 629 "lexer.l"
#line 686 "lexer.l"
{
yylval->sized_string = NULL;
@@ -2077,7 +2134,7 @@ YY_RULE_SETUP
YY_BREAK
case 70:
YY_RULE_SETUP
#line 638 "lexer.l"
#line 695 "lexer.l"
{
yylval->sized_string = NULL;
@@ -2089,7 +2146,7 @@ YY_RULE_SETUP
case 71:
/* rule 71 can match eol */
YY_RULE_SETUP
#line 647 "lexer.l"
#line 704 "lexer.l"
{
// Match hex-digits with whitespace or comments. The latter are stripped
// out by hex_lexer.l
@@ -2105,12 +2162,12 @@ YY_RULE_SETUP
case 72:
/* rule 72 can match eol */
YY_RULE_SETUP
#line 660 "lexer.l"
#line 717 "lexer.l"
/* skip whitespace */
YY_BREAK
case 73:
YY_RULE_SETUP
#line 662 "lexer.l"
#line 719 "lexer.l"
{
if (yytext[0] >= 32 && yytext[0] < 127)
@@ -2125,10 +2182,10 @@ YY_RULE_SETUP
YY_BREAK
case 74:
YY_RULE_SETUP
#line 674 "lexer.l"
#line 731 "lexer.l"
ECHO;
YY_BREAK
#line 2131 "lexer.c"
#line 2188 "lexer.c"
case YY_END_OF_BUFFER:
{
@@ -3277,7 +3334,7 @@ void yyfree (void * ptr , yyscan_t yyscanner)
#define YYTABLES_NAME "yytables"
#line 674 "lexer.l"
#line 731 "lexer.l"
@@ -3494,3 +3551,4 @@ int yr_lex_parse_rules_fd(
return compiler->errors;
}
+61 -3
View File
@@ -116,6 +116,20 @@ with noyywrap then we can remove this pragma.
#define snprintf _snprintf
#endif
static int is_absolute_path(
char* path)
{
if (path == NULL)
return FALSE;
#if defined(_WIN32) || defined(__CYGWIN__)
return strlen(path) > 2 &&
path[1] == ':' && (path[2] == '/' || path[2] == '\\');
#else
return strlen(path) > 0 && path[0] == '/';
#endif
}
%}
%option reentrant bison-bridge
@@ -203,23 +217,66 @@ include[ \t]+\" {
if (compiler->include_callback != NULL)
{
#ifdef _MSC_VER
char* b = NULL;
#endif
char* s = NULL;
char* f;
char buffer[1024];
const char* included_rules;
char* current_file_name;
char* include_path;
*yyextra->lex_buf_ptr = '\0'; // null-terminate included file path
// move path of current source file into buffer
current_file_name = yr_compiler_get_current_file_name(compiler);
if (current_file_name == NULL ||
compiler->include_callback != _yr_compiler_default_include_callback ||
is_absolute_path(yyextra->lex_buf))
{
include_path = yyextra->lex_buf;
}
else
{
strlcpy(buffer, current_file_name, sizeof(buffer));
s = strrchr(buffer, '/');
#ifdef _MSC_VER
b = strrchr(buffer, '\\'); // in Windows both path delimiters are accepted
#endif
#ifdef _MSC_VER
if (s != NULL || b != NULL)
#else
if (s != NULL)
#endif
{
#ifdef _MSC_VER
f = (b > s) ? (b + 1) : (s + 1);
#else
f = s + 1;
#endif
strlcpy(f, yyextra->lex_buf, sizeof(buffer) - (f - buffer));
include_path = buffer;
}
else
{
include_path = yyextra->lex_buf;
}
}
included_rules = compiler->include_callback(
yyextra->lex_buf,
include_path,
current_file_name,
compiler->current_namespace->name,
compiler->incl_clbk_user_data);
if (included_rules != NULL)
{
int error_code = _yr_compiler_push_file_name(compiler, yyextra->lex_buf);
int error_code = _yr_compiler_push_file_name(compiler, include_path);
if (error_code != ERROR_SUCCESS)
{
@@ -886,3 +943,4 @@ int yr_lex_parse_rules_fd(
return compiler->errors;
}
+1
View File
@@ -0,0 +1 @@
rule baz { condition: true }
+3
View File
@@ -0,0 +1,3 @@
include "include/bar.yar"
rule foo { condition: bar }
+3
View File
@@ -0,0 +1,3 @@
include "../baz.yar"
rule bar { condition: baz }
-1
View File
@@ -1 +0,0 @@
rule test { condition: true }
+2 -2
View File
@@ -105,14 +105,14 @@ void test_file_descriptor()
YR_RULES* rules = NULL;
#if defined(_WIN32) || defined(__CYGWIN__)
HANDLE fd = CreateFile("tests/data/true.yar", GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL);
HANDLE fd = CreateFile("tests/data/baz.yar", GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL);
if (fd == INVALID_HANDLE_VALUE)
{
fputs("CreateFile failed", stderr);
exit(1);
}
#else
int fd = open("tests/data/true.yar", O_RDONLY);
int fd = open("tests/data/baz.yar", O_RDONLY);
if (fd < 0)
{
perror("open");
+5 -1
View File
@@ -1737,7 +1737,11 @@ void test_integer_functions()
void test_include_files()
{
assert_true_rule(
"include \"tests/data/true.yar\" rule t { condition: test }",
"include \"tests/data/baz.yar\" rule t { condition: baz }",
NULL);
assert_true_rule(
"include \"tests/data/foo.yar\" rule t { condition: foo }",
NULL);
}