Bug 197921

Summary: Wrongly calculate AT_PHDR for ELF auxiliary vectors
Product: Other Reporter: netfirewall
Component: OtherAssignee: other_other
Status: NEW ---    
Severity: normal CC: a.kawashiro, xiangzhex
Priority: P1    
Hardware: All   
OS: Linux   
Kernel Version: 4.13.0 Subsystem:
Regression: No Bisected commit-id:
Attachments: Example ELF with abnormal proram header offset

Description netfirewall 2017-11-19 16:24:06 UTC
The AT_PHDR of ELF auxiliary vectors should point to the memory address of program header. But binfmt_elf.c calculates this address as follow:

NEW_AUX_ENT(AT_PHDR, load_addr + exec->e_phoff);

which is wrong since e_phoff is the file offset of program header and load_addr is the memory base address from PT_LOAD entry.

The ld.so uses AT_PHDR as the memory address of program header. In normal case, since the e_phoff is usually 64 and in the first PT_LOAD region, it is the correct program header address.

But if the address of program header isn't equal to the first PT_LOAD address + e_phoff (e.g. Put the program header in other non-consecutive PT_LOAD region), ld.so will try to read program header from wrong address then crash or use incorrect program header.
Comment 1 netfirewall 2017-11-19 16:44:12 UTC
Created attachment 260719 [details]
Example ELF with abnormal proram header offset

I move the program header of this ELF to file offset 0x1040, which will be mapped to 0x601040. But AT_PHDR will be 0x401040, which is wrong.
Comment 2 xiangzhe xu 2021-03-26 04:53:03 UTC
I got the same problem. It seems that the issue still exists in the kernel.
Comment 3 Akira Kawata 2021-10-17 14:03:51 UTC
I am now trying to make a patch to fix this issue and I think there are two problems around AT_PHDR.

The first one is the current kernel use `exec->e_phoff` as the offset for program headers as discussed in this issue.

The second one is it calculates `load_addr` from the first program header. This should be the minimum value for all program headers as discussed in https://bugs.launchpad.net/qemu/+bug/1885332.