1
0
mirror of https://sourceware.org/git/glibc.git synced 2025-08-08 17:42:12 +03:00

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>
This commit is contained in:
Wilco Dijkstra
2022-06-10 17:13:29 +01:00
committed by Wilco Dijkstra
parent f107b7b30d
commit fdaf78656f
9 changed files with 20 additions and 50 deletions

View File

@@ -34,15 +34,15 @@ struct libc_ifunc_impl
/* Add an IFUNC implementation, IMPL, for function FUNC, to ARRAY with /* Add an IFUNC implementation, IMPL, for function FUNC, to ARRAY with
USABLE at index I and advance I by one. */ 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; \ 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 /* Return the number of IFUNC implementations, N, for function FUNC if
string NAME matches FUNC. */ string NAME matches FUNC. */
#define IFUNC_IMPL(n, name, func, ...) \ #define IFUNC_IMPL(max, name, func, ...) \
if (strcmp (name, #func) == 0) \ if (strcmp (name, #func) == 0) \
{ \ { size_t n = 0;\
__VA_ARGS__; \ __VA_ARGS__; \
return n; \ return n; \
} }

View File

@@ -24,16 +24,11 @@
#include <init-arch.h> #include <init-arch.h>
#include <stdio.h> #include <stdio.h>
/* Maximum number of IFUNC implementations. */
#define MAX_IFUNC 8
size_t size_t
__libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
size_t max) size_t max)
{ {
assert (max >= MAX_IFUNC); size_t i = max;
size_t i = 0;
INIT_ARCH (); 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, !mte, __strlen_asimd)
IFUNC_IMPL_ADD (array, i, strlen, 1, __strlen_mte)) IFUNC_IMPL_ADD (array, i, strlen, 1, __strlen_mte))
return i; return 0;
} }

View File

@@ -29,7 +29,7 @@ size_t
__libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
size_t max) size_t max)
{ {
size_t i = 0; size_t i = max;
bool use_neon = true; bool use_neon = true;
#ifdef __ARM_NEON__ #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, use_neon, __memchr_neon)
IFUNC_IMPL_ADD (array, i, memchr, 1, __memchr_noneon)); IFUNC_IMPL_ADD (array, i, memchr, 1, __memchr_noneon));
return i; return 0;
} }

View File

@@ -22,9 +22,6 @@
#include <ifunc-impl-list.h> #include <ifunc-impl-list.h>
#include "init-arch.h" #include "init-arch.h"
/* Maximum number of IFUNC implementations. */
#define MAX_IFUNC 4
/* Fill ARRAY of MAX elements with IFUNC implementations for function /* Fill ARRAY of MAX elements with IFUNC implementations for function
NAME and return the number of valid entries. */ 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, __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
size_t max) size_t max)
{ {
assert (max >= MAX_IFUNC); size_t i = max;
size_t i = 0;
/* Support sysdeps/i386/i686/multiarch/memchr.S. */ /* Support sysdeps/i386/i686/multiarch/memchr.S. */
IFUNC_IMPL (i, name, memchr, 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)) IFUNC_IMPL_ADD (array, i, strncmp, 1, __strncmp_ia32))
#endif #endif
return i; return 0;
} }

View File

@@ -22,16 +22,11 @@
#include <ldsodefs.h> #include <ldsodefs.h>
#include <ifunc-impl-list.h> #include <ifunc-impl-list.h>
/* Maximum number of IFUNC implementations. */
#define MAX_IFUNC 6
size_t size_t
__libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
size_t max) size_t max)
{ {
assert (max >= MAX_IFUNC); size_t i = max;
size_t i = 0;
unsigned long int hwcap = GLRO(dl_hwcap); unsigned long int hwcap = GLRO(dl_hwcap);
/* hwcap contains only the latest supported ISA, the code checks which is /* 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, IFUNC_IMPL_ADD (array, i, strchr, 1,
__strchr_ppc)) __strchr_ppc))
return i; return 0;
} }

View File

@@ -22,16 +22,11 @@
#include <ldsodefs.h> #include <ldsodefs.h>
#include <ifunc-impl-list.h> #include <ifunc-impl-list.h>
/* Maximum number of IFUNC implementations. */
#define MAX_IFUNC 6
size_t size_t
__libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
size_t max) size_t max)
{ {
assert (max >= MAX_IFUNC); size_t i = max;
size_t i = 0;
unsigned long int hwcap = GLRO(dl_hwcap); unsigned long int hwcap = GLRO(dl_hwcap);
unsigned long int hwcap2 = GLRO(dl_hwcap2); 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, IFUNC_IMPL_ADD (array, i, strcasestr, 1,
__strcasestr_ppc)) __strcasestr_ppc))
return i; return 0;
} }

View File

@@ -66,9 +66,6 @@
#include <ifunc-wmemset.h> #include <ifunc-wmemset.h>
#include <ifunc-wmemcmp.h> #include <ifunc-wmemcmp.h>
/* Maximum number of IFUNC implementations. */
#define MAX_IFUNC 3
/* Fill ARRAY of MAX elements with IFUNC implementations for function /* Fill ARRAY of MAX elements with IFUNC implementations for function
NAME supported on target machine and return the number of valid NAME supported on target machine and return the number of valid
entries. */ entries. */
@@ -76,9 +73,7 @@ size_t
__libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
size_t max) size_t max)
{ {
assert (max >= MAX_IFUNC); size_t i = max;
size_t i = 0;
/* Get hardware information. */ /* Get hardware information. */
unsigned long int dl_hwcap = GLRO (dl_hwcap); 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 */ #endif /* HAVE_WMEMCMP_IFUNC */
return i; return 0;
} }

View File

@@ -30,7 +30,7 @@ size_t
__libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
size_t max) size_t max)
{ {
size_t i = 0; size_t i = max;
int hwcap; int hwcap;
hwcap = GLRO(dl_hwcap); hwcap = GLRO(dl_hwcap);
@@ -75,5 +75,5 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
__memmove_niagara7) __memmove_niagara7)
IFUNC_IMPL_ADD (array, i, memmove, 1, __memmove_ultra1)); IFUNC_IMPL_ADD (array, i, memmove, 1, __memmove_ultra1));
return i; return 0;
} }

View File

@@ -23,9 +23,6 @@
#include <sysdep.h> #include <sysdep.h>
#include "init-arch.h" #include "init-arch.h"
/* Maximum number of IFUNC implementations. */
#define MAX_IFUNC 5
/* Fill ARRAY of MAX elements with IFUNC implementations for function /* Fill ARRAY of MAX elements with IFUNC implementations for function
NAME supported on target machine and return the number of valid NAME supported on target machine and return the number of valid
entries. */ entries. */
@@ -34,9 +31,7 @@ size_t
__libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
size_t max) size_t max)
{ {
assert (max >= MAX_IFUNC); size_t i = max;
size_t i = 0;
/* Support sysdeps/x86_64/multiarch/memcmpeq.c. */ /* Support sysdeps/x86_64/multiarch/memcmpeq.c. */
IFUNC_IMPL (i, name, __memcmpeq, 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)) __wmemset_chk_avx512_unaligned))
#endif #endif
return i; return 0;
} }