aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWilco Dijkstra <wilco.dijkstra@arm.com>2022-06-10 17:13:29 +0100
committerWilco Dijkstra <wdijkstr@arm.com>2022-06-10 17:13:29 +0100
commitfdaf78656fb6cc7caeb7b4e37068e8a8bf4dc639 (patch)
tree05302f7351e2b505af1d50d165bbbe371123d15d
parentf107b7b30d815f191181617e2c14f21e6af4ddcf (diff)
downloadglibc-fdaf78656fb6cc7caeb7b4e37068e8a8bf4dc639.tar
glibc-fdaf78656fb6cc7caeb7b4e37068e8a8bf4dc639.tar.gz
glibc-fdaf78656fb6cc7caeb7b4e37068e8a8bf4dc639.tar.bz2
glibc-fdaf78656fb6cc7caeb7b4e37068e8a8bf4dc639.zip
Add bounds check to __libc_ifunc_impl_list
Add a proper bounds check to __libc_ifunc_impl_list. This makes MAX_IFUNC redundant and fixes several targets that will write outside the array. To avoid unnecessary large diffs, pass the maximum in the argument 'i' to IFUNC_IMPL_ADD - 'max' can be used in new ifunc definitions and existing ones can be updated if desired. Passes buildmanyglibc. Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
-rw-r--r--include/ifunc-impl-list.h8
-rw-r--r--sysdeps/aarch64/multiarch/ifunc-impl-list.c9
-rw-r--r--sysdeps/arm/armv7/multiarch/ifunc-impl-list.c4
-rw-r--r--sysdeps/i386/i686/multiarch/ifunc-impl-list.c9
-rw-r--r--sysdeps/powerpc/powerpc32/power4/multiarch/ifunc-impl-list.c9
-rw-r--r--sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c9
-rw-r--r--sysdeps/s390/multiarch/ifunc-impl-list.c9
-rw-r--r--sysdeps/sparc/sparc64/multiarch/ifunc-impl-list.c4
-rw-r--r--sysdeps/x86_64/multiarch/ifunc-impl-list.c9
9 files changed, 20 insertions, 50 deletions
diff --git a/include/ifunc-impl-list.h b/include/ifunc-impl-list.h
index 78087f015c..00bf48f3f1 100644
--- a/include/ifunc-impl-list.h
+++ b/include/ifunc-impl-list.h
@@ -34,15 +34,15 @@ struct libc_ifunc_impl
/* Add an IFUNC implementation, IMPL, for function FUNC, to ARRAY with
USABLE at index I and advance I by one. */
-#define IFUNC_IMPL_ADD(array, i, func, usable, impl) \
+#define IFUNC_IMPL_ADD(array, max, func, usable, impl) \
extern __typeof (func) impl attribute_hidden; \
- (array)[i++] = (struct libc_ifunc_impl) { #impl, (void (*) (void)) impl, (usable) };
+ if (n < max) (array)[n++] = (struct libc_ifunc_impl) { #impl, (void (*) (void)) impl, (usable) };
/* Return the number of IFUNC implementations, N, for function FUNC if
string NAME matches FUNC. */
-#define IFUNC_IMPL(n, name, func, ...) \
+#define IFUNC_IMPL(max, name, func, ...) \
if (strcmp (name, #func) == 0) \
- { \
+ { size_t n = 0;\
__VA_ARGS__; \
return n; \
}
diff --git a/sysdeps/aarch64/multiarch/ifunc-impl-list.c b/sysdeps/aarch64/multiarch/ifunc-impl-list.c
index f6c6d008da..4144615ab2 100644
--- a/sysdeps/aarch64/multiarch/ifunc-impl-list.c
+++ b/sysdeps/aarch64/multiarch/ifunc-impl-list.c
@@ -24,16 +24,11 @@
#include <init-arch.h>
#include <stdio.h>
-/* Maximum number of IFUNC implementations. */
-#define MAX_IFUNC 8
-
size_t
__libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
size_t max)
{
- assert (max >= MAX_IFUNC);
-
- size_t i = 0;
+ size_t i = max;
INIT_ARCH ();
@@ -76,5 +71,5 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
IFUNC_IMPL_ADD (array, i, strlen, !mte, __strlen_asimd)
IFUNC_IMPL_ADD (array, i, strlen, 1, __strlen_mte))
- return i;
+ return 0;
}
diff --git a/sysdeps/arm/armv7/multiarch/ifunc-impl-list.c b/sysdeps/arm/armv7/multiarch/ifunc-impl-list.c
index af9f749045..e92bcb27a2 100644
--- a/sysdeps/arm/armv7/multiarch/ifunc-impl-list.c
+++ b/sysdeps/arm/armv7/multiarch/ifunc-impl-list.c
@@ -29,7 +29,7 @@ size_t
__libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
size_t max)
{
- size_t i = 0;
+ size_t i = max;
bool use_neon = true;
#ifdef __ARM_NEON__
@@ -57,5 +57,5 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
IFUNC_IMPL_ADD (array, i, memchr, use_neon, __memchr_neon)
IFUNC_IMPL_ADD (array, i, memchr, 1, __memchr_noneon));
- return i;
+ return 0;
}
diff --git a/sysdeps/i386/i686/multiarch/ifunc-impl-list.c b/sysdeps/i386/i686/multiarch/ifunc-impl-list.c
index c014f52bf9..9237b589f5 100644
--- a/sysdeps/i386/i686/multiarch/ifunc-impl-list.c
+++ b/sysdeps/i386/i686/multiarch/ifunc-impl-list.c
@@ -22,9 +22,6 @@
#include <ifunc-impl-list.h>
#include "init-arch.h"
-/* Maximum number of IFUNC implementations. */
-#define MAX_IFUNC 4
-
/* Fill ARRAY of MAX elements with IFUNC implementations for function
NAME and return the number of valid entries. */
@@ -32,9 +29,7 @@ size_t
__libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
size_t max)
{
- assert (max >= MAX_IFUNC);
-
- size_t i = 0;
+ size_t i = max;
/* Support sysdeps/i386/i686/multiarch/memchr.S. */
IFUNC_IMPL (i, name, memchr,
@@ -358,5 +353,5 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
IFUNC_IMPL_ADD (array, i, strncmp, 1, __strncmp_ia32))
#endif
- return i;
+ return 0;
}
diff --git a/sysdeps/powerpc/powerpc32/power4/multiarch/ifunc-impl-list.c b/sysdeps/powerpc/powerpc32/power4/multiarch/ifunc-impl-list.c
index 01890367a4..e6ef5e6267 100644
--- a/sysdeps/powerpc/powerpc32/power4/multiarch/ifunc-impl-list.c
+++ b/sysdeps/powerpc/powerpc32/power4/multiarch/ifunc-impl-list.c
@@ -22,16 +22,11 @@
#include <ldsodefs.h>
#include <ifunc-impl-list.h>
-/* Maximum number of IFUNC implementations. */
-#define MAX_IFUNC 6
-
size_t
__libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
size_t max)
{
- assert (max >= MAX_IFUNC);
-
- size_t i = 0;
+ size_t i = max;
unsigned long int hwcap = GLRO(dl_hwcap);
/* hwcap contains only the latest supported ISA, the code checks which is
@@ -179,5 +174,5 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
IFUNC_IMPL_ADD (array, i, strchr, 1,
__strchr_ppc))
- return i;
+ return 0;
}
diff --git a/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c b/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c
index ac533a9886..5a3c7a5886 100644
--- a/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c
+++ b/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c
@@ -22,16 +22,11 @@
#include <ldsodefs.h>
#include <ifunc-impl-list.h>
-/* Maximum number of IFUNC implementations. */
-#define MAX_IFUNC 6
-
size_t
__libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
size_t max)
{
- assert (max >= MAX_IFUNC);
-
- size_t i = 0;
+ size_t i = max;
unsigned long int hwcap = GLRO(dl_hwcap);
unsigned long int hwcap2 = GLRO(dl_hwcap2);
@@ -448,5 +443,5 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
IFUNC_IMPL_ADD (array, i, strcasestr, 1,
__strcasestr_ppc))
- return i;
+ return 0;
}
diff --git a/sysdeps/s390/multiarch/ifunc-impl-list.c b/sysdeps/s390/multiarch/ifunc-impl-list.c
index c1902b2c26..5d0c73094d 100644
--- a/sysdeps/s390/multiarch/ifunc-impl-list.c
+++ b/sysdeps/s390/multiarch/ifunc-impl-list.c
@@ -66,9 +66,6 @@
#include <ifunc-wmemset.h>
#include <ifunc-wmemcmp.h>
-/* Maximum number of IFUNC implementations. */
-#define MAX_IFUNC 3
-
/* Fill ARRAY of MAX elements with IFUNC implementations for function
NAME supported on target machine and return the number of valid
entries. */
@@ -76,9 +73,7 @@ size_t
__libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
size_t max)
{
- assert (max >= MAX_IFUNC);
-
- size_t i = 0;
+ size_t i = max;
/* Get hardware information. */
unsigned long int dl_hwcap = GLRO (dl_hwcap);
@@ -670,5 +665,5 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
)
#endif /* HAVE_WMEMCMP_IFUNC */
- return i;
+ return 0;
}
diff --git a/sysdeps/sparc/sparc64/multiarch/ifunc-impl-list.c b/sysdeps/sparc/sparc64/multiarch/ifunc-impl-list.c
index 9be12f9130..918eb69a03 100644
--- a/sysdeps/sparc/sparc64/multiarch/ifunc-impl-list.c
+++ b/sysdeps/sparc/sparc64/multiarch/ifunc-impl-list.c
@@ -30,7 +30,7 @@ size_t
__libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
size_t max)
{
- size_t i = 0;
+ size_t i = max;
int hwcap;
hwcap = GLRO(dl_hwcap);
@@ -75,5 +75,5 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
__memmove_niagara7)
IFUNC_IMPL_ADD (array, i, memmove, 1, __memmove_ultra1));
- return i;
+ return 0;
}
diff --git a/sysdeps/x86_64/multiarch/ifunc-impl-list.c b/sysdeps/x86_64/multiarch/ifunc-impl-list.c
index 58f3ec8306..dc595752e0 100644
--- a/sysdeps/x86_64/multiarch/ifunc-impl-list.c
+++ b/sysdeps/x86_64/multiarch/ifunc-impl-list.c
@@ -23,9 +23,6 @@
#include <sysdep.h>
#include "init-arch.h"
-/* Maximum number of IFUNC implementations. */
-#define MAX_IFUNC 5
-
/* Fill ARRAY of MAX elements with IFUNC implementations for function
NAME supported on target machine and return the number of valid
entries. */
@@ -34,9 +31,7 @@ size_t
__libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
size_t max)
{
- assert (max >= MAX_IFUNC);
-
- size_t i = 0;
+ size_t i = max;
/* Support sysdeps/x86_64/multiarch/memcmpeq.c. */
IFUNC_IMPL (i, name, __memcmpeq,
@@ -1015,5 +1010,5 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
__wmemset_chk_avx512_unaligned))
#endif
- return i;
+ return 0;
}