X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=src%2Futil%2Fcommon_allocation.c;h=dfa65d579dc6b74b0e566e44baff2fc5451dcaa1;hb=72c8645af31896829b674b575c5375706f362a30;hp=92cbc974773ad3154bfdca3f9af7233af335527f;hpb=86290d22b2632f1cddeb5ae5756574d7f5dcae83;p=oweals%2Fgnunet.git diff --git a/src/util/common_allocation.c b/src/util/common_allocation.c index 92cbc9747..dfa65d579 100644 --- a/src/util/common_allocation.c +++ b/src/util/common_allocation.c @@ -23,9 +23,18 @@ * @brief wrapper around malloc/free * @author Christian Grothoff */ - #include "platform.h" #include "gnunet_common.h" +#if HAVE_MALLOC_H +#include +#endif +#if HAVE_MALLOC_MALLOC_H +#include +#endif + +#define LOG(kind,...) GNUNET_log_from (kind, "util",__VA_ARGS__) + +#define LOG_STRERROR(kind,syscall) GNUNET_log_from_strerror (kind, "util", syscall) #ifndef INT_MAX #define INT_MAX 0x7FFFFFFF @@ -55,19 +64,63 @@ void * GNUNET_xmalloc_ (size_t size, const char *filename, int linenumber) { void *ret; + /* As a security precaution, we generally do not allow very large - allocations using the default 'GNUNET_malloc' macro */ + * allocations using the default 'GNUNET_malloc' macro */ GNUNET_assert_at (size <= GNUNET_MAX_MALLOC_CHECKED, filename, linenumber); ret = GNUNET_xmalloc_unchecked_ (size, filename, linenumber); if (ret == NULL) - { - GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "malloc"); - abort (); - } + { + LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "malloc"); + GNUNET_abort (); + } return ret; } +/** + * Allocate and initialize memory. Checks the return value, aborts if no more + * memory is available. Don't use GNUNET_xmemdup_ directly. Use the + * GNUNET_memdup macro. + * + * @param buf buffer to initialize from (must contain size bytes) + * @param size number of bytes to allocate + * @param filename where is this call being made (for debugging) + * @param linenumber line where this call is being made (for debugging) + * @return allocated memory, never NULL + */ +void * +GNUNET_xmemdup_ (const void *buf, size_t size, const char *filename, + int linenumber) +{ + void *ret; + + /* As a security precaution, we generally do not allow very large + * allocations here */ + GNUNET_assert_at (size <= GNUNET_MAX_MALLOC_CHECKED, filename, linenumber); +#ifdef W32_MEM_LIMIT + size += sizeof (size_t); + if (mem_used + size > W32_MEM_LIMIT) + return NULL; +#endif + GNUNET_assert_at (size < INT_MAX, filename, linenumber); + ret = malloc (size); + if (ret == NULL) + { + LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "malloc"); + GNUNET_abort (); + } +#ifdef W32_MEM_LIMIT + *((size_t *) ret) = size; + ret = &((size_t *) ret)[1]; + mem_used += size; +#endif + memcpy (ret, buf, size); + return ret; +} + + + /** * Wrapper around malloc. Allocates size bytes of memory. * The memory will be zero'ed out. @@ -88,7 +141,6 @@ GNUNET_xmalloc_unchecked_ (size_t size, const char *filename, int linenumber) return NULL; #endif - GNUNET_assert_at (size < INT_MAX, filename, linenumber); result = malloc (size); if (result == NULL) return NULL; @@ -115,9 +167,7 @@ GNUNET_xmalloc_unchecked_ (size_t size, const char *filename, int linenumber) * @return pointer to size bytes of memory */ void * -GNUNET_xrealloc_ (void *ptr, - size_t n, - const char *filename, int linenumber) +GNUNET_xrealloc_ (void *ptr, size_t n, const char *filename, int linenumber) { #ifdef W32_MEM_LIMIT n += sizeof (size_t); @@ -125,11 +175,11 @@ GNUNET_xrealloc_ (void *ptr, mem_used = mem_used - *((size_t *) ptr) + n; #endif ptr = realloc (ptr, n); - if (!ptr) - { - GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "realloc"); - abort (); - } + if ((NULL == ptr) && (n > 0)) + { + LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "realloc"); + GNUNET_abort (); + } #ifdef W32_MEM_LIMIT ptr = &((size_t *) ptr)[1]; #endif @@ -137,6 +187,22 @@ GNUNET_xrealloc_ (void *ptr, } +# if __BYTE_ORDER == __LITTLE_ENDIAN +#define BAADFOOD_STR "\x0D\xF0\xAD\xBA" +#endif +# if __BYTE_ORDER == __BIG_ENDIAN +#define BAADFOOD_STR "\xBA\xAD\xF0\x0D" +#endif + +#if WINDOWS +#define M_SIZE(p) _msize (p) +#endif +#if HAVE_MALLOC_USABLE_SIZE +#define M_SIZE(p) malloc_usable_size (p) +#elif HAVE_MALLOC_SIZE +#define M_SIZE(p) malloc_size (p) +#endif + /** * Free memory. Merely a wrapper for the case that we * want to keep track of allocations. @@ -152,6 +218,20 @@ GNUNET_xfree_ (void *ptr, const char *filename, int linenumber) #ifdef W32_MEM_LIMIT ptr = &((size_t *) ptr)[-1]; mem_used -= *((size_t *) ptr); +#endif +#if defined(M_SIZE) +#if ENABLE_POISONING + { + const uint64_t baadfood = GNUNET_ntohll (0xBAADF00DBAADF00DLL); + uint64_t *base = ptr; + size_t s = M_SIZE (ptr); + size_t i; + + for (i=0;i newCount, filename, linenumber); size = newCount * elementSize; if (size == 0) - { - tmp = NULL; - } + { + tmp = NULL; + } else - { - tmp = GNUNET_xmalloc_ (size, filename, linenumber); - memset (tmp, 0, size); /* client code should not rely on this, though... */ - if (*oldCount > newCount) - *oldCount = newCount; /* shrink is also allowed! */ - memcpy (tmp, *old, elementSize * (*oldCount)); - } + { + tmp = GNUNET_xmalloc_ (size, filename, linenumber); + memset (tmp, 0, size); /* client code should not rely on this, though... */ + if (*oldCount > newCount) + *oldCount = newCount; /* shrink is also allowed! */ + memcpy (tmp, *old, elementSize * (*oldCount)); + } if (*old != NULL) - { - GNUNET_xfree_ (*old, filename, linenumber); - } + { + GNUNET_xfree_ (*old, filename, linenumber); + } *old = tmp; *oldCount = newCount; } @@ -267,4 +387,25 @@ GNUNET_snprintf (char *buf, size_t size, const char *format, ...) return ret; } + +/** + * Create a copy of the given message. + * + * @param msg message to copy + * @return duplicate of the message + */ +struct GNUNET_MessageHeader * +GNUNET_copy_message (const struct GNUNET_MessageHeader *msg) +{ + struct GNUNET_MessageHeader *ret; + uint16_t msize; + + msize = ntohs (msg->size); + GNUNET_assert (msize >= sizeof (struct GNUNET_MessageHeader)); + ret = GNUNET_malloc (msize); + memcpy (ret, msg, msize); + return ret; +} + + /* end of common_allocation.c */