[ovs-dev] actions: Enforce a maximum limit for nested action depth

Message ID 1541623337-16025-1-git-send-email-pkusunyifeng@gmail.com
State Accepted
Headers show
Series
  • [ovs-dev] actions: Enforce a maximum limit for nested action depth
Related show

Commit Message

Yifeng Sun Nov. 7, 2018, 8:42 p.m.
If nested depth of actions is too deep, then the stack will be overflown
and ovs-vswitch crashes. This patch prevents this by adding a depth limit
to nested actions.

Reported-at: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=11237
Signed-off-by: Yifeng Sun <pkusunyifeng@gmail.com>
---
 ovn/lib/actions.c | 9 +++++++++
 1 file changed, 9 insertions(+)

Comments

Ben Pfaff Nov. 9, 2018, 9:17 p.m. | #1
On Wed, Nov 07, 2018 at 12:42:15PM -0800, Yifeng Sun wrote:
> If nested depth of actions is too deep, then the stack will be overflown
> and ovs-vswitch crashes. This patch prevents this by adding a depth limit
> to nested actions.
> 
> Reported-at: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=11237
> Signed-off-by: Yifeng Sun <pkusunyifeng@gmail.com>

Thank you for the fixes.  I applied all of these to master and
backported this one as far as branch-2.7.

Patch

diff --git a/ovn/lib/actions.c b/ovn/lib/actions.c
index ea720467e786..7b7a89478dfb 100644
--- a/ovn/lib/actions.c
+++ b/ovn/lib/actions.c
@@ -185,12 +185,15 @@  first_ptable(const struct ovnact_encode_params *ep,
             : ep->egress_ptable);
 }
 
+#define MAX_NESTED_ACTION_DEPTH 32
+
 /* Context maintained during ovnacts_parse(). */
 struct action_context {
     const struct ovnact_parse_params *pp; /* Parameters. */
     struct lexer *lexer;        /* Lexer for pulling more tokens. */
     struct ofpbuf *ovnacts;     /* Actions. */
     struct expr *prereqs;       /* Prerequisites to apply to match. */
+    int depth;                  /* Current nested action depth. */
 };
 
 static void parse_actions(struct action_context *, enum lex_type sentinel);
@@ -1092,6 +1095,11 @@  parse_nested_action(struct action_context *ctx, enum ovnact_type type,
         return;
     }
 
+    if (ctx->depth + 1 == MAX_NESTED_ACTION_DEPTH) {
+        lexer_error(ctx->lexer, "maximum depth of nested actions reached");
+        return;
+    }
+
     uint64_t stub[1024 / 8];
     struct ofpbuf nested = OFPBUF_STUB_INITIALIZER(stub);
 
@@ -1100,6 +1108,7 @@  parse_nested_action(struct action_context *ctx, enum ovnact_type type,
         .lexer = ctx->lexer,
         .ovnacts = &nested,
         .prereqs = NULL,
+        .depth = ctx->depth + 1,
     };
     parse_actions(&inner_ctx, LEX_T_RCURLY);