[augeas-devel] [PATCH 1 of 2] Safer memory allocation from libvirt

David Lutterkort dlutter at redhat.com
Thu May 8 17:46:54 UTC 2008


# HG changeset patch
# User David Lutterkort <dlutter at redhat.com>
# Date 1210268606 25200
# Node ID 90826d5f3420a5ac5312243f8fb321ec089cc09a
# Parent  169ca23cd0b9fd3311e44943e46fb063798e0034
Safer memory allocation from libvirt

diff -r 169ca23cd0b9 -r 90826d5f3420 src/Makefile.am
--- a/src/Makefile.am	Thu May 08 10:41:53 2008 -0700
+++ b/src/Makefile.am	Thu May 08 10:43:26 2008 -0700
@@ -14,6 +14,7 @@ include_HEADERS = augeas.h fa.h
 
 libaugeas_la_SOURCES = augeas.h augeas.c config.h \
 	internal.h internal.c \
+	memory.h memory.c \
         syntax.c syntax.h parser.y builtin.c lens.c lens.h regexp.c \
 	transform.c get.c put.c list.h
 libaugeas_la_LDFLAGS = -Wl,--version-script=$(srcdir)/augeas_sym.version
@@ -25,7 +26,7 @@ augparse_SOURCES = augparse.c
 augparse_SOURCES = augparse.c
 augparse_LDADD = libaugeas.la
 
-libfa_la_SOURCES = fa.c fa.h hash.c hash.h
+libfa_la_SOURCES = fa.c fa.h hash.c hash.h memory.c memory.h
 
 liblexer_la_SOURCES = lexer.l
 liblexer_la_CFLAGS = $(AM_CFLAGS) -Wno-error
diff -r 169ca23cd0b9 -r 90826d5f3420 src/internal.h
--- a/src/internal.h	Thu May 08 10:41:53 2008 -0700
+++ b/src/internal.h	Thu May 08 10:43:26 2008 -0700
@@ -37,6 +37,10 @@
 
 #ifdef __GNUC__
 
+#ifndef __GNUC_PREREQ
+#define __GNUC_PREREQ(maj,min) 0
+#endif
+
 /**
  * ATTRIBUTE_UNUSED:
  *
@@ -60,10 +64,19 @@
 #define ATTRIBUTE_PURE __attribute__((pure))
 #endif
 
+#ifndef ATTRIBUTE_RETURN_CHECK
+#if __GNUC_PREREQ (3, 4)
+#define ATTRIBUTE_RETURN_CHECK __attribute__((__warn_unused_result__))
+#else
+#define ATTRIBUTE_RETURN_CHECK
+#endif
+#endif
+
 #else
 #define ATTRIBUTE_UNUSED
 #define ATTRIBUTE_FORMAT(...)
 #define ATTRIBUTE_PURE
+#define ATTRIBUTE_RETURN_CHECK
 #endif                                   /* __GNUC__ */
 
 /* String equality tests, suggested by Jim Meyering. */
