]> git.ipfire.org Git - thirdparty/FORT-validator.git/commitdiff
Add 'asn1-decode-max-stack' arg to set max stack size when decoding ASN1
authorpcarana <pc.moreno2099@gmail.com>
Mon, 28 Oct 2019 23:38:54 +0000 (17:38 -0600)
committerpcarana <pc.moreno2099@gmail.com>
Thu, 31 Oct 2019 19:19:09 +0000 (13:19 -0600)
docs/usage.md
examples/config.json
man/fort.8
src/asn1/decode.c
src/config.c
src/config.h

index 7c8e4b13f45e6d915c697c0259562abc0d00f8d0..d646c068a334cacdc578d0f61ac8c8039004f059 100644 (file)
@@ -36,11 +36,12 @@ command: fort
        21. [`--log.file-name-format`](#--logfile-name-format)
        22. [`--output.roa`](#--outputroa)
        23. [`--output.bgpsec`](#--outputbgpsec)
-       24. [`--configuration-file`](#--configuration-file)
-       25. [`rsync.program`](#rsyncprogram)
-       26. [`rsync.arguments-recursive`](#rsyncarguments-recursive)
-       27. [`rsync.arguments-flat`](#rsyncarguments-flat)
-       28. [`incidences`](#incidences)
+       24. [`--asn1-decode-max-stack`](#--asn1-decode-max-stack)
+       25. [`--configuration-file`](#--configuration-file)
+       26. [`rsync.program`](#rsyncprogram)
+       27. [`rsync.arguments-recursive`](#rsyncarguments-recursive)
+       28. [`rsync.arguments-flat`](#rsyncarguments-flat)
+       29. [`incidences`](#incidences)
 
 ## Syntax
 
@@ -465,6 +466,17 @@ Each line of the result is printed in the following order: _AS, Subject Key Iden
 
 If a value isn't specified, then the BGPsec Router Keys aren't printed.
 
+### `--asn1-decode-max-stack`
+
+- **Type:** Integer
+- **Availability:** `argv` and JSON
+- **Default:** 4096
+- **Range:** 1--[`UINT_MAX`](http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/limits.h.html)
+
+ASN1 decoder max allowed stack size in bytes, utilized to avoid a stack overflow when a large nested ASN1 object is parsed.
+
+This check is merely a caution, since ASN1 decoding functions are recursive and might cause a stack overflow. So, this argument probably won't be necessary in most cases, since the RPKI ASN1 objects don't have nested objects that require too much stack allocation (for now).
+
 ### `--configuration-file`
 
 - **Type:** String (Path to file)
index 6e1b7f1f7a8e984bdb03324351ea2fa30a7c0679..45f2b4e56804664f7a78e0a5f4b6e407d7deb58b 100644 (file)
@@ -54,5 +54,6 @@
   "output": {
     "roa": "/tmp/fort/roas.csv",
     "bgpsec": "/tmp/fort/bgpsec.csv"
-  }
+  },
+  "asn1-decode-max-stack": 4096
 }
index 5f18690e28de1f8fe0489b12976ffd65bb3abe24..fcf0679a96d50d5023fa5d8d546443197515604f 100644 (file)
@@ -541,6 +541,15 @@ value, eg.
 .B \-\-output.bgpsec=-
 .RE
 
+.B \-\-asn1-decode-max-stack=\fIUNSIGNED_INTEGER\fR
+.RS 4
+ASN1 decoder max allowed stack size in bytes, utilized to avoid a stack
+overflow when a large nested ASN1 object is parsed.
+.P
+By default, it has a value of \fI4096\fR (4 kB).
+.RE
+.P
+
 .SH EXAMPLES
 .B fort \-t /tmp/tal \-r /tmp/repository \-\-server.port 9323
 .RS 4
@@ -645,7 +654,8 @@ to a specific value:
   "output": {
     "roa": "/tmp/fort/roas.csv",
     "bgpsec": "/tmp/fort/bgpsec.csv"
-  }
+  },
+  "asn1-decode-max-stack": 4096
 }
 .fi
 .RE
index cc971ab44c8196927efa833483e1fcc796f3faf0..6c28b09a946916732f4858dfed08d702f0639b73 100644 (file)
@@ -2,6 +2,7 @@
 
 #include <errno.h>
 #include "common.h"
+#include "config.h"
 #include "log.h"
 
 #define COND_LOG(log, pr) (log ? pr : -EINVAL)
@@ -97,13 +98,15 @@ asn1_decode(const void *buffer, size_t buffer_size,
     asn_TYPE_descriptor_t const *descriptor, void **result, bool log,
     bool dec_as_der)
 {
+       asn_codec_ctx_t s_codec_ctx;
        asn_dec_rval_t rval;
        int error;
 
        *result = NULL;
+       s_codec_ctx.max_stack_size = config_get_asn1_decode_max_stack();
 
-       /* TODO (next iteration) first argument is more or less important. */
-       rval = ber_decode(0, descriptor, result, buffer, buffer_size);
+       rval = ber_decode(&s_codec_ctx, descriptor, result, buffer,
+           buffer_size);
        if (rval.code != RC_OK) {
                /* Must free partial object according to API contracts. */
                ASN_STRUCT_FREE(*descriptor, *result);
index 67b42c837a7778c13d28bdb01acc44e61c655f9d..b96364eca10bb1d42331672df5f1bbede21534b3 100644 (file)
@@ -94,6 +94,9 @@ struct rpki_config {
                /** File where the validated BGPsec certs will be stored */
                char *bgpsec;
        } output;
+
+       /* ASN1 decoder max stack size allowed */
+       unsigned int asn1_decode_max_stack;
 };
 
 static void print_usage(FILE *, bool);
@@ -376,6 +379,16 @@ static const struct option_field options[] = {
                .arg_doc = "<file>",
        },
 
+       {
+               .id = 8000,
+               .name = "asn1-decode-max-stack",
+               .type = &gt_uint,
+               .offset = offsetof(struct rpki_config, asn1_decode_max_stack),
+               .doc = "ASN1 decoder max stack size, utilized to avoid a stack overflow on large nested ASN1 objects",
+               .min = 1,
+               .max = UINT_MAX,
+       },
+
        { 0 },
 };
 
@@ -579,6 +592,8 @@ set_default_values(void)
        rpki_config.output.roa = NULL;
        rpki_config.output.bgpsec = NULL;
 
+       rpki_config.asn1_decode_max_stack = 4096; /* 4kB */
+
        return 0;
 
 revert_recursive_array:
@@ -878,6 +893,12 @@ config_get_output_bgpsec(void)
        return rpki_config.output.bgpsec;
 }
 
+unsigned int
+config_get_asn1_decode_max_stack(void)
+{
+       return rpki_config.asn1_decode_max_stack;
+}
+
 void
 free_rpki_config(void)
 {
index 036a8cebb49230630140d7bdf98443a663164054..0ec3d7acc381b9b56ef0a446bd8ab62ebd95ab9a 100644 (file)
@@ -39,6 +39,7 @@ char *config_get_rsync_program(void);
 struct string_array const *config_get_rsync_args(bool);
 char const *config_get_output_roa(void);
 char const *config_get_output_bgpsec(void);
+unsigned int config_get_asn1_decode_max_stack(void);
 
 /* Needed public by the JSON module */
 void *get_rpki_config_field(struct option_field const *);