Skip to content

Commit

Permalink
Disable a symbol name cache if ASLR is enabled
Browse files Browse the repository at this point in the history
`resolve_usym()` caches a `bcc_symbol` object using an executable name
as a key, but on the ASLR-enabled platform, symbol addresses change with
each execution. Disable (discard) a cache, in this case, to resolve
symbol names properly.

Note and known issues:

- A cache is discarded whenever resolve_usym is called even if a pid is
the same as the old one. This is because pid may be reused.
- This does not check whether a binary is PIE ASLAR or not. Note that
even if a binary is not PIE ASLR, addresses of shared libraries are
randomized if ASLR is enabled.  (If a binary is not PIE ASLR and
`resolve_usym()` resolves symbol in a binary, we can utilize a cache.)
- If ASLR is disabled on the first execution but enabled on the second
execution, `resolve_usym()` for the second run will use the previous
cache.
- I'm not sure how much performance impact this has. If the impact is
huge, maybe this should be an option.
- As discussed in bpftrace#246, symbolizing will fail after process termination
(this is a separate issue). For example:

```
% bpftrace -e 'u:/lib/x86_64-linux-gnu/libc.so.6:*nanosleep* /comm == "sleep"/ { @[ustack] = count(); }'
Attaching 7 probes...
^C

@[
    0x7ff1917cb990
]: 3
@no such file or directory: /proc/3557/personality
[
    0x7fea4211c990
]: 3
@no such file or directory: /proc/3554/personality
[
    0x7f32bc51a990
]: 3
```

-----

Closes bpftrace#1031 and solves the second part of bpftrace#75.
  • Loading branch information
mmisono committed Dec 26, 2019
1 parent 3b9e959 commit 19206ed
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 0 deletions.
45 changes: 45 additions & 0 deletions src/bpftrace.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include <fcntl.h>
#include <sys/prctl.h>
#include <sys/stat.h>
#include <sys/personality.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
Expand Down Expand Up @@ -1692,6 +1693,43 @@ std::string BPFtrace::resolve_inet(int af, const uint8_t* inet) const
return addrstr;
}


// /proc/sys/kernel/randomize_va_space >= 1 and // system-wide
// (/proc/<pid>/personality & ADDR_NO_RNDOMIZE) == 0 // this pid
bool BPFtrace::is_aslr_enabled(int pid)
{
std::string randomize_va_space_file = "/proc/sys/kernel/randomize_va_space";
std::string personality_file = "/proc/" + std::to_string(pid) + "/personality";

{
std::ifstream file(randomize_va_space_file);
if (file.fail())
{
std::cerr << strerror(errno) << ": " << randomize_va_space_file << std::endl;
// conservatively return true
return true;
}

std::string line;
if(std::getline(file, line) && std::stoi(line) < 1)
return false;
}

{
std::ifstream file(personality_file);
if (file.fail())
{
std::cerr << strerror(errno) << ": " << personality_file << std::endl;
return true;
}
std::string line;
if(std::getline(file, line) && ((std::stoi(line) & ADDR_NO_RANDOMIZE) == 0))
return true;
}

return false;
}

std::string BPFtrace::resolve_usym(uintptr_t addr, int pid, bool show_offset, bool show_module)
{
struct bcc_symbol usym;
Expand Down Expand Up @@ -1737,6 +1775,13 @@ std::string BPFtrace::resolve_usym(uintptr_t addr, int pid, bool show_offset, bo
symbol << " ([unknown])";
}

if (psyms && is_aslr_enabled(pid))
{
std::string pid_exe = get_pid_exe(pid);
exe_sym_.erase(pid_exe);
bcc_free_symcache(psyms, pid);
}

return symbol.str();
}

Expand Down
1 change: 1 addition & 0 deletions src/bpftrace.h
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ class BPFtrace
virtual pid_t child_pid() { return child_pid_; };
int spawn_child();
void kill_child();
bool is_aslr_enabled(int pid);

std::string cmd_;
int pid_{0};
Expand Down

0 comments on commit 19206ed

Please sign in to comment.