summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDaniel Salzman <daniel.salzman@nic.cz>2017-06-22 12:16:42 +0200
committerDaniel Salzman <daniel.salzman@nic.cz>2017-06-22 12:16:42 +0200
commit02a70728cb96e381f435d778f943ad0948d51230 (patch)
treef6c8d6034a59577ed0eecc00f41b10e47276a7cb
parenttsig: move signature validity period check after the signature validity check (diff)
parentjournal: fixed stack overflow by hybrid static-dynamic array (diff)
downloadknot-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.c16
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;