diff mbox series

[ovs-dev] ofp-actions: Set an action depth limit to prevent stackoverflow by ofpacts_parse

Message ID 1549068266-26746-1-git-send-email-pkusunyifeng@gmail.com
State Accepted
Headers show
Series [ovs-dev] ofp-actions: Set an action depth limit to prevent stackoverflow by ofpacts_parse | expand

Commit Message

Yifeng Sun Feb. 2, 2019, 12:44 a.m. UTC
Reported-at: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=12557
Signed-off-by: Yifeng Sun <pkusunyifeng@gmail.com>
---
 include/openvswitch/ofp-actions.h | 4 ++++
 lib/ofp-actions.c                 | 5 +++++
 2 files changed, 9 insertions(+)

Comments

Ben Pfaff Feb. 4, 2019, 8:41 p.m. UTC | #1
On Fri, Feb 01, 2019 at 04:44:26PM -0800, Yifeng Sun wrote:
> Reported-at: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=12557
> Signed-off-by: Yifeng Sun <pkusunyifeng@gmail.com>

I'm not enthusiastic about the CONST_CASTs here, but it solves the
problem and I don't expect them to cause a real problem of their own.

Thank you!

I applied this to master and backported as far as it would go.
diff mbox series

Patch

diff --git a/include/openvswitch/ofp-actions.h b/include/openvswitch/ofp-actions.h
index caaa37c05a1d..14c5eab74bd3 100644
--- a/include/openvswitch/ofp-actions.h
+++ b/include/openvswitch/ofp-actions.h
@@ -1175,7 +1175,11 @@  struct ofpact_parse_params {
     /* Output. */
     struct ofpbuf *ofpacts;
     enum ofputil_protocol *usable_protocols;
+
+    /* Parse context. */
+    unsigned int depth;
 };
+#define MAX_OFPACT_PARSE_DEPTH 100
 char *ofpacts_parse_actions(const char *, const struct ofpact_parse_params *)
     OVS_WARN_UNUSED_RESULT;
 char *ofpacts_parse_instructions(const char *,
diff --git a/lib/ofp-actions.c b/lib/ofp-actions.c
index f76db6c0f948..6f175186498d 100644
--- a/lib/ofp-actions.c
+++ b/lib/ofp-actions.c
@@ -9062,11 +9062,16 @@  static char * OVS_WARN_UNUSED_RESULT
 ofpacts_parse(char *str, const struct ofpact_parse_params *pp,
               bool allow_instructions, enum ofpact_type outer_action)
 {
+    if (pp->depth >= MAX_OFPACT_PARSE_DEPTH) {
+        return xstrdup("Action nested too deeply");
+    }
+    CONST_CAST(struct ofpact_parse_params *, pp)->depth++;
     uint32_t orig_size = pp->ofpacts->size;
     char *error = ofpacts_parse__(str, pp, allow_instructions, outer_action);
     if (error) {
         pp->ofpacts->size = orig_size;
     }
+    CONST_CAST(struct ofpact_parse_params *, pp)->depth--;
     return error;
 }