Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save kerneltoast/563d5f258989b456e545958644c8d811 to your computer and use it in GitHub Desktop.
Save kerneltoast/563d5f258989b456e545958644c8d811 to your computer and use it in GitHub Desktop.
From c30b6188e2024995f241cce29b569f9595d27110 Mon Sep 17 00:00:00 2001
From: Sultan Alsawaf <sultan@openresty.com>
Date: Tue, 13 Apr 2021 18:02:34 -0700
Subject: [PATCH] runtime: fix user address calculation for PIE binaries
Commit d1b554876 ("runtime: fix symbol lookups when the first section
isn't executable") resolved an issue caused by not storing VMA info when
it was actually needed, and it did this by unconditionally storing VMA
info. It turns out we don't want to unconditionally store VMA info, as
is the case for PIE binaries. Doing so causes user address calculations
for PIE binaries to erroneously include the offset of the section
containing the target address.
Fix it by restoring the old code and just adding what's needed to fix
the bug described in commit d1b554876 (i.e., always storing VMA info
when `vm_start + offset == addr`).
---
runtime/vma.c | 18 +++++++++++++++---
1 file changed, 15 insertions(+), 3 deletions(-)
diff --git a/runtime/vma.c b/runtime/vma.c
index 0b7ab1fb1..2bf1b0a9c 100644
--- a/runtime/vma.c
+++ b/runtime/vma.c
@@ -178,9 +178,21 @@ static int _stp_vma_mmap_cb(struct stap_task_finder_target *tgt,
"vm_cb: matched path %s to module (sec: %s)\n",
path, _stp_modules[i]->sections[0].name);
module = _stp_modules[i];
- res = stap_add_vma_map_info(tsk->group_leader,
- addr, addr + length,
- offset, path, module);
+ /* Make sure we really don't know about this module
+ yet. If we do know, we might want to extend
+ the coverage. */
+ res = stap_find_vma_map_info_user(tsk->group_leader,
+ module,
+ &vm_start, &vm_end,
+ NULL);
+ if (res == -ESRCH || vm_start + offset == addr)
+ res = stap_add_vma_map_info(tsk->group_leader,
+ addr, addr + length,
+ offset, path, module);
+ else if (res == 0 && vm_end + 1 == addr)
+ res = stap_extend_vma_map_info(tsk->group_leader,
+ vm_start,
+ addr + length);
/* VMA entries are allocated dynamically, this is fine,
* since we are in a task_finder callback, which is in
* user context. */
--
2.31.1
set -e
cat > a.c << EOF
int a = 0xfc4e;
int main () { return 0; }
EOF
gcc -pie a.c
OFFSET=`nm a.out | grep ' a' | grep -oP '[1-9]\S+' | sed 's/^/0x/'`
A_OUT="$PWD/a.out"
cat > test.stp << EOF
function get_addr:long() %{
/* pragma:vma */
STAP_RETURN(_stp_umodule_relocate("$A_OUT", $OFFSET, current));
%}
probe process("$A_OUT").function("main") {
addr = get_addr()
printf("Value at address 0x%lx is 0x%x\n", addr, user_int32_error(addr))
exit()
}
EOF
sudo stap -v -g -c $A_OUT test.stp
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment