]> git.ipfire.org Git - thirdparty/FORT-validator.git/commitdiff
Remove TODO: don't panic when uthash can't allocate memory
authorpcarana <pc.moreno2099@gmail.com>
Sat, 11 May 2019 00:41:05 +0000 (19:41 -0500)
committerpcarana <pc.moreno2099@gmail.com>
Sat, 11 May 2019 00:41:05 +0000 (19:41 -0500)
src/Makefile.am
src/clients.c
src/data_structure/uthash_nonfatal.h [new file with mode: 0644]
src/rtr/db/roa_table.c

index 359fa168f4151fb56a6e006294384e01cb18ac87..ccf42323b87fd81c5ef430f60c46bc6c7b5129ba 100644 (file)
@@ -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
index fd5e031ec99f74dbf1e401bdae1cf5e56cf21b25..b107f4ba893d2395201d5d50cb825dc52ccb2009 100644 (file)
@@ -3,12 +3,8 @@
 #include <pthread.h>
 #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 (file)
index 0000000..5743dda
--- /dev/null
@@ -0,0 +1,24 @@
+#ifndef SRC_DATA_STRUCTURE_UTHASH_NONFATAL_H_
+#define SRC_DATA_STRUCTURE_UTHASH_NONFATAL_H_
+
+#include <errno.h>
+
+/*
+ * "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_ */
index 28f0c12e2cd4816d23d0816d24bd8a397e3b6072..8f444783751cdb130c9887688bf7eb23d11b0e59 100644 (file)
@@ -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