diff mbox series

elf: Initialize tunables_env_alias with loop to avoid memset

Message ID 20240907170454.1660578-1-jesse.huang@sifive.com
State New
Headers show
Series elf: Initialize tunables_env_alias with loop to avoid memset | expand

Commit Message

Jesse Huang Sept. 7, 2024, 5:04 p.m. UTC
In static binaries, __tunables_init is called before the IREL relocation
is performed. This causes a problem where IFUNC for memset is provided,
because the initializer list here is translated to a call to memset,
which gets redirected to the PLT.

At the moment, all of the GOT entries still points to the top of the PLT,
thus the call first jump to the entry of memset in PLT, then jump to the
first entry of PLT, that finally leads to a infinite loop.

Fixed by using a for loop to initialize the array.
---
 elf/dl-tunables.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

Comments

H.J. Lu Sept. 7, 2024, 5:33 p.m. UTC | #1
On Sat, Sep 7, 2024 at 10:05 AM Jesse Huang <jesse.huang@sifive.com> wrote:
>
> In static binaries, __tunables_init is called before the IREL relocation
> is performed. This causes a problem where IFUNC for memset is provided,
> because the initializer list here is translated to a call to memset,
> which gets redirected to the PLT.

Why doesn't dl-symbol-redir-ifunc.h work for you?

> At the moment, all of the GOT entries still points to the top of the PLT,
> thus the call first jump to the entry of memset in PLT, then jump to the
> first entry of PLT, that finally leads to a infinite loop.
>
> Fixed by using a for loop to initialize the array.
> ---
>  elf/dl-tunables.c | 4 +++-
>  1 file changed, 3 insertions(+), 1 deletion(-)
>
> diff --git a/elf/dl-tunables.c b/elf/dl-tunables.c
> index 147cc4cf23..33f88ccf55 100644
> --- a/elf/dl-tunables.c
> +++ b/elf/dl-tunables.c
> @@ -301,7 +301,9 @@ __tunables_init (char **envp)
>      return;
>
>    enum { tunable_num_env_alias = array_length (tunable_env_alias_list) };
> -  struct tunable_toset_t tunables_env_alias[tunable_num_env_alias] = { 0 };
> +  struct tunable_toset_t tunables_env_alias[tunable_num_env_alias];
> +  for (int i = 0; i < tunable_num_env_alias; i++)
> +    tunables_env_alias[i] = (struct tunable_toset_t) { NULL, NULL, 0 };
>
>    while ((envp = get_next_env (envp, &envname, &envval, &prev_envp)) != NULL)
>      {
> --
> 2.46.0
>
Jesse Huang Sept. 9, 2024, 9:55 a.m. UTC | #2
I was completely unaware of the file and it indeed solved our problem.
Thank you for pointing it out!


--
Jesse Huang

H.J. Lu <hjl.tools@gmail.com> 於 2024年9月8日 週日 上午1:33寫道:

> On Sat, Sep 7, 2024 at 10:05 AM Jesse Huang <jesse.huang@sifive.com>
> wrote:
> >
> > In static binaries, __tunables_init is called before the IREL relocation
> > is performed. This causes a problem where IFUNC for memset is provided,
> > because the initializer list here is translated to a call to memset,
> > which gets redirected to the PLT.
>
> Why doesn't dl-symbol-redir-ifunc.h work for you?
>
> > At the moment, all of the GOT entries still points to the top of the PLT,
> > thus the call first jump to the entry of memset in PLT, then jump to the
> > first entry of PLT, that finally leads to a infinite loop.
> >
> > Fixed by using a for loop to initialize the array.
> > ---
> >  elf/dl-tunables.c | 4 +++-
> >  1 file changed, 3 insertions(+), 1 deletion(-)
> >
> > diff --git a/elf/dl-tunables.c b/elf/dl-tunables.c
> > index 147cc4cf23..33f88ccf55 100644
> > --- a/elf/dl-tunables.c
> > +++ b/elf/dl-tunables.c
> > @@ -301,7 +301,9 @@ __tunables_init (char **envp)
> >      return;
> >
> >    enum { tunable_num_env_alias = array_length (tunable_env_alias_list)
> };
> > -  struct tunable_toset_t tunables_env_alias[tunable_num_env_alias] = {
> 0 };
> > +  struct tunable_toset_t tunables_env_alias[tunable_num_env_alias];
> > +  for (int i = 0; i < tunable_num_env_alias; i++)
> > +    tunables_env_alias[i] = (struct tunable_toset_t) { NULL, NULL, 0 };
> >
> >    while ((envp = get_next_env (envp, &envname, &envval, &prev_envp)) !=
> NULL)
> >      {
> > --
> > 2.46.0
> >
>
>
> --
> H.J.
>
diff mbox series

Patch

diff --git a/elf/dl-tunables.c b/elf/dl-tunables.c
index 147cc4cf23..33f88ccf55 100644
--- a/elf/dl-tunables.c
+++ b/elf/dl-tunables.c
@@ -301,7 +301,9 @@  __tunables_init (char **envp)
     return;
 
   enum { tunable_num_env_alias = array_length (tunable_env_alias_list) };
-  struct tunable_toset_t tunables_env_alias[tunable_num_env_alias] = { 0 };
+  struct tunable_toset_t tunables_env_alias[tunable_num_env_alias];
+  for (int i = 0; i < tunable_num_env_alias; i++)
+    tunables_env_alias[i] = (struct tunable_toset_t) { NULL, NULL, 0 };
 
   while ((envp = get_next_env (envp, &envname, &envval, &prev_envp)) != NULL)
     {