Skip to content

Commit

Permalink
skip kprobe functions outside normal text section
Browse files Browse the repository at this point in the history
Fix issue #1634.

When kernel is about to attach a kprobe, the following functions
are called:
  register_kprobe
    check_kprobe_address_safe
      kernel_text_address
        core_kernel_text

In core_kernel_text, we have:
        if (addr >= (unsigned long)_stext &&
            addr < (unsigned long)_etext)
                return 1;

Basically, any address outside of [_stext, _etext] will
be rejected.

The functions marked as __init are outside [_stext, _etext].
That is why vfs_caches_init_early and vfs_caches_init
are rejected by trace_kprobe.
Given a regex, this patch avoided attaching these functions
if their func addresses are outside [_stext, _etext] range.

Signed-off-by: Yonghong Song <[email protected]>
  • Loading branch information
yonghong-song committed Mar 23, 2018
1 parent e0d808e commit e76f456
Showing 1 changed file with 19 additions and 4 deletions.
23 changes: 19 additions & 4 deletions src/python/bcc/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -481,11 +481,26 @@ def get_kprobe_functions(event_re):
with open("%s/../kprobes/blacklist" % TRACEFS, "rb") as blacklist_f:
blacklist = set([line.rstrip().split()[1] for line in blacklist_f])
fns = []

# find the start and the end of normal text region
stext = float('-inf')
etext = float('inf')
with open("/proc/kallsyms", "rb") as avail_file:
for line in avail_file:
(addr, t, fn) = line.rstrip().split()[:3]
if fn == b'_stext':
stext = int(addr.decode('ascii'), 16)
if fn == b'_etext':
etext = int(addr.decode('ascii'), 16)
break

with open("/proc/kallsyms", "rb") as avail_file:
for line in avail_file:
(_, t, fn) = line.rstrip().split()[:3]
(addr, t, fn) = line.rstrip().split()[:3]
if (t.lower() in [b't', b'w']) and re.match(event_re, fn) \
and fn not in blacklist:
and fn not in blacklist \
and int(addr.decode('ascii'), 16) >= stext \
and int(addr.decode('ascii'), 16) <= etext:
fns.append(fn)
return set(fns) # Some functions may appear more than once

Expand Down Expand Up @@ -558,7 +573,7 @@ def attach_kretprobe(self, event=b"", fn_name=b"", event_re=b""):
ev_name = b"r_" + event.replace(b"+", b"_").replace(b".", b"_")
fd = lib.bpf_attach_kprobe(fn.fd, 1, ev_name, event)
if fd < 0:
raise Exception("Failed to attach BPF to kprobe")
raise Exception("Failed to attach BPF to kretprobe")
self._add_kprobe_fd(ev_name, fd)
return self

Expand Down Expand Up @@ -877,7 +892,7 @@ def attach_uretprobe(self, name=b"", sym=b"", sym_re=b"", addr=None,
ev_name = self._get_uprobe_evname(b"r", path, addr, pid)
fd = lib.bpf_attach_uprobe(fn.fd, 1, ev_name, path, addr, pid)
if fd < 0:
raise Exception("Failed to attach BPF to uprobe")
raise Exception("Failed to attach BPF to uretprobe")
self._add_uprobe_fd(ev_name, fd)
return self

Expand Down

0 comments on commit e76f456

Please sign in to comment.