diff -r 169ca23cd0b9 -r 90826d5f3420 src/memory.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/memory.c	Thu May 08 10:43:26 2008 -0700
@@ -0,0 +1,102 @@
+/*
+ * memory.c: safer memory allocation
+ *
+ * Copyright (C) 2008 Daniel P. Berrange
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
+ *
+ */
+
+#include <config.h>
+#include <stdlib.h>
+#include <stddef.h>
+
+#include "memory.h"
+
+
+/* Return 1 if an array of N objects, each of size S, cannot exist due
+   to size arithmetic overflow.  S must be positive and N must be
+   nonnegative.  This is a macro, not an inline function, so that it
+   works correctly even when SIZE_MAX < N.
+
+   By gnulib convention, SIZE_MAX represents overflow in size
+   calculations, so the conservative dividend to use here is
+   SIZE_MAX - 1, since SIZE_MAX might represent an overflowed value.
+   However, malloc (SIZE_MAX) fails on all known hosts where
+   sizeof (ptrdiff_t) <= sizeof (size_t), so do not bother to test for
+   exactly-SIZE_MAX allocations on such hosts; this avoids a test and
+   branch when S is known to be 1.  */
+# define xalloc_oversized(n, s) \
+    ((size_t) (sizeof (ptrdiff_t) <= sizeof (size_t) ? -1 : -2) / (s) < (n))
+
+
+/**
+ * mem_alloc_n:
+ * @ptrptr: pointer to pointer for address of allocated memory
+ * @size: number of bytes to allocate
+ * @count: number of elements to allocate
+ *
+ * Allocate an array of memory 'count' elements long,
+ * each with 'size' bytes. Return the address of the
+ * allocated memory in 'ptrptr'.  The newly allocated
+ * memory is filled with zeros.
+ *
+ * Returns -1 on failure to allocate, zero on success
+ */
+int mem_alloc_n(void *ptrptr, size_t size, size_t count)
+{
+    if (size == 0 || count == 0) {
+        *(void **)ptrptr = NULL;
+        return 0;
+    }
+
+    *(void**)ptrptr = calloc(count, size);
+    if (*(void**)ptrptr == NULL)
+        return -1;
+    return 0;
+}
+
+/**
+ * virReallocN:
+ * @ptrptr: pointer to pointer for address of allocated memory
+ * @size: number of bytes to allocate
+ * @count: number of elements in array
+ *
+ * Resize the block of memory in 'ptrptr' to be an array of
+ * 'count' elements, each 'size' bytes in length. Update 'ptrptr'
+ * with the address of the newly allocated memory. On failure,
+ * 'ptrptr' is not changed and still points to the original memory
+ * block. The newly allocated memory is filled with zeros.
+ *
+ * Returns -1 on failure to allocate, zero on success
+ */
+int mem_realloc_n(void *ptrptr, size_t size, size_t count)
+{
+    void *tmp;
+    if (size == 0 || count == 0) {
+        free(*(void **)ptrptr);
+        *(void **)ptrptr = NULL;
+        return 0;
+    }
+    if (xalloc_oversized(count, size)) {
+        errno = ENOMEM;
+        return -1;
+    }
+    tmp = realloc(*(void**)ptrptr, size * count);
+    if (!tmp)
+        return -1;
+    *(void**)ptrptr = tmp;
+    return 0;
+}
diff -r 169ca23cd0b9 -r 90826d5f3420 src/memory.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/memory.h	Thu May 08 10:43:26 2008 -0700
@@ -0,0 +1,84 @@
+/*
+ * memory.c: safer memory allocation
+ *
+ * Copyright (C) 2008 Daniel P. Berrange
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
+ *
+ */
+
+
+#ifndef MEMORY_H_
+#define MEMORY_H_
+
+#include "internal.h"
+
+/* Don't call these directly - use the macros below */
+int mem_alloc_n(void *ptrptr, size_t size, size_t count) ATTRIBUTE_RETURN_CHECK;
+int mem_realloc_n(void *ptrptr, size_t size, size_t count) ATTRIBUTE_RETURN_CHECK;
+
+
+/**
+ * ALLOC:
+ * @ptr: pointer to hold address of allocated memory
+ *
+ * Allocate sizeof(*ptr) bytes of memory and store
+ * the address of allocated memory in 'ptr'. Fill the
+ * newly allocated memory with zeros.
+ *
+ * Returns -1 on failure, 0 on success
+ */
+#define ALLOC(ptr) mem_alloc_n(&(ptr), sizeof(*(ptr)), 1)
+
+/**
+ * ALLOC_N:
+ * @ptr: pointer to hold address of allocated memory
+ * @count: number of elements to allocate
+ *
+ * Allocate an array of 'count' elements, each sizeof(*ptr)
+ * bytes long and store the address of allocated memory in
+ * 'ptr'. Fill the newly allocated memory with zeros.
+ *
+ * Returns -1 on failure, 0 on success
+ */
+#define ALLOC_N(ptr, count) mem_alloc_n(&(ptr), sizeof(*(ptr)), (count))
+
+/**
+ * REALLOC_N:
+ * @ptr: pointer to hold address of allocated memory
+ * @count: number of elements to allocate
+ *
+ * Re-allocate an array of 'count' elements, each sizeof(*ptr)
+ * bytes long and store the address of allocated memory in
+ * 'ptr'. Fill the newly allocated memory with zeros
+ *
+ * Returns -1 on failure, 0 on success
+ */
+#define REALLOC_N(ptr, count) mem_realloc_n(&(ptr), sizeof(*(ptr)), (count))
+
+/**
+ * FREE:
+ * @ptr: pointer holding address to be freed
+ *
+ * Free the memory stored in 'ptr' and update to point
+ * to NULL.
+ */
+#define FREE(ptr)                               \
+  do {                                          \
+    free(ptr);                                  \
+    (ptr) = NULL;                               \
+  } while(0)
+
+#endif /* __VIR_MEMORY_H_ */




More information about the augeas-devel mailing list