Skip to content

Commit

Permalink
Safe allocation wrappers (#754)
Browse files Browse the repository at this point in the history
Create allocation wrappers with a configurable OOM handler (defaults to abort()).

See #752, #747
  • Loading branch information
michael-grunder committed Mar 13, 2020
1 parent 6850306 commit a153788
Show file tree
Hide file tree
Showing 11 changed files with 143 additions and 21 deletions.
17 changes: 9 additions & 8 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -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
OBJ=net.o hiredis.o sds.o async.o read.o alloc.o
EXAMPLES=hiredis-example hiredis-example-libevent hiredis-example-libev hiredis-example-glib
TESTS=hiredis-test
LIBNAME=libhiredis
Expand Down Expand Up @@ -68,13 +68,14 @@ endif
all: $(DYLIBNAME) $(STLIBNAME) hiredis-test $(PKGCONFNAME)

# 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
net.o: net.c fmacros.h net.h hiredis.h read.h sds.h
alloc.o: alloc.c fmacros.h alloc.h
async.o: async.c fmacros.h alloc.h async.h hiredis.h read.h sds.h net.h dict.c dict.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
net.o: net.c fmacros.h net.h hiredis.h read.h sds.h alloc.h
read.o: read.c fmacros.h read.h sds.h
sds.o: sds.c sds.h
test.o: test.c fmacros.h hiredis.h read.h sds.h
sds.o: sds.c sds.h sdsalloc.h
test.o: test.c fmacros.h hiredis.h read.h sds.h alloc.h net.h

$(DYLIBNAME): $(OBJ)
$(DYLIB_MAKE_CMD) $(OBJ)
Expand Down Expand Up @@ -177,7 +178,7 @@ $(PKGCONFNAME): hiredis.h

install: $(DYLIBNAME) $(STLIBNAME) $(PKGCONFNAME)
mkdir -p $(INSTALL_INCLUDE_PATH) $(INSTALL_INCLUDE_PATH)/adapters $(INSTALL_LIBRARY_PATH)
$(INSTALL) hiredis.h async.h read.h sds.h $(INSTALL_INCLUDE_PATH)
$(INSTALL) hiredis.h async.h read.h sds.h alloc.h $(INSTALL_INCLUDE_PATH)
$(INSTALL) adapters/*.h $(INSTALL_INCLUDE_PATH)/adapters
$(INSTALL) $(DYLIBNAME) $(INSTALL_LIBRARY_PATH)/$(DYLIB_MINOR_NAME)
cd $(INSTALL_LIBRARY_PATH) && ln -sf $(DYLIB_MINOR_NAME) $(DYLIBNAME)
Expand Down
2 changes: 1 addition & 1 deletion adapters/ae.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
2 changes: 1 addition & 1 deletion adapters/ivykis.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand Down
2 changes: 1 addition & 1 deletion adapters/libev.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
2 changes: 1 addition & 1 deletion adapters/libevent.h
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ static int redisLibeventAttach(redisAsyncContext *ac, struct event_base *base) {
return REDIS_ERR;

/* Create container for context and r/w events */
e = (redisLibeventEvents*)malloc(sizeof(*e));
e = (redisLibeventEvents*)hi_calloc(1, sizeof(*e));
e->context = ac;

/* Register functions to start/stop listening for events */
Expand Down
65 changes: 65 additions & 0 deletions alloc.c
Original file line number Diff line number Diff line change
@@ -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;
}
53 changes: 53 additions & 0 deletions alloc.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
/*
* 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
#define HIREDIS_ALLOC_H

#include <stdlib.h> /* for size_t */

#ifndef HIREDIS_OOM_HANDLER
#define HIREDIS_OOM_HANDLER abort()
#endif

#ifdef __cplusplus
extern "C" {
#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);

#ifdef __cplusplus
}
#endif

#endif /* HIREDIS_ALLOC_H */
3 changes: 2 additions & 1 deletion async.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
*/

#include "fmacros.h"
#include "alloc.h"
#include <stdlib.h>
#include <string.h>
#include <strings.h>
Expand Down Expand Up @@ -68,7 +69,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;
}
Expand Down
7 changes: 4 additions & 3 deletions dict.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
*/

#include "fmacros.h"
#include "alloc.h"
#include <stdlib.h>
#include <assert.h>
#include <limits.h>
Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -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;
Expand Down
1 change: 1 addition & 0 deletions hiredis.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
#include <sys/time.h> /* for struct timeval */
#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
Expand Down
10 changes: 5 additions & 5 deletions net.c
Original file line number Diff line number Diff line change
Expand Up @@ -287,13 +287,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));
}
Expand All @@ -312,7 +312,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);
Expand Down Expand Up @@ -440,12 +440,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));
}
Expand Down

0 comments on commit a153788

Please sign in to comment.