Skip to content

Commit

Permalink
expr: Set a limit on the depth of nested parentheses
Browse files Browse the repository at this point in the history
This patch checks the depth of nested parentheses to prevent
stack overflow. Since is_chassis_resident doesn't allow
nested parentheses, its following parentheses are not taken
into acount in the parentheses-depth context.

Reported-at: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=10714
Signed-off-by: Yifeng Sun <pkusunyifeng@gmail.com>
Suggested-by: Ben Pfaff <blp@ovn.org>
Signed-off-by: Ben Pfaff <blp@ovn.org>
  • Loading branch information
yifsun authored and blp committed Oct 11, 2018
1 parent 22e506d commit 474756f
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 0 deletions.
11 changes: 11 additions & 0 deletions ovn/lib/expr.c
Expand Up @@ -459,13 +459,16 @@ expr_print(const struct expr *e)

/* Parsing. */

#define MAX_PAREN_DEPTH 100

/* Context maintained during expr_parse(). */
struct expr_context {
struct lexer *lexer; /* Lexer for pulling more tokens. */
const struct shash *symtab; /* Symbol table. */
const struct shash *addr_sets; /* Address set table. */
const struct shash *port_groups; /* Port group table. */
bool not; /* True inside odd number of NOT operators. */
unsigned int paren_depth; /* Depth of nested parentheses. */
};

struct expr *expr_parse__(struct expr_context *);
Expand Down Expand Up @@ -1077,7 +1080,15 @@ expr_parse_primary(struct expr_context *ctx, bool *atomic)
{
*atomic = false;
if (lexer_match(ctx->lexer, LEX_T_LPAREN)) {
if (ctx->paren_depth >= MAX_PAREN_DEPTH) {
lexer_error(ctx->lexer, "Parentheses nested too deeply.");
return NULL;
}

ctx->paren_depth++;
struct expr *e = expr_parse__(ctx);
ctx->paren_depth--;

if (!lexer_force_match(ctx->lexer, LEX_T_RPAREN)) {
expr_destroy(e);
return NULL;
Expand Down
4 changes: 4 additions & 0 deletions tests/ovn.at
Expand Up @@ -285,6 +285,8 @@ ip6.src == ::1 => ip6.src == 0x1
inport == "eth0"
!(inport != "eth0") => inport == "eth0"

(((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((0))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) => 0

ip4.src == "eth0" => Integer field ip4.src is not compatible with string constant.
inport == 1 => String field inport is not compatible with integer constant.
ip4.src = 1.2.3.4 => Syntax error at `=' expecting relational operator.
Expand Down Expand Up @@ -351,6 +353,8 @@ eth.dst[40] x => Syntax error at `x' expecting end of input.

ip4.src == {1.2.3.4, $set1, $unknownset} => Syntax error at `$unknownset' expecting address set name.
eth.src == {$set3, badmac, 00:00:00:00:00:01} => Syntax error at `badmac' expecting constant.

((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((())))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) => Parentheses nested too deeply.
]])
sed 's/ =>.*//' test-cases.txt > input.txt
sed 's/.* => //' test-cases.txt > expout
Expand Down

0 comments on commit 474756f

Please sign in to comment.