diff mbox series

[ovs-dev] ofp-actions: Report an error if there are too many actions to parse.

Message ID 20210616203448.2324124-1-i.maximets@ovn.org
State Accepted
Headers show
Series [ovs-dev] ofp-actions: Report an error if there are too many actions to parse. | expand

Commit Message

Ilya Maximets June 16, 2021, 8:34 p.m. UTC
Not a very important fix, but fuzzer times out trying to test parsing
of a huge number of actions.  Fixing that by reporting an error as
soon as ofpacts oversized.

It would be great to use ofpacts_oversized() function instead of manual
size checking, but ofpacts->header here always points to the last
pushed action, so the value that ofpacts_oversized() would check is
always small.

Adding a unit test for this, plus the extra test for too deep nesting.

Reported-at: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=20254
Signed-off-by: Ilya Maximets <i.maximets@ovn.org>
---
 lib/ofp-actions.c    | 4 ++++
 tests/ofp-actions.at | 6 ++++++
 2 files changed, 10 insertions(+)

Comments

Ilya Maximets June 16, 2021, 8:37 p.m. UTC | #1
On 6/16/21 10:34 PM, Ilya Maximets wrote:
> Not a very important fix, but fuzzer times out trying to test parsing
> of a huge number of actions.  Fixing that by reporting an error as
> soon as ofpacts oversized.
> 
> It would be great to use ofpacts_oversized() function instead of manual
> size checking, but ofpacts->header here always points to the last
> pushed action, so the value that ofpacts_oversized() would check is
> always small.

Ugh.  s/ofpacts_oversized/ofpbuf_oversized/
I can fix that on commit if the new version will not be necessary
otherwise.

> 
> Adding a unit test for this, plus the extra test for too deep nesting.
> 
> Reported-at: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=20254
> Signed-off-by: Ilya Maximets <i.maximets@ovn.org>
> ---
>  lib/ofp-actions.c    | 4 ++++
>  tests/ofp-actions.at | 6 ++++++
>  2 files changed, 10 insertions(+)
> 
> diff --git a/lib/ofp-actions.c b/lib/ofp-actions.c
> index 6fb3da507..ecf914eac 100644
> --- a/lib/ofp-actions.c
> +++ b/lib/ofp-actions.c
> @@ -9326,6 +9326,7 @@ static char * OVS_WARN_UNUSED_RESULT
>  ofpacts_parse__(char *str, const struct ofpact_parse_params *pp,
>                  bool allow_instructions, enum ofpact_type outer_action)
>  {
> +    uint32_t orig_size = pp->ofpacts->size;
>      char *key, *value;
>      bool drop = false;
>      char *pos;
> @@ -9370,6 +9371,9 @@ ofpacts_parse__(char *str, const struct ofpact_parse_params *pp,
>          if (error) {
>              return error;
>          }
> +        if (pp->ofpacts->size - orig_size > UINT16_MAX) {
> +            return xasprintf("input too big");
> +        }
>      }
>  
>      if (drop && pp->ofpacts->size) {
> diff --git a/tests/ofp-actions.at b/tests/ofp-actions.at
> index 59093c03c..ef4898abb 100644
> --- a/tests/ofp-actions.at
> +++ b/tests/ofp-actions.at
> @@ -1144,4 +1144,10 @@ bad_action 'apply_actions' 'apply_actions is the default instruction'
>  bad_action 'xyzzy' 'unknown action xyzzy'
>  bad_action 'drop,3' '"drop" must not be accompanied by any other action or instruction'
>  
> +# Too many actions
> +writes=$(printf 'write_actions(%.0s' $(seq 100))
> +bad_action "${writes}" 'Action nested too deeply'
> +outputs=$(printf '1,%.0s' $(seq 4096))
> +bad_action "${outputs}" 'input too big'
> +
>  AT_CLEANUP
>
Alin-Gabriel Serdean July 2, 2021, 11:40 a.m. UTC | #2
From: Alin-Gabriel Serdean <aserdean@ovn.org>

>Not a very important fix, but fuzzer times out trying to test parsing
>of a huge number of actions.  Fixing that by reporting an error as
>soon as ofpacts oversized.
>
>It would be great to use ofpacts_oversized() function instead of manual
>size checking, but ofpacts->header here always points to the last
>pushed action, so the value that ofpacts_oversized() would check is
>always small.
>
>Adding a unit test for this, plus the extra test for too deep nesting.
>
>Reported-at: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=20254
>Signed-off-by: Ilya Maximets <i.maximets@ovn.org>
>
Acked-by: Alin-Gabriel Serdean <aserdean@ovn.org>
Ilya Maximets July 7, 2021, 8:51 p.m. UTC | #3
On 7/2/21 1:40 PM, aserdean@ovn.org wrote:
> From: Alin-Gabriel Serdean <aserdean@ovn.org>
> 
>> Not a very important fix, but fuzzer times out trying to test parsing
>> of a huge number of actions.  Fixing that by reporting an error as
>> soon as ofpacts oversized.
>>
>> It would be great to use ofpacts_oversized() function instead of manual
>> size checking, but ofpacts->header here always points to the last
>> pushed action, so the value that ofpacts_oversized() would check is
>> always small.
>>
>> Adding a unit test for this, plus the extra test for too deep nesting.
>>
>> Reported-at: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=20254
>> Signed-off-by: Ilya Maximets <i.maximets@ovn.org>
>>
> Acked-by: Alin-Gabriel Serdean <aserdean@ovn.org>

Thanks!  Applied.

Best regards, Ilya Maximets.
diff mbox series

Patch

diff --git a/lib/ofp-actions.c b/lib/ofp-actions.c
index 6fb3da507..ecf914eac 100644
--- a/lib/ofp-actions.c
+++ b/lib/ofp-actions.c
@@ -9326,6 +9326,7 @@  static char * OVS_WARN_UNUSED_RESULT
 ofpacts_parse__(char *str, const struct ofpact_parse_params *pp,
                 bool allow_instructions, enum ofpact_type outer_action)
 {
+    uint32_t orig_size = pp->ofpacts->size;
     char *key, *value;
     bool drop = false;
     char *pos;
@@ -9370,6 +9371,9 @@  ofpacts_parse__(char *str, const struct ofpact_parse_params *pp,
         if (error) {
             return error;
         }
+        if (pp->ofpacts->size - orig_size > UINT16_MAX) {
+            return xasprintf("input too big");
+        }
     }
 
     if (drop && pp->ofpacts->size) {
diff --git a/tests/ofp-actions.at b/tests/ofp-actions.at
index 59093c03c..ef4898abb 100644
--- a/tests/ofp-actions.at
+++ b/tests/ofp-actions.at
@@ -1144,4 +1144,10 @@  bad_action 'apply_actions' 'apply_actions is the default instruction'
 bad_action 'xyzzy' 'unknown action xyzzy'
 bad_action 'drop,3' '"drop" must not be accompanied by any other action or instruction'
 
+# Too many actions
+writes=$(printf 'write_actions(%.0s' $(seq 100))
+bad_action "${writes}" 'Action nested too deeply'
+outputs=$(printf '1,%.0s' $(seq 4096))
+bad_action "${outputs}" 'input too big'
+
 AT_CLEANUP