From: pcarana Date: Sat, 11 May 2019 00:41:05 +0000 (-0500) Subject: Remove TODO: don't panic when uthash can't allocate memory X-Git-Tag: v0.0.2~35^2 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=db69160da40bcf97b18085f4196e19766fcb8de1;p=thirdparty%2FFORT-validator.git Remove TODO: don't panic when uthash can't allocate memory --- diff --git a/src/Makefile.am b/src/Makefile.am index 359fa168..ccf42323 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -54,6 +54,7 @@ fort_SOURCES += crypto/hash.h crypto/hash.c fort_SOURCES += data_structure/array_list.h fort_SOURCES += data_structure/common.h fort_SOURCES += data_structure/uthash.h +fort_SOURCES += data_structure/uthash_nonfatal.h fort_SOURCES += object/certificate.h object/certificate.c fort_SOURCES += object/crl.h object/crl.c diff --git a/src/clients.c b/src/clients.c index fd5e031e..b107f4ba 100644 --- a/src/clients.c +++ b/src/clients.c @@ -3,12 +3,8 @@ #include #include "common.h" #include "log.h" -#include "data_structure/uthash.h" +#include "data_structure/uthash_nonfatal.h" -/* - * TODO uthash panics on memory allocations... - * http://troydhanson.github.io/uthash/userguide.html#_out_of_memory - */ #define SADDR_IN(addr) ((struct sockaddr_in *) addr) #define SADDR_IN6(addr) ((struct sockaddr_in6 *) addr) @@ -90,7 +86,13 @@ clients_add(int fd, struct sockaddr_storage *addr, uint8_t rtr_version) HASH_FIND_INT(table, &fd, old_client); if (old_client == NULL) { + errno = 0; HASH_ADD_INT(table, meat.fd, new_client); + if (errno) { + rwlock_unlock(&lock); + free(new_client); + return -pr_errno(errno, "Couldn't create client"); + } new_client = NULL; } else { /* diff --git a/src/data_structure/uthash_nonfatal.h b/src/data_structure/uthash_nonfatal.h new file mode 100644 index 00000000..5743dda4 --- /dev/null +++ b/src/data_structure/uthash_nonfatal.h @@ -0,0 +1,24 @@ +#ifndef SRC_DATA_STRUCTURE_UTHASH_NONFATAL_H_ +#define SRC_DATA_STRUCTURE_UTHASH_NONFATAL_H_ + +#include + +/* + * "To enable "returning a failure" if memory cannot be allocated, define the + * macro HASH_NONFATAL_OOM before including the uthash.h header file." + * (http://troydhanson.github.io/uthash/userguide.html#_out_of_memory) + * + * The errno variable will be set to ENOMEM, so that the caller can detect the + * error. + * + * This validation (check for errno) must be done on ops that allocate memory, + * so set 'errno' to 0 before this ops are made. The 'obj' won't be freed, + * this is the caller's responsibility. + */ +#define HASH_NONFATAL_OOM 1 +#define uthash_nonfatal_oom(obj) \ + errno = ENOMEM; \ + +#include "data_structure/uthash.h" + +#endif /* SRC_DATA_STRUCTURE_UTHASH_NONFATAL_H_ */ diff --git a/src/rtr/db/roa_table.c b/src/rtr/db/roa_table.c index 28f0c12e..8f444783 100644 --- a/src/rtr/db/roa_table.c +++ b/src/rtr/db/roa_table.c @@ -1,6 +1,6 @@ #include "rtr/db/roa_table.h" -#include "data_structure/uthash.h" +#include "data_structure/uthash_nonfatal.h" struct hashable_roa { /* @@ -93,7 +93,10 @@ add_roa(struct roa_table *table, struct hashable_roa *new) { struct hashable_roa *old; + errno = 0; HASH_REPLACE(hh, table->roas, data, sizeof(new->data), new, old); + if (errno) + return -pr_errno(errno, "ROA couldn't be added to hash table"); if (old != NULL) free(old); @@ -166,6 +169,7 @@ rtrhandler_handle_roa_v4(struct roa_table *table, uint32_t asn, struct ipv4_prefix const *prefix4, uint8_t max_length) { struct hashable_roa *roa; + int error; roa = create_roa(asn, max_length); if (roa == NULL) @@ -174,7 +178,10 @@ rtrhandler_handle_roa_v4(struct roa_table *table, uint32_t asn, roa->data.prefix_length = prefix4->len; roa->data.addr_fam = AF_INET; - return add_roa(table, roa); + error = add_roa(table, roa); + if (error) + free(roa); + return error; } int @@ -182,6 +189,7 @@ rtrhandler_handle_roa_v6(struct roa_table *table, uint32_t asn, struct ipv6_prefix const *prefix6, uint8_t max_length) { struct hashable_roa *roa; + int error; roa = create_roa(asn, max_length); if (roa == NULL) @@ -190,7 +198,10 @@ rtrhandler_handle_roa_v6(struct roa_table *table, uint32_t asn, roa->data.prefix_length = prefix6->len; roa->data.addr_fam = AF_INET6; - return add_roa(table, roa); + error = add_roa(table, roa); + if (error) + free(roa); + return error; } static int