From 5ca586df4a934c4004d6115343f0aa8c4717d27e Mon Sep 17 00:00:00 2001 From: Jeremiah Mackey Date: Fri, 27 Mar 2026 17:13:10 +0000 Subject: [PATCH 1/5] correct lock, semaphore, and thread accounting --- src/routes.c | 6 +++--- src/wolfsentry_util.c | 18 +++++++++--------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/routes.c b/src/routes.c index c240975..39cb2b3 100644 --- a/src/routes.c +++ b/src/routes.c @@ -3545,9 +3545,9 @@ WOLFSENTRY_API wolfsentry_errcode_t wolfsentry_route_table_get_default_event( char *event_label, int *event_label_len) { - if (table->default_event == NULL) - WOLFSENTRY_ERROR_RETURN(ITEM_NOT_FOUND); WOLFSENTRY_SHARED_OR_RETURN(); + if (table->default_event == NULL) + WOLFSENTRY_ERROR_UNLOCK_AND_RETURN(ITEM_NOT_FOUND); if (table->default_event->label_len >= *event_label_len) WOLFSENTRY_ERROR_UNLOCK_AND_RETURN(BUFFER_TOO_SMALL); memcpy(event_label, table->default_event->label, (size_t)(table->default_event->label_len + 1)); @@ -3776,7 +3776,7 @@ WOLFSENTRY_API int wolfsentry_inet6_ntoa(const byte *addr, unsigned int addr_bit int i; const char *start_buf = buf; int this_zerospan_length = 0; - int this_zerospan_offset; + int this_zerospan_offset = 0; int longest_zerospan_length = 0; int longest_zerospan_offset = 0; diff --git a/src/wolfsentry_util.c b/src/wolfsentry_util.c index 340f540..f4c537c 100644 --- a/src/wolfsentry_util.c +++ b/src/wolfsentry_util.c @@ -1613,7 +1613,7 @@ static const struct wolfsentry_semcbs builtin_sem_methods = #define sem_init (hpi->semcbs.sem_init ? hpi->semcbs.sem_init : builtin_sem_methods.sem_init) #define sem_post (hpi->semcbs.sem_post ? hpi->semcbs.sem_post : builtin_sem_methods.sem_post) -#define sem_wait (hpi->emcbs->sem_wait ? hpi->emcbs->sem_wait : builtin_sem_methods.sem_wait) +#define sem_wait (hpi->semcbs.sem_wait ? hpi->semcbs.sem_wait : builtin_sem_methods.sem_wait) #define sem_timedwait (hpi->semcbs.sem_timedwait ? hpi->semcbs.sem_timedwait : builtin_sem_methods.sem_timedwait) #define sem_trywait (hpi->semcbs.sem_trywait ? hpi->semcbs.sem_trywait : builtin_sem_methods.sem_trywait) #define sem_destroy (hpi->semcbs.sem_destroy ? hpi->semcbs.sem_destroy : builtin_sem_methods.sem_destroy) @@ -1622,7 +1622,7 @@ static const struct wolfsentry_semcbs builtin_sem_methods = #define sem_init (hpi->semcbs.sem_init) #define sem_post (hpi->semcbs.sem_post) -#define sem_wait (hpi->emcbs->sem_wait) +#define sem_wait (hpi->semcbs.sem_wait) #define sem_timedwait (hpi->semcbs.sem_timedwait) #define sem_trywait (hpi->semcbs.sem_trywait) #define sem_destroy (hpi->semcbs.sem_destroy) @@ -1674,14 +1674,11 @@ WOLFSENTRY_API wolfsentry_errcode_t wolfsentry_lock_init(struct wolfsentry_host_ goto out; free_write_waiters: - if (sem_init(&lock->sem_write_waiters, (flags & WOLFSENTRY_LOCK_FLAG_PSHARED) != 0, 0 /* value */) < 0) - WOLFSENTRY_ERROR_RETURN(SYS_RESOURCE_FAILED); + (void)sem_destroy(&lock->sem_write_waiters); free_read_waiters: - if (sem_init(&lock->sem_read_waiters, (flags & WOLFSENTRY_LOCK_FLAG_PSHARED) != 0, 0 /* value */) < 0) - WOLFSENTRY_ERROR_RETURN(SYS_RESOURCE_FAILED); + (void)sem_destroy(&lock->sem_read_waiters); free_sem: - if (sem_init(&lock->sem, (flags & WOLFSENTRY_LOCK_FLAG_PSHARED) != 0, 1 /* value */) < 0) - WOLFSENTRY_ERROR_RETURN(SYS_RESOURCE_FAILED); + (void)sem_destroy(&lock->sem); out: @@ -1961,7 +1958,7 @@ WOLFSENTRY_API wolfsentry_errcode_t wolfsentry_lock_shared_abstimed(struct wolfs if (sem_trywait(&lock->sem_read_waiters) == 0) { if (sem_post(&lock->sem) < 0) WOLFSENTRY_ERROR_RETURN(SYS_OP_FATAL); - WOLFSENTRY_RETURN_OK; + goto got_read; } --lock->read_waiter_count; @@ -1972,6 +1969,8 @@ WOLFSENTRY_API wolfsentry_errcode_t wolfsentry_lock_shared_abstimed(struct wolfs WOLFSENTRY_ERROR_RERETURN(ret); } + got_read: + ++thread->shared_count; if (! thread->tracked_shared_lock) { thread->tracked_shared_lock = lock; @@ -2276,6 +2275,7 @@ WOLFSENTRY_API wolfsentry_errcode_t wolfsentry_lock_mutex_abstimed(struct wolfse if (sem_trywait(&lock->sem_write_waiters) == 0) { if (sem_post(&lock->sem) < 0) WOLFSENTRY_ERROR_RETURN(SYS_OP_FATAL); + WOLFSENTRY_ATOMIC_STORE(lock->write_lock_holder, WOLFSENTRY_THREAD_GET_ID); if (thread) ++thread->mutex_and_reservation_count; WOLFSENTRY_RETURN_OK; From b706fac6adac55bf92bb1fecb62362f661560d98 Mon Sep 17 00:00:00 2001 From: Jeremiah Mackey Date: Fri, 27 Mar 2026 17:12:14 +0000 Subject: [PATCH 2/5] correct route matching, dispatch, and purge logic --- src/addr_families.c | 2 +- src/routes.c | 16 +++++++++++----- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/src/addr_families.c b/src/addr_families.c index de8f9c6..74b1f67 100644 --- a/src/addr_families.c +++ b/src/addr_families.c @@ -324,7 +324,7 @@ WOLFSENTRY_LOCAL wolfsentry_errcode_t wolfsentry_addr_family_clone( if ((*new_bynumber = (struct wolfsentry_addr_family_bynumber *)WOLFSENTRY_MALLOC_1(dest_context->hpi.allocator, sizeof **new_bynumber)) == NULL) WOLFSENTRY_ERROR_RETURN(SYS_RESOURCE_FAILED); if ((*new_byname = (struct wolfsentry_addr_family_byname *)WOLFSENTRY_MALLOC_1(dest_context->hpi.allocator, byname_size)) == NULL) { - (void)WOLFSENTRY_FREE_1(dest_context->hpi.allocator, (void *)new_byname); + (void)WOLFSENTRY_FREE_1(dest_context->hpi.allocator, (void *)*new_bynumber); WOLFSENTRY_ERROR_RETURN(SYS_RESOURCE_FAILED); } memcpy(*new_bynumber, src_bynumber, sizeof **new_bynumber); diff --git a/src/routes.c b/src/routes.c index 39cb2b3..1661025 100644 --- a/src/routes.c +++ b/src/routes.c @@ -520,7 +520,7 @@ static int compare_match_exactness(const struct wolfsentry_route *target, const } else #endif { - right_match_score = addr_prefix_match_size(WOLFSENTRY_ROUTE_LOCAL_ADDR(target), WOLFSENTRY_ROUTE_LOCAL_ADDR_BITS(target), WOLFSENTRY_ROUTE_LOCAL_ADDR(right), WOLFSENTRY_ROUTE_LOCAL_ADDR_BITS(right)); + right_match_score = addr_prefix_match_size(WOLFSENTRY_ROUTE_REMOTE_ADDR(target), WOLFSENTRY_ROUTE_REMOTE_ADDR_BITS(target), WOLFSENTRY_ROUTE_REMOTE_ADDR(right), WOLFSENTRY_ROUTE_REMOTE_ADDR_BITS(right)); } } @@ -2562,9 +2562,11 @@ static wolfsentry_errcode_t wolfsentry_route_event_dispatch_0( (WOLFSENTRY_ATOMIC_LOAD(rule_route->meta.derogatory_count) >= config->config.derogatory_threshold_for_penaltybox) : - (WOLFSENTRY_ATOMIC_LOAD(rule_route->meta.derogatory_count) - - WOLFSENTRY_ATOMIC_LOAD(rule_route->meta.commendable_count) - >= (int)config->config.derogatory_threshold_for_penaltybox))) + ((WOLFSENTRY_ATOMIC_LOAD(rule_route->meta.derogatory_count) + >= WOLFSENTRY_ATOMIC_LOAD(rule_route->meta.commendable_count)) + && ((wolfsentry_hitcount_t)(WOLFSENTRY_ATOMIC_LOAD(rule_route->meta.derogatory_count) + - WOLFSENTRY_ATOMIC_LOAD(rule_route->meta.commendable_count)) + >= config->config.derogatory_threshold_for_penaltybox)))) { wolfsentry_route_flags_t flags_before; WOLFSENTRY_WARN_ON_FAILURE( @@ -2961,6 +2963,10 @@ static wolfsentry_errcode_t wolfsentry_route_event_dispatch_by_route_1( goto out; } + if (route->header.parent_table == NULL) { + ret = WOLFSENTRY_ERROR_ENCODE(INTERNAL_CHECK_FATAL); + goto out; + } if (route->header.parent_table->ent_type != WOLFSENTRY_OBJECT_TYPE_ROUTE) { ret = WOLFSENTRY_ERROR_ENCODE(WRONG_OBJECT); goto out; @@ -3095,7 +3101,7 @@ static wolfsentry_errcode_t wolfsentry_route_stale_purge_1( (! (route->flags & WOLFSENTRY_ROUTE_FLAG_PENDING_DELETE)) && ((table->max_purgeable_idle_time == 0) || (now - route->meta.last_hit_time > table->max_purgeable_idle_time))) { - continue; + break; } } #ifdef WOLFSENTRY_THREADSAFE From c84e2df2a9b91afa5f984a06b24f71af078c1605 Mon Sep 17 00:00:00 2001 From: Jeremiah Mackey Date: Fri, 27 Mar 2026 17:14:11 +0000 Subject: [PATCH 3/5] correct route rendering output streams --- src/routes.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/routes.c b/src/routes.c index 1661025..6bdecab 100644 --- a/src/routes.c +++ b/src/routes.c @@ -4439,8 +4439,6 @@ static wolfsentry_errcode_t wolfsentry_route_render_address(WOLFSENTRY_CONTEXT_A int fmt_buf_len = (int)sizeof(fmt_buf); int ret = wolfsentry_inet6_ntoa(addr, addr_bits, fmt_buf, &fmt_buf_len); WOLFSENTRY_RERETURN_IF_ERROR(ret); - if (fprintf(f, "%.*s/%u", fmt_buf_len, fmt_buf, addr_bits) < 0) - WOLFSENTRY_ERROR_RETURN(IO_FAILED); if (fprintf(f, "[%.*s]/%u", fmt_buf_len, fmt_buf, addr_bits) < 0) WOLFSENTRY_ERROR_RETURN(IO_FAILED); } else if (sa_family == WOLFSENTRY_AF_LOCAL) { @@ -4523,7 +4521,7 @@ WOLFSENTRY_API wolfsentry_errcode_t wolfsentry_route_render_flags(wolfsentry_rou } else already = 1; if (rendername == NULL) { - if (fprintf(stderr, "unk-0x%x", masked_flags) < 0) + if (fprintf(f, "unk-0x%x", masked_flags) < 0) WOLFSENTRY_ERROR_RETURN(IO_FAILED); } else { if (fputs(rendername, f) < 0) @@ -4542,7 +4540,7 @@ static wolfsentry_errcode_t wolfsentry_route_render_endpoint(WOLFSENTRY_CONTEXT_ const byte *addr = (sa_local_p ? WOLFSENTRY_ROUTE_LOCAL_ADDR(r) : WOLFSENTRY_ROUTE_REMOTE_ADDR(r)); if (sa_local_p ? (r->flags & WOLFSENTRY_ROUTE_FLAG_SA_LOCAL_ADDR_WILDCARD) : (r->flags & WOLFSENTRY_ROUTE_FLAG_SA_REMOTE_ADDR_WILDCARD)) { - if (fputs("*", stdout) < 0) + if (fputs("*", f) < 0) WOLFSENTRY_ERROR_RETURN(IO_FAILED); } #ifdef WOLFSENTRY_ADDR_BITMASK_MATCHING @@ -4648,7 +4646,7 @@ static wolfsentry_errcode_t wolfsentry_route_exports_render_endpoint(WOLFSENTRY_ const byte *addr = (sa_local_p ? r->local_address : r->remote_address); if (sa_local_p ? (r->flags & WOLFSENTRY_ROUTE_FLAG_SA_LOCAL_ADDR_WILDCARD) : (r->flags & WOLFSENTRY_ROUTE_FLAG_SA_REMOTE_ADDR_WILDCARD)) { - if (fputs("*", stdout) < 0) + if (fputs("*", f) < 0) WOLFSENTRY_ERROR_RETURN(IO_FAILED); } #ifdef WOLFSENTRY_ADDR_BITMASK_MATCHING From 53dd90f97d861b8707bda8d9eca0f7f5b394deb1 Mon Sep 17 00:00:00 2001 From: Jeremiah Mackey Date: Fri, 27 Mar 2026 17:16:36 +0000 Subject: [PATCH 4/5] harden JSON parser error handling and bounds checks --- src/json/centijson_dom.c | 19 ++++++++++++++++--- src/json/centijson_sax.c | 17 +++++++++++++---- src/json/centijson_value.c | 14 ++++++++++---- 3 files changed, 39 insertions(+), 11 deletions(-) diff --git a/src/json/centijson_dom.c b/src/json/centijson_dom.c index ba28438..cf880d9 100644 --- a/src/json/centijson_dom.c +++ b/src/json/centijson_dom.c @@ -266,10 +266,17 @@ json_dom_process(JSON_TYPE type, const unsigned char* data, size_t data_size, vo * append their json_values. */ if(dom_parser->path_size >= dom_parser->path_alloc) { JSON_VALUE** new_path; - size_t new_path_alloc = dom_parser->path_alloc * 2; + size_t new_path_alloc; - if(new_path_alloc == 0) + if(dom_parser->path_alloc == 0) { new_path_alloc = 32; + } + else if(dom_parser->path_alloc > SIZE_MAX / 2 / sizeof(JSON_VALUE*)) { + return JSON_ERR_OUTOFMEMORY; + } + else { + new_path_alloc = dom_parser->path_alloc * 2; + } new_path = (JSON_VALUE**) realloc((void *)dom_parser->path, new_path_alloc * sizeof(JSON_VALUE*)); if(new_path == NULL) return JSON_ERR_OUTOFMEMORY; @@ -617,8 +624,14 @@ json_dom_dump_helper( keys_size = json_value_dict_keys_ordered(node, keys, n); else keys_size = json_value_dict_keys_sorted(node, keys, n); - if (keys_size != n) + if (keys_size != n) { +#ifdef WOLFSENTRY + json_free(WOLFSENTRY_CONTEXT_ARGS_OUT_EX(allocator), (void *)keys); +#else + free((void *)keys); +#endif return JSON_ERR_INTERNAL; + } for(i = 0; i < n; i++) { JSON_VALUE* json_value; diff --git a/src/json/centijson_sax.c b/src/json/centijson_sax.c index 5471bc7..e65b406 100644 --- a/src/json/centijson_sax.c +++ b/src/json/centijson_sax.c @@ -857,10 +857,11 @@ json_feed(JSON_PARSER* parser, const unsigned char* input, size_t size) { /* Update parser->pos to point to the exact place. */ while(parser->pos.offset < parser->config.max_total_len) { + ch = input[off]; + off++; parser->pos.offset++; parser->pos.column_number++; - off++; - json_handle_new_line(parser, input[off]); + json_handle_new_line(parser, ch); } json_raise(parser, JSON_ERR_MAXTOTALLEN); @@ -891,10 +892,18 @@ json_feed(JSON_PARSER* parser, const unsigned char* input, size_t size) if(parser->nesting_level >= parser->nesting_stack_size) { unsigned char* new_nesting_stack; - size_t new_nesting_stack_size = parser->nesting_stack_size * 2; + size_t new_nesting_stack_size; - if(new_nesting_stack_size == 0) + if(parser->nesting_stack_size == 0) { new_nesting_stack_size = 32; + } + else if(parser->nesting_stack_size > SIZE_MAX / 2) { + json_raise(parser, JSON_ERR_OUTOFMEMORY); + break; + } + else { + new_nesting_stack_size = parser->nesting_stack_size * 2; + } new_nesting_stack = (unsigned char *)realloc(parser->nesting_stack, new_nesting_stack_size); if(new_nesting_stack == NULL) { json_raise(parser, JSON_ERR_OUTOFMEMORY); diff --git a/src/json/centijson_value.c b/src/json/centijson_value.c index 9d61c88..857ca1c 100644 --- a/src/json/centijson_value.c +++ b/src/json/centijson_value.c @@ -1794,15 +1794,21 @@ json_value_dict_clean( WOLFSENTRY_CONTEXT_ARGS_OUT_EX(allocator), #endif &node->key); - if (ret < 0) + if (ret < 0) { + free(node); + free((void *)stack); return ret; + } ret = json_value_fini( #ifdef WOLFSENTRY WOLFSENTRY_CONTEXT_ARGS_OUT_EX(allocator), #endif &node->json_value); - if (ret < 0) + if (ret < 0) { + free(node); + free((void *)stack); return ret; + } free(node); stack_size += json_value_dict_leftmost_path(stack + stack_size, right); @@ -1928,6 +1934,8 @@ json_value_clone(WOLFSENTRY_CONTEXT_ARGS_IN_EX(struct wolfsentry_allocator *allo break; } ret = json_value_clone(WOLFSENTRY_CONTEXT_ARGS_OUT_EX(allocator), &src_dict_node->json_value, dest_node); + if (ret < 0) + break; src_dict_node = src_dict_node->order_next; } } else { @@ -1954,8 +1962,6 @@ json_value_clone(WOLFSENTRY_CONTEXT_ARGS_IN_EX(struct wolfsentry_allocator *allo } free((void *)stack); - - break; } if (ret < 0) { int ret2 = json_value_fini(WOLFSENTRY_CONTEXT_ARGS_OUT_EX(allocator), clone); From f936ad7b1927d2aafa0c6c8187a7a2eafc348e6d Mon Sep 17 00:00:00 2001 From: Jeremiah Mackey Date: Fri, 27 Mar 2026 17:12:14 +0000 Subject: [PATCH 5/5] correct config, KV, protocol, and utility logic --- src/json/centijson_value.c | 34 +++++++++++++++++----------------- src/json/load_config.c | 9 ++++++++- src/kv.c | 2 +- src/lwip/packet_filter_glue.c | 4 ++-- src/routes.c | 28 ++++++++++++++++++---------- src/wolfsentry_util.c | 8 ++++---- 6 files changed, 50 insertions(+), 35 deletions(-) diff --git a/src/json/centijson_value.c b/src/json/centijson_value.c index 857ca1c..51cf405 100644 --- a/src/json/centijson_value.c +++ b/src/json/centijson_value.c @@ -1943,31 +1943,31 @@ json_value_clone(WOLFSENTRY_CONTEXT_ARGS_IN_EX(struct wolfsentry_allocator *allo RBTREE **stack = (RBTREE **)malloc(rbtree_stack_size_needed(src_dict)); /* put this on the heap to avoid runaway growth of stack on deep JSON trees. */ if (! stack) { ret = JSON_ERR_OUTOFMEMORY; - break; - } - - stack_size = json_value_dict_leftmost_path(stack, src_dict->root); - - while(stack_size > 0) { - src_dict_node = stack[--stack_size]; - dest_node = json_value_dict_get_or_add_(WOLFSENTRY_CONTEXT_ARGS_OUT_EX(allocator), clone, json_value_string(&src_dict_node->key), json_value_string_length(&src_dict_node->key)); - if (! dest_node) { - ret = JSON_ERR_OUTOFMEMORY; - break; + } else { + stack_size = json_value_dict_leftmost_path(stack, src_dict->root); + + while(stack_size > 0) { + src_dict_node = stack[--stack_size]; + dest_node = json_value_dict_get_or_add_(WOLFSENTRY_CONTEXT_ARGS_OUT_EX(allocator), clone, json_value_string(&src_dict_node->key), json_value_string_length(&src_dict_node->key)); + if (! dest_node) { + ret = JSON_ERR_OUTOFMEMORY; + break; + } + ret = json_value_clone(WOLFSENTRY_CONTEXT_ARGS_OUT_EX(allocator), &src_dict_node->json_value, dest_node); + if (ret < 0) + break; + stack_size += json_value_dict_leftmost_path(stack + stack_size, src_dict_node->right); } - ret = json_value_clone(WOLFSENTRY_CONTEXT_ARGS_OUT_EX(allocator), &src_dict_node->json_value, dest_node); - if (ret < 0) - break; - stack_size += json_value_dict_leftmost_path(stack + stack_size, src_dict_node->right); - } - free((void *)stack); + free((void *)stack); + } } if (ret < 0) { int ret2 = json_value_fini(WOLFSENTRY_CONTEXT_ARGS_OUT_EX(allocator), clone); if (ret2 < 0) WOLFSENTRY_WARN("json_value_fini: %s\n", json_error_str(ret2)); } + break; } } diff --git a/src/json/load_config.c b/src/json/load_config.c index 7a03213..eb33d9c 100644 --- a/src/json/load_config.c +++ b/src/json/load_config.c @@ -26,6 +26,7 @@ #define WOLFSENTRY_SOURCE_ID WOLFSENTRY_SOURCE_ID_JSON_LOAD_CONFIG_C #include +#include #define MAX_IPV4_ADDR_BITS (sizeof(struct in_addr) * BITS_PER_BYTE) #define MAX_IPV6_ADDR_BITS (sizeof(struct in6_addr) * BITS_PER_BYTE) @@ -384,12 +385,18 @@ static wolfsentry_errcode_t convert_wolfsentry_duration(struct wolfsentry_contex switch (*endptr) { case 'd': + if (conv > LONG_MAX / 24 || conv < LONG_MIN / 24) + WOLFSENTRY_ERROR_RETURN(CONFIG_INVALID_VALUE); conv *= 24; /* fallthrough */ case 'h': + if (conv > LONG_MAX / 60 || conv < LONG_MIN / 60) + WOLFSENTRY_ERROR_RETURN(CONFIG_INVALID_VALUE); conv *= 60; /* fallthrough */ case 'm': + if (conv > LONG_MAX / 60 || conv < LONG_MIN / 60) + WOLFSENTRY_ERROR_RETURN(CONFIG_INVALID_VALUE); conv *= 60; /* fallthrough */ case 's': @@ -1968,7 +1975,7 @@ WOLFSENTRY_API wolfsentry_errcode_t wolfsentry_config_json_fini( struct wolfsentry_route_table *old_route_table, *new_route_table; if ((ret = wolfsentry_route_get_main_table(JPSP_WOLFSENTRY_ACTUAL_CONTEXT_ARGS_OUT, &old_route_table)) < 0) goto out; - if ((ret = wolfsentry_route_get_main_table(JPSP_WOLFSENTRY_ACTUAL_CONTEXT_ARGS_OUT, &new_route_table)) < 0) + if ((ret = wolfsentry_route_get_main_table(JPSP_WOLFSENTRY_CONTEXT_ARGS_OUT, &new_route_table)) < 0) goto out; if (wolfsentry_table_n_deletes((struct wolfsentry_table_header *)new_route_table) != wolfsentry_table_n_deletes((struct wolfsentry_table_header *)old_route_table)) diff --git a/src/kv.c b/src/kv.c index 601737f..1a6e9d9 100644 --- a/src/kv.c +++ b/src/kv.c @@ -1054,7 +1054,7 @@ WOLFSENTRY_API wolfsentry_errcode_t wolfsentry_user_value_get_json( struct wolfsentry_kv_pair_internal **user_value_record) { wolfsentry_errcode_t ret; - if ((ret = wolfsentry_kv_get_reference(WOLFSENTRY_CONTEXT_ARGS_OUT, wolfsentry->user_values, key, key_len, WOLFSENTRY_KV_STRING, user_value_record)) < 0) + if ((ret = wolfsentry_kv_get_reference(WOLFSENTRY_CONTEXT_ARGS_OUT, wolfsentry->user_values, key, key_len, WOLFSENTRY_KV_JSON, user_value_record)) < 0) WOLFSENTRY_ERROR_RERETURN(ret); *value = WOLFSENTRY_KV_V_JSON(&(*user_value_record)->kv); WOLFSENTRY_RETURN_OK; diff --git a/src/lwip/packet_filter_glue.c b/src/lwip/packet_filter_glue.c index 1e5e1dc..7b71bc6 100644 --- a/src/lwip/packet_filter_glue.c +++ b/src/lwip/packet_filter_glue.c @@ -1098,10 +1098,10 @@ static err_t icmp6_filter_with_wolfsentry( else memset(&local.local.addr, 0, sizeof *laddr); - remote.remote.sa_proto = IPPROTO_ICMP; + remote.remote.sa_proto = IPPROTO_ICMPV6; remote.remote.sa_port = 0; - local.local.sa_proto = IPPROTO_ICMP; + local.local.sa_proto = IPPROTO_ICMPV6; local.local.sa_port = icmp6_type; if (event->netif) diff --git a/src/routes.c b/src/routes.c index 6bdecab..34baa90 100644 --- a/src/routes.c +++ b/src/routes.c @@ -2366,6 +2366,9 @@ static wolfsentry_errcode_t wolfsentry_route_event_dispatch_0( wolfsentry_route_flags_t current_rule_route_flags; wolfsentry_errcode_t ret; wolfsentry_time_t now; + int penalty_triggered = 0; + wolfsentry_hitcount_t derog_snap; + wolfsentry_hitcount_t commend_snap; if (target_route == NULL) WOLFSENTRY_ERROR_RETURN(INVALID_ARG); @@ -2553,20 +2556,25 @@ static wolfsentry_errcode_t wolfsentry_route_event_dispatch_0( } } + /* Snapshot atomic counts once so the guard and arithmetic operate on the + * same values (avoid TOCTOU between successive loads). */ + derog_snap = WOLFSENTRY_ATOMIC_LOAD(rule_route->meta.derogatory_count); + commend_snap = WOLFSENTRY_ATOMIC_LOAD(rule_route->meta.commendable_count); + if (config->config.derogatory_threshold_for_penaltybox > 0) { + if (config->config.flags & WOLFSENTRY_EVENTCONFIG_FLAG_DEROGATORY_THRESHOLD_IGNORE_COMMENDABLE) { + penalty_triggered = (derog_snap >= config->config.derogatory_threshold_for_penaltybox); + } else { + penalty_triggered = (derog_snap >= commend_snap) + && ((derog_snap - commend_snap) + >= config->config.derogatory_threshold_for_penaltybox); + } + } + if (current_rule_route_flags & WOLFSENTRY_ROUTE_FLAG_PENALTYBOXED) { *action_results |= WOLFSENTRY_ACTION_RES_REJECT; ret = WOLFSENTRY_ERROR_ENCODE(OK); goto done; - } else if ((config->config.derogatory_threshold_for_penaltybox > 0) - && ((config->config.flags & WOLFSENTRY_EVENTCONFIG_FLAG_DEROGATORY_THRESHOLD_IGNORE_COMMENDABLE) ? - (WOLFSENTRY_ATOMIC_LOAD(rule_route->meta.derogatory_count) - >= config->config.derogatory_threshold_for_penaltybox) - : - ((WOLFSENTRY_ATOMIC_LOAD(rule_route->meta.derogatory_count) - >= WOLFSENTRY_ATOMIC_LOAD(rule_route->meta.commendable_count)) - && ((wolfsentry_hitcount_t)(WOLFSENTRY_ATOMIC_LOAD(rule_route->meta.derogatory_count) - - WOLFSENTRY_ATOMIC_LOAD(rule_route->meta.commendable_count)) - >= config->config.derogatory_threshold_for_penaltybox)))) + } else if (penalty_triggered) { wolfsentry_route_flags_t flags_before; WOLFSENTRY_WARN_ON_FAILURE( diff --git a/src/wolfsentry_util.c b/src/wolfsentry_util.c index f4c537c..2327250 100644 --- a/src/wolfsentry_util.c +++ b/src/wolfsentry_util.c @@ -232,7 +232,7 @@ WOLFSENTRY_API const char *wolfsentry_errcode_error_string(wolfsentry_errcode_t return "unknown user defined error code"; } else if (i >= WOLFSENTRY_SUCCESS_ID_USER_BASE) { if (user_defined_successes[i - WOLFSENTRY_SUCCESS_ID_USER_BASE]) - return user_defined_errors[i - WOLFSENTRY_SUCCESS_ID_USER_BASE]; + return user_defined_successes[i - WOLFSENTRY_SUCCESS_ID_USER_BASE]; else return "unknown user defined success code"; } else if (i >= 0) @@ -634,7 +634,7 @@ static void *wolfsentry_builtin_malloc( WOLFSENTRY_CONTEXT_ARGS_THREAD_NOT_USED; #ifdef WOLFSENTRY_MALLOC_DEBUG { - ret = malloc(size); + void *ret = malloc(size); if (ret != NULL) WOLFSENTRY_ATOMIC_INCREMENT(n_mallocs, 1); WOLFSENTRY_RETURN_VALUE(ret); @@ -989,9 +989,9 @@ WOLFSENTRY_API wolfsentry_errcode_t wolfsentry_get_deadline_rel(WOLFSENTRY_CONTE WOLFSENTRY_SUCCESS_RETURN(EXPIRED); } else { if (now >= deadline) - WOLFSENTRY_RETURN_OK; - else WOLFSENTRY_SUCCESS_RETURN(EXPIRED); + else + WOLFSENTRY_RETURN_OK; } } }