diff options
author | Daniel Salzman <daniel.salzman@nic.cz> | 2017-06-22 12:16:42 +0200 |
---|---|---|
committer | Daniel Salzman <daniel.salzman@nic.cz> | 2017-06-22 12:16:42 +0200 |
commit | 02a70728cb96e381f435d778f943ad0948d51230 (patch) | |
tree | f6c8d6034a59577ed0eecc00f41b10e47276a7cb | |
parent | tsig: move signature validity period check after the signature validity check (diff) | |
parent | journal: fixed stack overflow by hybrid static-dynamic array (diff) | |
download | knot-02a70728cb96e381f435d778f943ad0948d51230.tar.xz knot-02a70728cb96e381f435d778f943ad0948d51230.zip |
Merge branch 'journal_stack_overflow' into 'master'
journal: fixed stack overflow by hybrid static-dynamic array
See merge request !732
-rw-r--r-- | src/knot/journal/journal.c | 16 |
1 files changed, 14 insertions, 2 deletions
diff --git a/src/knot/journal/journal.c b/src/knot/journal/journal.c index 8f7599944..ac94050e6 100644 --- a/src/knot/journal/journal.c +++ b/src/knot/journal/journal.c @@ -47,6 +47,15 @@ * uint32_t serial_to + uint32_t chunk_count + 24B unused */ #define JOURNAL_HEADER_SIZE (32) +// eventually move to contrib and reuse as needed +#define local_array_max_static_size (100) +#define local_array(type, name, size, retval) \ + type name ## _static__[local_array_max_static_size] = { 0 }; \ + type *name ## _dynamic__ = ((size) > local_array_max_static_size ? calloc((size), sizeof(type)) : NULL); \ + type *name = ((size) > local_array_max_static_size ? name ## _dynamic__ : name ## _static__); \ + if ((retval) != 0 && (name) == NULL) { free(name ## _dynamic__); return (retval); } +#define local_array_free(name) { free(name ## _dynamic__); } + enum { LAST_FLUSHED_VALID = 1 << 0, /* "last flush is valid" flag. */ SERIAL_TO_VALID = 1 << 1, /* "last serial_to is valid" flag. */ @@ -762,8 +771,9 @@ static int normal_iterkeycb(iteration_ctx_t *ctx) static int vals_to_changeset(knot_db_val_t *vals, int nvals, const knot_dname_t *zone_name, changeset_t **ch, bool is_bootstrap) { - uint8_t *valps[nvals]; - size_t vallens[nvals]; + local_array(uint8_t *, valps, nvals, KNOT_ENOMEM) + local_array(size_t, vallens, nvals, KNOT_ENOMEM) + for (int i = 0; i < nvals; i++) { valps[i] = vals[i].data + JOURNAL_HEADER_SIZE; vallens[i] = vals[i].len - JOURNAL_HEADER_SIZE; @@ -777,6 +787,8 @@ static int vals_to_changeset(knot_db_val_t *vals, int nvals, int ret = is_bootstrap ? changeset_deserialize_bootstrap(t_ch, valps, vallens, nvals) : changeset_deserialize(t_ch, valps, vallens, nvals); + local_array_free(valps) + local_array_free(vallens) if (ret != KNOT_EOK) { changeset_free(t_ch); return ret; |