diff --git a/src/actions.c b/src/actions.c index d92b174..a73f3f8 100644 --- a/src/actions.c +++ b/src/actions.c @@ -240,11 +240,11 @@ WOLFSENTRY_API wolfsentry_errcode_t wolfsentry_action_get_reference(WOLFSENTRY_C label_len = (int)strlen(label); if (label_len > WOLFSENTRY_MAX_LABEL_BYTES) WOLFSENTRY_ERROR_RETURN(STRING_ARG_TOO_LONG); + WOLFSENTRY_SHARED_OR_RETURN(); if ((action_template = (struct wolfsentry_action *)WOLFSENTRY_MALLOC(sizeof *action_template + (size_t)label_len)) == NULL) - WOLFSENTRY_ERROR_RETURN(SYS_RESOURCE_FAILED); + WOLFSENTRY_ERROR_UNLOCK_AND_RETURN(SYS_RESOURCE_FAILED); action_template->label_len = (byte)label_len; memcpy(action_template->label, label, (size_t)label_len); - WOLFSENTRY_SHARED_OR_RETURN(); ret = wolfsentry_action_get_reference_1(WOLFSENTRY_CONTEXT_ARGS_OUT, action_template, action); WOLFSENTRY_FREE(action_template); WOLFSENTRY_ERROR_UNLOCK_AND_RERETURN(ret); @@ -470,7 +470,10 @@ WOLFSENTRY_LOCAL wolfsentry_errcode_t wolfsentry_action_list_clone( new_ale->action = new_action; WOLFSENTRY_REFCOUNT_INCREMENT(new_action->header.refcount, ret); - WOLFSENTRY_UNLOCK_AND_RERETURN_IF_ERROR(ret); + if (ret < 0) { + WOLFSENTRY_FREE_1(dest_context->hpi.allocator, new_ale); + goto out; + } wolfsentry_list_ent_append(&dest_action_list->header, &new_ale->header); } ret = WOLFSENTRY_ERROR_ENCODE(OK); diff --git a/src/json/centijson_sax.c b/src/json/centijson_sax.c index e65b406..1c71d53 100644 --- a/src/json/centijson_sax.c +++ b/src/json/centijson_sax.c @@ -311,7 +311,12 @@ json_buf_append(JSON_PARSER* parser, const unsigned char* data, size_t size) { if(parser->buf_used + size > parser->buf_alloced) { unsigned char* new_buf; - size_t new_alloced = (parser->buf_used + size) * 2; + size_t new_alloced; + if(parser->buf_used > SIZE_MAX / 2 || size > SIZE_MAX / 2 - parser->buf_used) { + json_raise(parser, JSON_ERR_OUTOFMEMORY); + WOLFSENTRY_RETURN_VALUE(-1); + } + new_alloced = (parser->buf_used + size) * 2; new_buf = (unsigned char *)realloc(parser->buf, new_alloced); if(new_buf == NULL) { diff --git a/src/json/load_config.c b/src/json/load_config.c index eb33d9c..4130da5 100644 --- a/src/json/load_config.c +++ b/src/json/load_config.c @@ -368,16 +368,22 @@ static wolfsentry_errcode_t convert_eventconfig_flag(JSON_TYPE type, wolfsentry_ static wolfsentry_errcode_t convert_wolfsentry_duration(struct wolfsentry_context *wolfsentry, JSON_TYPE type, const unsigned char *data, size_t data_size, wolfsentry_time_t *out) { wolfsentry_errcode_t ret; + char buf[24]; char *endptr; long conv; if ((type != JSON_STRING) && (type != JSON_NUMBER)) WOLFSENTRY_ERROR_RETURN(CONFIG_INVALID_VALUE); + if (data_size >= sizeof buf) + WOLFSENTRY_ERROR_RETURN(NUMERIC_ARG_TOO_BIG); + memcpy(buf, data, data_size); + buf[data_size] = 0; + #ifndef WOLFSENTRY_NO_ERRNO_H errno = 0; #endif - conv = strtol((const char *)data, &endptr, 0); + conv = strtol(buf, &endptr, 0); #ifndef WOLFSENTRY_NO_ERRNO_H if (errno != 0) WOLFSENTRY_ERROR_RETURN(CONFIG_INVALID_VALUE); @@ -405,7 +411,7 @@ static wolfsentry_errcode_t convert_wolfsentry_duration(struct wolfsentry_contex default: break; } - if ((size_t)(endptr - (char *)data) != data_size) + if ((size_t)(endptr - buf) != data_size) WOLFSENTRY_ERROR_RETURN(CONFIG_INVALID_VALUE); if ((ret = wolfsentry_interval_from_seconds(wolfsentry, conv, 0 /* howlong_nsecs */, out)) < 0) WOLFSENTRY_ERROR_RERETURN(ret); @@ -602,6 +608,10 @@ static inline int convert_hex_byte(const unsigned char **in, size_t *in_len, byt return d1; ++(*in); --(*in_len); + if (*in_len < 1) { + *out = (byte)d1; + return 0; + } d2 = convert_hex_digit(**in); if (d2 < 0) { *out = (byte)d1; diff --git a/src/kv.c b/src/kv.c index 1a6e9d9..ff9cbbe 100644 --- a/src/kv.c +++ b/src/kv.c @@ -536,11 +536,12 @@ WOLFSENTRY_LOCAL wolfsentry_errcode_t wolfsentry_kv_delete( struct wolfsentry_kv_pair_internal *kv_template; struct wolfsentry_kv_pair_internal *old = NULL; wolfsentry_errcode_t ret; - if ((ret = wolfsentry_kv_new(WOLFSENTRY_CONTEXT_ARGS_OUT, key, key_len, 0 /* data_len */, &kv_template)) < 0) - WOLFSENTRY_ERROR_RERETURN(ret); WOLFSENTRY_MUTEX_OR_RETURN(); + if ((ret = wolfsentry_kv_new(WOLFSENTRY_CONTEXT_ARGS_OUT, key, key_len, 0 /* data_len */, &kv_template)) < 0) + WOLFSENTRY_ERROR_UNLOCK_AND_RERETURN(ret); + ret = wolfsentry_kv_get_1(WOLFSENTRY_CONTEXT_ARGS_OUT, kv_table, kv_template, &old); WOLFSENTRY_WARN_ON_FAILURE(wolfsentry_kv_drop_reference(WOLFSENTRY_CONTEXT_ARGS_OUT, kv_template, NULL)); WOLFSENTRY_UNLOCK_AND_RERETURN_IF_ERROR(ret); diff --git a/src/routes.c b/src/routes.c index 34baa90..390f2fb 100644 --- a/src/routes.c +++ b/src/routes.c @@ -134,7 +134,7 @@ static inline int addr_prefix_match_size( for (; ret < min_len; ++ret) { int byte_number = ret / 8; int bit_number = ret % 8; - if ((a[byte_number] & (1U << bit_number)) != (b[byte_number] & (1U << bit_number))) + if ((a[byte_number] & (0x80U >> bit_number)) != (b[byte_number] & (0x80U >> bit_number))) break; } @@ -1955,6 +1955,8 @@ static wolfsentry_errcode_t wolfsentry_route_lookup_1( const size_t addr_buf_size = WOLFSENTRY_BITS_TO_BYTES(remote->addr_len) + WOLFSENTRY_BITS_TO_BYTES(local->addr_len); struct wolfsentry_route *target; + if (addr_buf_size > (size_t)WOLFSENTRY_MAX_ADDR_BYTES * 2) + WOLFSENTRY_ERROR_RETURN(NUMERIC_ARG_TOO_BIG); target = (struct wolfsentry_route *)alloca(sizeof(*target) + addr_buf_size); #define LOOKUP_TARGET target #endif @@ -2765,7 +2767,10 @@ static wolfsentry_errcode_t wolfsentry_route_event_dispatch_1( if ((rule_route->parent_event == NULL) && (route_table->default_event != NULL)) { rule_route->parent_event = route_table->default_event; WOLFSENTRY_REFCOUNT_INCREMENT(rule_route->parent_event->header.refcount, ret); - WOLFSENTRY_UNLOCK_AND_RERETURN_IF_ERROR(ret); + if (ret < 0) { + rule_route->parent_event = NULL; + goto just_free_resources; + } } } @@ -4012,24 +4017,26 @@ WOLFSENTRY_API wolfsentry_errcode_t wolfsentry_route_flag_assoc_by_name(const ch static wolfsentry_errcode_t ws_itoa(int i, unsigned char **out, size_t *spc) { int out_chars; - int digit_thresh; + unsigned int u; + unsigned int digit_thresh; int neg; if (i < 0) { neg = 1; - i = -i; + u = -(unsigned int)i; out_chars = 2; } else { neg = 0; + u = (unsigned int)i; out_chars = 1; } for (digit_thresh = 10; ; digit_thresh *= 10) { - if (i >= digit_thresh) + if (u >= digit_thresh) ++out_chars; else { digit_thresh /= 10; break; } - if (digit_thresh == 1000000000) + if (digit_thresh == 1000000000U) break; } if (*spc < (size_t)out_chars) @@ -4038,8 +4045,8 @@ static wolfsentry_errcode_t ws_itoa(int i, unsigned char **out, size_t *spc) { if (neg) *(*out)++ = '-'; while (digit_thresh >= 1) { - int quotient = i / digit_thresh; - i %= digit_thresh; + unsigned int quotient = u / digit_thresh; + u %= digit_thresh; digit_thresh /= 10; *(*out)++ = (unsigned char)('0' + quotient); } @@ -4625,7 +4632,7 @@ WOLFSENTRY_API wolfsentry_errcode_t wolfsentry_route_render(WOLFSENTRY_CONTEXT_A } } - wolfsentry_route_render_proto(r->sa_proto, r->flags, f); + WOLFSENTRY_RERETURN_IF_ERROR(wolfsentry_route_render_proto(r->sa_proto, r->flags, f)); if (r->parent_event != NULL) { if (fprintf(f, ", ev = \"%.*s\"%s", (int)r->parent_event->label_len, r->parent_event->label, WOLFSENTRY_CHECK_BITS(r->flags, WOLFSENTRY_ROUTE_FLAG_PARENT_EVENT_WILDCARD) ? "[*]" : "") < 0) @@ -4715,11 +4722,14 @@ WOLFSENTRY_API wolfsentry_errcode_t wolfsentry_route_exports_render(WOLFSENTRY_C ret = wolfsentry_addr_family_ntop(WOLFSENTRY_CONTEXT_ARGS_OUT, r->sa_family, &addr_family, &family_name); if (WOLFSENTRY_ERROR_CODE_IS(ret, OK)) { if (fprintf(f, ", AF = %s", family_name) < 0) - WOLFSENTRY_ERROR_RETURN(IO_FAILED); + ret = WOLFSENTRY_ERROR_ENCODE(IO_FAILED); if (addr_family) { - if ((ret = wolfsentry_addr_family_drop_reference(WOLFSENTRY_CONTEXT_ARGS_OUT, addr_family, NULL /* action_results */ )) < 0) - WOLFSENTRY_ERROR_RERETURN(ret); + wolfsentry_errcode_t drop_ret = wolfsentry_addr_family_drop_reference(WOLFSENTRY_CONTEXT_ARGS_OUT, addr_family, NULL /* action_results */ ); + if (drop_ret < 0) + WOLFSENTRY_ERROR_RERETURN(drop_ret); } + if (ret < 0) + WOLFSENTRY_ERROR_RERETURN(ret); } else #endif { @@ -4728,7 +4738,7 @@ WOLFSENTRY_API wolfsentry_errcode_t wolfsentry_route_exports_render(WOLFSENTRY_C } } - wolfsentry_route_render_proto(r->sa_proto, r->flags, f); + WOLFSENTRY_RERETURN_IF_ERROR(wolfsentry_route_render_proto(r->sa_proto, r->flags, f)); if (r->parent_event_label_len > 0) { if (fprintf(f, ", ev = \"%.*s\"%s", (int)r->parent_event_label_len, r->parent_event_label, WOLFSENTRY_CHECK_BITS(r->flags, WOLFSENTRY_ROUTE_FLAG_PARENT_EVENT_WILDCARD) ? "[*]" : "") < 0) diff --git a/src/wolfsentry_util.c b/src/wolfsentry_util.c index 2327250..fc590a0 100644 --- a/src/wolfsentry_util.c +++ b/src/wolfsentry_util.c @@ -666,9 +666,9 @@ static void *wolfsentry_builtin_realloc( #ifdef WOLFSENTRY_MALLOC_DEBUG { void *ret = realloc(ptr, size); - if ((ptr == null) && (ret != NULL)) + if ((ptr == NULL) && (ret != NULL)) WOLFSENTRY_ATOMIC_INCREMENT(n_mallocs, 1); - else if ((ptr != null) && (ret == NULL)) + else if ((ptr != NULL) && (ret == NULL)) WOLFSENTRY_ATOMIC_DECREMENT(n_mallocs, 1); return ret; } @@ -1775,7 +1775,6 @@ WOLFSENTRY_API wolfsentry_errcode_t wolfsentry_lock_destroy(struct wolfsentry_rw (lock->read_waiter_count != 0) || (lock->write_waiter_count != 0) || (lock->read2write_waiter_read_count != 0) || - (lock->read2write_reservation_holder != WOLFSENTRY_THREAD_NO_ID) || (lock->promoted_at_count != 0)) { WOLFSENTRY_WARN("attempt to destroy lock with corrupted state {%u,%d,%d,%d,%d,%d,%d}\n", (unsigned int)lock->state, lock->holder_count.read, lock->read_waiter_count, lock->write_waiter_count, lock->read2write_waiter_read_count, lock->read2write_reservation_holder != WOLFSENTRY_THREAD_NO_ID, lock->promoted_at_count); @@ -3618,6 +3617,8 @@ WOLFSENTRY_API wolfsentry_errcode_t wolfsentry_eventconfig_check( ((config->route_private_data_alignment & (config->route_private_data_alignment - 1)) != 0) || (config->route_private_data_alignment > config->route_private_data_size))) WOLFSENTRY_ERROR_RETURN(INVALID_ARG); + if (config->route_private_data_size > MAX_UINT_OF(((struct wolfsentry_route *)0)->data_addr_offset)) + WOLFSENTRY_ERROR_RETURN(NUMERIC_ARG_TOO_BIG); } if (config->route_private_data_alignment > 0) {