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:
committed by
Wilco Dijkstra
parent
f107b7b30d
commit
fdaf78656f
@@ -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; \
|
||||||
}
|
}
|
||||||
|
@@ -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;
|
||||||
}
|
}
|
||||||
|
@@ -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;
|
||||||
}
|
}
|
||||||
|
@@ -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;
|
||||||
}
|
}
|
||||||
|
@@ -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;
|
||||||
}
|
}
|
||||||
|
@@ -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;
|
||||||
}
|
}
|
||||||
|
@@ -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;
|
||||||
}
|
}
|
||||||
|
@@ -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;
|
||||||
}
|
}
|
||||||
|
@@ -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;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user