Regression: NULL l_addr in link_map structure for vdso on 5.5.0
Nobody has claimed this yet.
Assessment
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Newbie friendliness
- 32/100
- Issue type
- Bug
- Clarity
- Mostly clear
- Activity status
- Stale
- Domain
- devtools, operating-systems, reverse-engineering
Research direction
Start with the minimal vdsoaddr application and reproduce it under rr, comparing the link_map l_addr value with and without rr. Read elf/setup-vdso.h, especially setup_vdso(), and inspect the librrpage.so PT_LOAD entries and commit 4be0255d. Done means the vdso link_map l_addr remains valid under rr without regressing normal execution.
Written by the indexing model from the issue text.
Description
I've discovered a regression from 5.4.0 to 5.5.0. Applications that use dlopen() to obtain a dynamic linker struct link_map pointer corresponding to the vdso and observe the l_addr field will find it to be NULL. Here's a minimal application that crashes on 5.5.0 (link with -ldl):
#include <assert.h>
#include <link.h>
#include <string.h>
int main(void) {
const struct link_map *l = dlopen(NULL, RTLD_LAZY);
while(l && strcmp(l->l_name, "linux-vdso.so.1"))
l = l->l_next;
assert(l->l_addr);
return 0;
}
It looks like the NULL originates in ld-linux.so's setup_vdso() function. When running without rr, all of the PT_LOAD entries in the program header have a p_vaddr of 0, so line 52 has no effect and line 64 is equivalent to l->l_addr = l->l_map_start. Under rr, the first PT_LOAD entry has a p_vaddr that matches l->l_map_start, so line 64 instead resets l->l_addr to NULL.
It looks like for setup_vdso() to work correctly on librrpage.so, all of its PT_LOAD entries would have to have a p_vaddr of 0, which is infeasible. And since setup_vdso() is an inline function, it cannot be interposed. Perhaps rr can just manually set the l_addr field after the dynamic linker is finished?
I'm using glibc 2.33 from Debian:
$ apt policy libc6
libc6:
Installed: 2.33-1
It looks like this was introduced in 4be0255d, which proxies the vdso. Here's my bisection script:
#!/bin/sh
mydir="`dirname "$0"`"
set -ev
[ -e vdsoaddr ] || c99 -o vdsoaddr "$mydir/vdsoaddr.c" -ldl
[ -e vdsoaddr-0 ] && rm -rf vdsoaddr-0
git cherry HEAD dbc94c6f | grep ^+ >/dev/null && git cherry-pick -n dbc94c6f
./configure
make -j8
git reset --hard
_RR_TRACE_DIR="." bin/rr ./vdsoaddr || false
- Dominant language
- C++
- Stars
- 10.7k
- Forks
- 662
- Avg merge
- 2d 3h
- Merged PRs (30d)
- 2
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from rr-debugger/rr
-
Difficulty 2/5 1-3 hours Newbie friendliness 76/100
rr-debugger/rr#4096 · 1 comment ·
-
Difficulty 4/5 3-5 days Newbie friendliness 48/100
rr-debugger/rr#4093 · 6 comments ·
-
Difficulty 4/5 3-5 days Newbie friendliness 48/100
rr-debugger/rr#4090 · 1 comment ·
-
Difficulty 4/5 3-5 days Newbie friendliness 35/100
rr-debugger/rr#4060 · 5 comments ·
-
Difficulty 3/5 1-2 days Newbie friendliness 68/100
rr-debugger/rr#4059 · 1 comment ·
Similar issues
-
Difficulty 2/5 1-3 hours Newbie friendliness 86/100
-
Sensor initialization takes very long when `--initial-sim-time` is set to current UNIX timestamp Open
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
gazebosim/gz-sensors#662 · 1 comment ·
-
enhancement
Difficulty 2/5 1-3 hours Newbie friendliness 76/100
-
comp-datalake
Difficulty 2/5 1-3 hours Newbie friendliness 88/100
ClickHouse/ClickHouse#121222 ·
-
Difficulty 2/5 1-3 hours Newbie friendliness 68/100
LadybirdBrowser/ladybird#12123 ·