summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Haller <thaller@redhat.com>2018-09-05 08:02:35 +0200
committerThomas Haller <thaller@redhat.com>2018-09-07 11:24:17 +0200
commit1fb8fbbc9967bce6bdda707d87b694c1f18aa860 (patch)
treea5d497423daf7db8363c5622454175c2f0ed6429
parent98f28ddf2e9cbf04f2af99a9059c52f6d56eaa99 (diff)
downloadNetworkManager-1fb8fbbc9967bce6bdda707d87b694c1f18aa860.tar.gz
shared: add nm_memdup() as replacement for g_memdup()
I think g_memdup() is dangerous for integer overflow. There is no need for accepting this danger, just use our own nm_memdup() which does not have this flaw.
-rw-r--r--shared/nm-utils/nm-shared-utils.h31
1 files changed, 31 insertions, 0 deletions
diff --git a/shared/nm-utils/nm-shared-utils.h b/shared/nm-utils/nm-shared-utils.h
index 171544feab..ce5fd9986e 100644
--- a/shared/nm-utils/nm-shared-utils.h
+++ b/shared/nm-utils/nm-shared-utils.h
@@ -190,6 +190,37 @@ nm_ip_addr_set (int addr_family, gpointer dst, const NMIPAddr *src)
/*****************************************************************************/
+/* like g_memdup(). The difference is that the @size argument is of type
+ * gsize, while g_memdup() has type guint. Since, the size of container types
+ * like GArray is guint as well, this means trying to g_memdup() an
+ * array,
+ * g_memdup (array->data, array->len * sizeof (ElementType))
+ * will lead to integer overflow, if there are more than G_MAXUINT/sizeof(ElementType)
+ * bytes. That seems unnecessarily dangerous to me.
+ * nm_memdup() avoids that, because its size argument is always large enough
+ * to contain all data that a GArray can hold.
+ *
+ * Another minor difference to g_memdup() is that the glib version also
+ * returns %NULL if @data is %NULL. E.g. g_memdup(NULL, 1)
+ * gives %NULL, but nm_memdup(NULL, 1) crashes. I think that
+ * is desirable, because @size MUST be correct at all times. @size
+ * may be zero, but one must not claim to have non-zero bytes when
+ * passing a %NULL @data pointer.
+ */
+static inline gpointer
+nm_memdup (gconstpointer data, gsize size)
+{
+ gpointer p;
+
+ if (size == 0)
+ return NULL;
+ p = g_malloc (size);
+ memcpy (p, data, size);
+ return p;
+}
+
+/*****************************************************************************/
+
extern const void *const _NM_PTRARRAY_EMPTY[1];
#define NM_PTRARRAY_EMPTY(type) ((type const*) _NM_PTRARRAY_EMPTY)