summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Grunder <michael.grunder@gmail.com>2020-01-28 12:13:05 -0800
committerGitHub <noreply@github.com>2020-01-28 12:13:05 -0800
commit669ac9d0c843f9ccf07d4969ff6bff75fafee01f (patch)
tree6075cb357e13342f6844dc9891d6c3c38c8e6f86
parent0501c623c91344e54cb2775a91509650960789b1 (diff)
Safe allocation wrappers (#754)
Create allocation wrappers with a configurable OOM handler (defaults to abort()). See #752, #747
-rw-r--r--CMakeLists.txt3
-rw-r--r--Makefile19
-rw-r--r--adapters/ae.h2
-rw-r--r--adapters/ivykis.h2
-rw-r--r--adapters/libev.h2
-rw-r--r--adapters/libevent.h2
-rw-r--r--alloc.c65
-rw-r--r--alloc.h44
-rw-r--r--async.c5
-rw-r--r--dict.c7
-rw-r--r--hiredis.h1
-rw-r--r--net.c14
-rw-r--r--ssl.c2
13 files changed, 141 insertions, 27 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index fcd8d4b..770e1a1 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -30,7 +30,8 @@ ADD_LIBRARY(hiredis SHARED
net.c
read.c
sds.c
- sockcompat.c)
+ sockcompat.c
+ alloc.c)
SET_TARGET_PROPERTIES(hiredis
PROPERTIES
diff --git a/Makefile b/Makefile
index 25ac154..10a823c 100644
--- a/Makefile
+++ b/Makefile
@@ -3,7 +3,7 @@
# Copyright (C) 2010-2011 Pieter Noordhuis <pcnoordhuis at gmail dot com>
# This file is released under the BSD license, see the COPYING file
-OBJ=net.o hiredis.o sds.o async.o read.o sockcompat.o
+OBJ=net.o hiredis.o sds.o async.o read.o sockcompat.o alloc.o
SSL_OBJ=ssl.o
EXAMPLES=hiredis-example hiredis-example-libevent hiredis-example-libev hiredis-example-glib
ifeq ($(USE_SSL),1)
@@ -95,15 +95,16 @@ all: $(SSL_DYLIBNAME) $(SSL_STLIBNAME) $(SSL_PKGCONFNAME)
endif
# Deps (use make dep to generate this)
-async.o: async.c fmacros.h async.h hiredis.h read.h sds.h net.h dict.c dict.h
-dict.o: dict.c fmacros.h dict.h
-hiredis.o: hiredis.c fmacros.h hiredis.h read.h sds.h net.h win32.h
-net.o: net.c fmacros.h net.h hiredis.h read.h sds.h sockcompat.h win32.h
-read.o: read.c fmacros.h read.h sds.h
-sds.o: sds.c sds.h
+async.o: async.c fmacros.h alloc.h async.h hiredis.h read.h sds.h net.h dict.c dict.h win32.h async_private.h
+dict.o: dict.c fmacros.h alloc.h dict.h
+hiredis.o: hiredis.c fmacros.h hiredis.h read.h sds.h alloc.h net.h async.h win32.h
+alloc.o: alloc.c alloc.h
+net.o: net.c fmacros.h net.h hiredis.h read.h sds.h alloc.h sockcompat.h win32.h
+read.o: read.c fmacros.h read.h sds.h win32.h
+sds.o: sds.c sds.h sdsalloc.h
sockcompat.o: sockcompat.c sockcompat.h
-ssl.o: ssl.c hiredis.h
-test.o: test.c fmacros.h hiredis.h read.h sds.h
+ssl.o: ssl.c hiredis.h read.h sds.h alloc.h async.h async_private.h
+test.o: test.c fmacros.h hiredis.h read.h sds.h alloc.h net.h
$(DYLIBNAME): $(OBJ)
$(DYLIB_MAKE_CMD) -o $(DYLIBNAME) $(OBJ) $(REAL_LDFLAGS)
diff --git a/adapters/ae.h b/adapters/ae.h
index 5c551c2..0393992 100644
--- a/adapters/ae.h
+++ b/adapters/ae.h
@@ -108,7 +108,7 @@ static int redisAeAttach(aeEventLoop *loop, redisAsyncContext *ac) {
return REDIS_ERR;
/* Create container for context and r/w events */
- e = (redisAeEvents*)malloc(sizeof(*e));
+ e = (redisAeEvents*)hi_malloc(sizeof(*e));
e->context = ac;
e->loop = loop;
e->fd = c->fd;
diff --git a/adapters/ivykis.h b/adapters/ivykis.h
index 6a12a86..75616ee 100644
--- a/adapters/ivykis.h
+++ b/adapters/ivykis.h
@@ -55,7 +55,7 @@ static int redisIvykisAttach(redisAsyncContext *ac) {
return REDIS_ERR;
/* Create container for context and r/w events */
- e = (redisIvykisEvents*)malloc(sizeof(*e));
+ e = (redisIvykisEvents*)hi_malloc(sizeof(*e));
e->context = ac;
/* Register functions to start/stop listening for events */
diff --git a/adapters/libev.h b/adapters/libev.h
index 2bf8d52..abad436 100644
--- a/adapters/libev.h
+++ b/adapters/libev.h
@@ -119,7 +119,7 @@ static int redisLibevAttach(EV_P_ redisAsyncContext *ac) {
return REDIS_ERR;
/* Create container for context and r/w events */
- e = (redisLibevEvents*)malloc(sizeof(*e));
+ e = (redisLibevEvents*)hi_malloc(sizeof(*e));
e->context = ac;
#if EV_MULTIPLICITY
e->loop = loop;
diff --git a/adapters/libevent.h b/adapters/libevent.h
index a495277..0674ca6 100644
--- a/adapters/libevent.h
+++ b/adapters/libevent.h
@@ -152,7 +152,7 @@ static int redisLibeventAttach(redisAsyncContext *ac, struct event_base *base) {
return REDIS_ERR;
/* Create container for context and r/w events */
- e = (redisLibeventEvents*)calloc(1, sizeof(*e));
+ e = (redisLibeventEvents*)hi_calloc(1, sizeof(*e));
e->context = ac;
/* Register functions to start/stop listening for events */
diff --git a/alloc.c b/alloc.c
new file mode 100644
index 0000000..55c3020
--- /dev/null
+++ b/alloc.c
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2020, Michael Grunder <michael dot grunder at gmail dot com>
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Redis nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "fmacros.h"
+#include "alloc.h"
+#include <string.h>
+
+void *hi_malloc(size_t size) {
+ void *ptr = malloc(size);
+ if (ptr == NULL)
+ HIREDIS_OOM_HANDLER;
+
+ return ptr;
+}
+
+void *hi_calloc(size_t nmemb, size_t size) {
+ void *ptr = calloc(nmemb, size);
+ if (ptr == NULL)
+ HIREDIS_OOM_HANDLER;
+
+ return ptr;
+}
+
+void *hi_realloc(void *ptr, size_t size) {
+ void *newptr = realloc(ptr, size);
+ if (newptr == NULL)
+ HIREDIS_OOM_HANDLER;
+
+ return newptr;
+}
+
+char *hi_strdup(const char *str) {
+ char *newstr = strdup(str);
+ if (newstr == NULL)
+ HIREDIS_OOM_HANDLER;
+
+ return newstr;
+}
diff --git a/alloc.h b/alloc.h
new file mode 100644
index 0000000..803129c
--- /dev/null
+++ b/alloc.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2020, Michael Grunder <michael dot grunder at gmail dot com>
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Redis nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef HIREDIS_ALLOC_H
+
+#include <stdlib.h> /* for size_t */
+
+#ifndef HIREDIS_OOM_HANDLER
+#define HIREDIS_OOM_HANDLER abort()
+#endif
+
+void *hi_malloc(size_t size);
+void *hi_calloc(size_t nmemb, size_t size);
+void *hi_realloc(void *ptr, size_t size);
+char *hi_strdup(const char *str);
+
+#endif /* HIREDIS_ALLOC_H */
diff --git a/async.c b/async.c
index 4f422d5..a966ed5 100644
--- a/async.c
+++ b/async.c
@@ -30,6 +30,7 @@
*/
#include "fmacros.h"
+#include "alloc.h"
#include <stdlib.h>
#include <string.h>
#ifndef _MSC_VER
@@ -57,7 +58,7 @@ static unsigned int callbackHash(const void *key) {
static void *callbackValDup(void *privdata, const void *src) {
((void) privdata);
- redisCallback *dup = malloc(sizeof(*dup));
+ redisCallback *dup = hi_malloc(sizeof(*dup));
memcpy(dup,src,sizeof(*dup));
return dup;
}
@@ -754,7 +755,7 @@ int redisAsyncFormattedCommand(redisAsyncContext *ac, redisCallbackFn *fn, void
void redisAsyncSetTimeout(redisAsyncContext *ac, struct timeval tv) {
if (!ac->c.timeout) {
- ac->c.timeout = calloc(1, sizeof(tv));
+ ac->c.timeout = hi_calloc(1, sizeof(tv));
}
if (tv.tv_sec == ac->c.timeout->tv_sec &&
diff --git a/dict.c b/dict.c
index 5b349f0..eaf4e4d 100644
--- a/dict.c
+++ b/dict.c
@@ -34,6 +34,7 @@
*/
#include "fmacros.h"
+#include "alloc.h"
#include <stdlib.h>
#include <assert.h>
#include <limits.h>
@@ -71,7 +72,7 @@ static void _dictReset(dict *ht) {
/* Create a new hash table */
static dict *dictCreate(dictType *type, void *privDataPtr) {
- dict *ht = malloc(sizeof(*ht));
+ dict *ht = hi_malloc(sizeof(*ht));
_dictInit(ht,type,privDataPtr);
return ht;
}
@@ -142,7 +143,7 @@ static int dictAdd(dict *ht, void *key, void *val) {
return DICT_ERR;
/* Allocates the memory and stores key */
- entry = malloc(sizeof(*entry));
+ entry = hi_malloc(sizeof(*entry));
entry->next = ht->table[index];
ht->table[index] = entry;
@@ -256,7 +257,7 @@ static dictEntry *dictFind(dict *ht, const void *key) {
}
static dictIterator *dictGetIterator(dict *ht) {
- dictIterator *iter = malloc(sizeof(*iter));
+ dictIterator *iter = hi_malloc(sizeof(*iter));
iter->ht = ht;
iter->index = -1;
diff --git a/hiredis.h b/hiredis.h
index bdc6670..9921e61 100644
--- a/hiredis.h
+++ b/hiredis.h
@@ -42,6 +42,7 @@ struct timeval; /* forward declaration */
#endif
#include <stdint.h> /* uintXX_t, etc */
#include "sds.h" /* for sds */
+#include "alloc.h" /* for allocation wrappers */
#define HIREDIS_MAJOR 0
#define HIREDIS_MINOR 14
diff --git a/net.c b/net.c
index e5f40b0..c928b33 100644
--- a/net.c
+++ b/net.c
@@ -358,13 +358,13 @@ static int _redisContextConnectTcp(redisContext *c, const char *addr, int port,
if (c->tcp.host != addr) {
free(c->tcp.host);
- c->tcp.host = strdup(addr);
+ c->tcp.host = hi_strdup(addr);
}
if (timeout) {
if (c->timeout != timeout) {
if (c->timeout == NULL)
- c->timeout = malloc(sizeof(struct timeval));
+ c->timeout = hi_malloc(sizeof(struct timeval));
memcpy(c->timeout, timeout, sizeof(struct timeval));
}
@@ -383,7 +383,7 @@ static int _redisContextConnectTcp(redisContext *c, const char *addr, int port,
c->tcp.source_addr = NULL;
} else if (c->tcp.source_addr != source_addr) {
free(c->tcp.source_addr);
- c->tcp.source_addr = strdup(source_addr);
+ c->tcp.source_addr = hi_strdup(source_addr);
}
snprintf(_port, 6, "%d", port);
@@ -447,7 +447,7 @@ addrretry:
/* For repeat connection */
free(c->saddr);
- c->saddr = malloc(p->ai_addrlen);
+ c->saddr = hi_malloc(p->ai_addrlen);
memcpy(c->saddr, p->ai_addr, p->ai_addrlen);
c->addrlen = p->ai_addrlen;
@@ -526,12 +526,12 @@ int redisContextConnectUnix(redisContext *c, const char *path, const struct time
c->connection_type = REDIS_CONN_UNIX;
if (c->unix_sock.path != path)
- c->unix_sock.path = strdup(path);
+ c->unix_sock.path = hi_strdup(path);
if (timeout) {
if (c->timeout != timeout) {
if (c->timeout == NULL)
- c->timeout = malloc(sizeof(struct timeval));
+ c->timeout = hi_malloc(sizeof(struct timeval));
memcpy(c->timeout, timeout, sizeof(struct timeval));
}
@@ -543,7 +543,7 @@ int redisContextConnectUnix(redisContext *c, const char *path, const struct time
if (redisContextTimeoutMsec(c,&timeout_msec) != REDIS_OK)
return REDIS_ERR;
- sa = (struct sockaddr_un*)(c->saddr = malloc(sizeof(struct sockaddr_un)));
+ sa = (struct sockaddr_un*)(c->saddr = hi_malloc(sizeof(struct sockaddr_un)));
c->addrlen = sizeof(struct sockaddr_un);
sa->sun_family = AF_UNIX;
strncpy(sa->sun_path, path, sizeof(sa->sun_path) - 1);
diff --git a/ssl.c b/ssl.c
index b97fc1d..e1e4aba 100644
--- a/ssl.c
+++ b/ssl.c
@@ -151,7 +151,7 @@ static void initOpensslLocks(void) {
return;
}
nlocks = CRYPTO_num_locks();
- ossl_locks = malloc(sizeof(*ossl_locks) * nlocks);
+ ossl_locks = hi_malloc(sizeof(*ossl_locks) * nlocks);
for (ii = 0; ii < nlocks; ii++) {
sslLockInit(ossl_locks + ii);
}