DynamoRIO / DynamoRIO/dynamorio

Match glibc behavior when passing arguments to ifunc resolvers in private loader

Open
#7,392 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
C
Stars
3.2k
Forks
629
Avg merge
2d 15h
Merged PRs (30d)
31

Description

Currently, our private loader unconditionally passes no arguments to ifunc resolvers. On x86_64 and x86_32, this exactly matches the behavior of glibc 2.41[1][2]. But on aarch32, aarch64 and riscv64, ifunc resolvers take different arguments,

- aarch32: `Elf32_Addr (*)(unsigned long int hwcap)`[3]
- aarch64: `Elf64_Addr (*)(uint64_t hwcap, const __ifunc_arg_t *arg)`[4], where `__ifunc_arg_t` is defined as[5]
```
typedef struct __ifunc_arg_t {
unsigned long _size;
unsigned long _hwcap;
unsigned long _hwcap2;
} __ifunc_arg_t;
```
- riscv64: `ElfW(Addr) (*)(uint64_t hwcap, void *hwprobe, void *reserved)`[6], where hwprobe is a pointer to __riscv_hwprobe[7], a wrapper over riscv_hwprobe syscall, and reserved should be NULL.

Xref #7374 which corrects the prototype on riscv64. Wrong arguments passed to resolvers are causing segfaults with a newer glibc and clients depending on glibc attached.

Additionally, the prototype of ifunc resolvers varies between glibc versions,

- aarch32
- Before glibc commit `73da6bacfd (arm: Pass hwcap to ifuncs., 2012-05-25)` which landed in v2.17: `Elf32_Addr (*)(void)` (no argument)
- aarch64
- Before glibc commit `2b8a3c86e7 (aarch64: new ifunc resolver ABI, 2019-04-23)` which landed in v2.30: `Elf64_Addr (*)(uint64_t addr)`
- Before glibc commit `7520ff8c74 (aarch64: Enable ifunc support., 2013-11-25)` which landed v2.19: `Elf64_Addr (*)(void)`. But this is the commit that really enables ifunc support on AArch64, so maybe we could omit earlier versions.
- riscv64
- Before glibc commit `78308ce77a (riscv: Add __riscv_hwprobe pointer to ifunc calls, 2024-02-27)` which landed in v2.40: `ElfW(Addr) (*) (uint64_t hwcap, void *reserved)`, where reserved should be NULL.

We may parse the version of dynamic loader and pass the exactly same arguments to resolvers as the glibc loader does.

[1]: https://github.com/bminor/glibc/blob/74f59e9271cbb4071671e5a474e7d4f1622b186f/sysdeps/x86_64/].h#L32
[2]: https://github.com/bminor/glibc/blob/74f59e9271cbb4071671e5a474e7d4f1622b186f/sysdeps/i386/dl-irel.h#L32
[3]: https://github.com/bminor/glibc/blob/74f59e9271cbb4071671e5a474e7d4f1622b186f/sysdeps/arm/dl-irel.h#L33
[4]: https://github.com/bminor/glibc/blob/74f59e9271cbb4071671e5a474e7d4f1622b186f/sysdeps/aarch64/dl-irel.h#L40-L41
[5]: https://github.com/bminor/glibc/blob/74f59e9271cbb4071671e5a474e7d4f1622b186f/sysdeps/aarch64/sys/ifunc.h#L33-L38
[6]: https://github.com/bminor/glibc/blob/74f59e9271cbb4071671e5a474e7d4f1622b186f/sysdeps/riscv/dl-irel.h#L37-L38
[7]: https://github.com/bminor/glibc/blob/74f59e9271cbb4071671e5a474e7d4f1622b186f/sysdeps/unix/sysv/linux/riscv/hwprobe.c#L25-L36

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.