Check the endianness earlier in unw_create_addr_space() on all
architectures to avoid leaking the dynamically allocated address space
struct.
This was already fixed for ARM in commit cf6a99879604 ("Fix memory leak
in ARM unw_create_addr_space()"). Move the endianness check also on ARM
to avoid malloc() & free() in the error case.
---
src/arm/Gcreate_addr_space.c | 20 +++++++++-----------
src/hppa/Gcreate_addr_space.c | 14 ++++++++------
src/mips/Gcreate_addr_space.c | 17 +++++++++--------
src/ppc/Gcreate_addr_space.c | 14 ++++++++------
src/x86/Gcreate_addr_space.c | 14 ++++++++------
src/x86_64/Gcreate_addr_space.c | 15 +++++++++------
6 files changed, 51 insertions(+), 43 deletions(-)
diff --git a/src/arm/Gcreate_addr_space.c b/src/arm/Gcreate_addr_space.c
index 5374649..4d59a20 100644
--- a/src/arm/Gcreate_addr_space.c
+++ b/src/arm/Gcreate_addr_space.c
@@ -32,8 +32,16 @@ unw_create_addr_space (unw_accessors_t *a, int byte_order)
#ifdef UNW_LOCAL_ONLY
return NULL;
#else
- unw_addr_space_t as = malloc (sizeof (*as));
+ unw_addr_space_t as;
+ /*
+ * ARM supports little-endian and big-endian.
+ */
+ if (byte_order != 0 && byte_order != __LITTLE_ENDIAN
+ && byte_order != __BIG_ENDIAN)
+ return NULL;
+
+ as = malloc (sizeof (*as));
if (!as)
return NULL;
@@ -41,16 +49,6 @@ unw_create_addr_space (unw_accessors_t *a, int byte_order)
as->acc = *a;
- /*
- * ARM supports little-endian and big-endian.
- */
- if (byte_order != 0 && byte_order != __LITTLE_ENDIAN
- && byte_order != __BIG_ENDIAN)
- {
- free(as);
- return NULL;
- }
-
/* Default to little-endian for ARM. */
if (byte_order == 0 || byte_order == __LITTLE_ENDIAN)
as->big_endian = 0;
diff --git a/src/hppa/Gcreate_addr_space.c b/src/hppa/Gcreate_addr_space.c
index 8f4301f..ecc805d 100644
--- a/src/hppa/Gcreate_addr_space.c
+++ b/src/hppa/Gcreate_addr_space.c
@@ -33,8 +33,15 @@ unw_create_addr_space (unw_accessors_t *a, int byte_order)
#ifdef UNW_LOCAL_ONLY
return NULL;
#else
- unw_addr_space_t as = malloc (sizeof (*as));
+ unw_addr_space_t as;
+ /*
+ * hppa supports only big-endian.
+ */
+ if (byte_order != 0 && byte_order != __BIG_ENDIAN)
+ return NULL;
+
+ as = malloc (sizeof (*as));
if (!as)
return NULL;
@@ -42,11 +49,6 @@ unw_create_addr_space (unw_accessors_t *a, int byte_order)
as->acc = *a;
- /*
- * hppa supports only big-endian.
- */
- if (byte_order != 0 && byte_order != __BIG_ENDIAN)
- return NULL;
return as;
#endif
}
diff --git a/src/mips/Gcreate_addr_space.c b/src/mips/Gcreate_addr_space.c
index af084ef..371841d 100644
--- a/src/mips/Gcreate_addr_space.c
+++ b/src/mips/Gcreate_addr_space.c
@@ -32,14 +32,7 @@ unw_create_addr_space (unw_accessors_t *a, int byte_order)
#ifdef UNW_LOCAL_ONLY
return NULL;
#else
- unw_addr_space_t as = malloc (sizeof (*as));
-
- if (!as)
- return NULL;
-
- memset (as, 0, sizeof (*as));
-
- as->acc = *a;
+ unw_addr_space_t as;
/*
* MIPS supports only big or little-endian, not weird stuff like
@@ -50,6 +43,14 @@ unw_create_addr_space (unw_accessors_t *a, int byte_order)
&& byte_order != __BIG_ENDIAN)
return NULL;
+ as = malloc (sizeof (*as));
+ if (!as)
+ return NULL;
+
+ memset (as, 0, sizeof (*as));
+
+ as->acc = *a;
+
if (byte_order == 0)
/* use host default: */
as->big_endian = (__BYTE_ORDER == __BIG_ENDIAN);
diff --git a/src/ppc/Gcreate_addr_space.c b/src/ppc/Gcreate_addr_space.c
index 21ec10f..09bde56 100644
--- a/src/ppc/Gcreate_addr_space.c
+++ b/src/ppc/Gcreate_addr_space.c
@@ -35,8 +35,15 @@ unw_create_addr_space (unw_accessors_t *a, int byte_order)
#ifdef UNW_LOCAL_ONLY
return NULL;
#else
- unw_addr_space_t as = malloc (sizeof (*as));
+ unw_addr_space_t as;
+ /*
+ * Linux ppc64 supports only big-endian.
+ */
+ if (byte_order != 0 && byte_order != __BIG_ENDIAN)
+ return NULL;
+
+ as = malloc (sizeof (*as));
if (!as)
return NULL;
@@ -44,11 +51,6 @@ unw_create_addr_space (unw_accessors_t *a, int byte_order)
as->acc = *a;
- /*
- * Linux ppc64 supports only big-endian.
- */
- if (byte_order != 0 && byte_order != __BIG_ENDIAN)
- return NULL;
return as;
#endif
}
diff --git a/src/x86/Gcreate_addr_space.c b/src/x86/Gcreate_addr_space.c
index 5dd6367..5b07940 100644
--- a/src/x86/Gcreate_addr_space.c
+++ b/src/x86/Gcreate_addr_space.c
@@ -37,8 +37,15 @@ unw_create_addr_space (unw_accessors_t *a, int byte_order)
#ifdef UNW_LOCAL_ONLY
return NULL;
#else
- unw_addr_space_t as = malloc (sizeof (*as));
+ unw_addr_space_t as;
+ /*
+ * x86 supports only little-endian.
+ */
+ if (byte_order != 0 && byte_order != __LITTLE_ENDIAN)
+ return NULL;
+
+ as = malloc (sizeof (*as));
if (!as)
return NULL;
@@ -46,11 +53,6 @@ unw_create_addr_space (unw_accessors_t *a, int byte_order)
as->acc = *a;
- /*
- * x86 supports only little-endian.
- */
- if (byte_order != 0 && byte_order != __LITTLE_ENDIAN)
- return NULL;
return as;
#endif
}
diff --git a/src/x86_64/Gcreate_addr_space.c b/src/x86_64/Gcreate_addr_space.c
index 02b93eb..aab126a 100644
--- a/src/x86_64/Gcreate_addr_space.c
+++ b/src/x86_64/Gcreate_addr_space.c
@@ -3,6 +3,7 @@
Contributed by David Mosberger-Tang <[email protected]>
Modified for x86_64 by Max Asbock <[email protected]>
+ Copyright (C) 2012 Tommi Rantala <[email protected]>
This file is part of libunwind.
@@ -39,8 +40,15 @@ unw_create_addr_space (unw_accessors_t *a, int byte_order)
#ifdef UNW_LOCAL_ONLY
return NULL;
#else
- unw_addr_space_t as = malloc (sizeof (*as));
+ unw_addr_space_t as;
+ /*
+ * x86_64 supports only little-endian.
+ */
+ if (byte_order != 0 && byte_order != __LITTLE_ENDIAN)
+ return NULL;
+
+ as = malloc (sizeof (*as));
if (!as)
return NULL;
@@ -48,11 +56,6 @@ unw_create_addr_space (unw_accessors_t *a, int byte_order)
as->acc = *a;
- /*
- * x86_64 supports only little-endian.
- */
- if (byte_order != 0 && byte_order != __LITTLE_ENDIAN)
- return NULL;
return as;
#endif
}
--
1.7.9.5
_______________________________________________
Libunwind-devel mailing list
[email protected]
https://lists.nongnu.org/mailman/listinfo/libunwind-devel