elf: Initialize tunables_env_alias with loop to avoid memset
Checks
Context |
Check |
Description |
redhat-pt-bot/TryBot-apply_patch |
success
|
Patch applied to master at the time it was sent
|
redhat-pt-bot/TryBot-32bit |
success
|
Build for i686
|
linaro-tcwg-bot/tcwg_glibc_build--master-arm |
success
|
Build passed
|
linaro-tcwg-bot/tcwg_glibc_check--master-arm |
success
|
Test passed
|
linaro-tcwg-bot/tcwg_glibc_build--master-aarch64 |
success
|
Build passed
|
linaro-tcwg-bot/tcwg_glibc_check--master-aarch64 |
success
|
Test passed
|
Commit Message
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
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
>
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.
>
@@ -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)
{