execsnoop-bpfcc: immediately segfaults

Bug #1748176 reported by Chris West
6
This bug affects 1 person
Affects Status Importance Assigned to Milestone
bpfcc (Ubuntu)
New
Undecided
Unassigned

Bug Description

execsnoop-bpfcc prints some compiler warnings, then immediately segfaults.

This may have been discussed upstream at: https://github.com/iovisor/bcc/issues/1276

Output:

(gdb) r
Starting program: /usr/bin/python /usr/sbin/execsnoop-bpfcc
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
In file included from /virtual/main.c:3:
In file included from include/linux/sched.h:13:
In file included from include/linux/pid.h:4:
In file included from include/linux/rculist.h:10:
In file included from include/linux/rcupdate.h:40:
In file included from include/linux/preempt.h:80:
In file included from ./arch/x86/include/asm/preempt.h:6:
In file included from include/linux/thread_info.h:37:
In file included from ./arch/x86/include/asm/thread_info.h:63:
In file included from ./arch/x86/include/asm/cpufeature.h:4:
./arch/x86/include/asm/processor.h:534:17: warning: taking address of packed member 'sp0' of class or structure 'x86_hw_tss' may result in an unaligned pointer value [-Waddress-of-packed-member]
        this_cpu_write(cpu_tss_rw.x86_tss.sp0, sp0);
                       ^~~~~~~~~~~~~~~~~~~~~~
include/linux/percpu-defs.h:495:68: note: expanded from macro 'this_cpu_write'
#define this_cpu_write(pcp, val) __pcpu_size_call(this_cpu_write_, pcp, val)
                                                                          ^~~
include/linux/percpu-defs.h:362:22: note: expanded from macro '__pcpu_size_call'
        __verify_pcpu_ptr(&(variable)); \
                            ^~~~~~~~
include/linux/percpu-defs.h:206:47: note: expanded from macro '__verify_pcpu_ptr'
        const void __percpu *__vpp_verify = (typeof((ptr) + 0))NULL; \
                                                     ^~~
In file included from /virtual/main.c:3:
In file included from include/linux/sched.h:13:
In file included from include/linux/pid.h:4:
In file included from include/linux/rculist.h:10:
In file included from include/linux/rcupdate.h:40:
In file included from include/linux/preempt.h:80:
In file included from ./arch/x86/include/asm/preempt.h:6:
In file included from include/linux/thread_info.h:37:
In file included from ./arch/x86/include/asm/thread_info.h:63:
In file included from ./arch/x86/include/asm/cpufeature.h:4:
./arch/x86/include/asm/processor.h:551:30: warning: taking address of packed member 'sp1' of class or structure 'x86_hw_tss' may result in an unaligned pointer value [-Waddress-of-packed-member]
        return this_cpu_read_stable(cpu_current_top_of_stack);
                                    ^~~~~~~~~~~~~~~~~~~~~~~~
./arch/x86/include/asm/processor.h:374:34: note: expanded from macro 'cpu_current_top_of_stack'
#define cpu_current_top_of_stack cpu_tss_rw.x86_tss.sp1
                                 ^~~~~~~~~~~~~~~~~~~~~~
./arch/x86/include/asm/percpu.h:391:59: note: expanded from macro 'this_cpu_read_stable'
#define this_cpu_read_stable(var) percpu_stable_op("mov", var)
                                                                ^~~
./arch/x86/include/asm/percpu.h:218:16: note: expanded from macro 'percpu_stable_op'
                    : "p" (&(var))); \
                             ^~~
In file included from /virtual/main.c:3:
In file included from include/linux/sched.h:13:
In file included from include/linux/pid.h:4:
In file included from include/linux/rculist.h:10:
In file included from include/linux/rcupdate.h:40:
In file included from include/linux/preempt.h:80:
In file included from ./arch/x86/include/asm/preempt.h:6:
In file included from include/linux/thread_info.h:37:
In file included from ./arch/x86/include/asm/thread_info.h:63:
In file included from ./arch/x86/include/asm/cpufeature.h:4:
./arch/x86/include/asm/processor.h:551:30: warning: taking address of packed member 'sp1' of class or structure 'x86_hw_tss' may result in an unaligned pointer value [-Waddress-of-packed-member]
        return this_cpu_read_stable(cpu_current_top_of_stack);
                                    ^~~~~~~~~~~~~~~~~~~~~~~~
./arch/x86/include/asm/processor.h:374:34: note: expanded from macro 'cpu_current_top_of_stack'
#define cpu_current_top_of_stack cpu_tss_rw.x86_tss.sp1
                                 ^~~~~~~~~~~~~~~~~~~~~~
./arch/x86/include/asm/percpu.h:391:59: note: expanded from macro 'this_cpu_read_stable'
#define this_cpu_read_stable(var) percpu_stable_op("mov", var)
                                                                ^~~
./arch/x86/include/asm/percpu.h:223:16: note: expanded from macro 'percpu_stable_op'
                    : "p" (&(var))); \
                             ^~~
In file included from /virtual/main.c:3:
In file included from include/linux/sched.h:13:
In file included from include/linux/pid.h:4:
In file included from include/linux/rculist.h:10:
In file included from include/linux/rcupdate.h:40:
In file included from include/linux/preempt.h:80:
In file included from ./arch/x86/include/asm/preempt.h:6:
In file included from include/linux/thread_info.h:37:
In file included from ./arch/x86/include/asm/thread_info.h:63:
In file included from ./arch/x86/include/asm/cpufeature.h:4:
./arch/x86/include/asm/processor.h:551:30: warning: taking address of packed member 'sp1' of class or structure 'x86_hw_tss' may result in an unaligned pointer value [-Waddress-of-packed-member]
        return this_cpu_read_stable(cpu_current_top_of_stack);
                                    ^~~~~~~~~~~~~~~~~~~~~~~~
./arch/x86/include/asm/processor.h:374:34: note: expanded from macro 'cpu_current_top_of_stack'
#define cpu_current_top_of_stack cpu_tss_rw.x86_tss.sp1
                                 ^~~~~~~~~~~~~~~~~~~~~~
./arch/x86/include/asm/percpu.h:391:59: note: expanded from macro 'this_cpu_read_stable'
#define this_cpu_read_stable(var) percpu_stable_op("mov", var)
                                                                ^~~
./arch/x86/include/asm/percpu.h:228:16: note: expanded from macro 'percpu_stable_op'
                    : "p" (&(var))); \
                             ^~~
In file included from /virtual/main.c:3:
In file included from include/linux/sched.h:13:
In file included from include/linux/pid.h:4:
In file included from include/linux/rculist.h:10:
In file included from include/linux/rcupdate.h:40:
In file included from include/linux/preempt.h:80:
In file included from ./arch/x86/include/asm/preempt.h:6:
In file included from include/linux/thread_info.h:37:
In file included from ./arch/x86/include/asm/thread_info.h:63:
In file included from ./arch/x86/include/asm/cpufeature.h:4:
./arch/x86/include/asm/processor.h:551:30: warning: taking address of packed member 'sp1' of class or structure 'x86_hw_tss' may result in an unaligned pointer value [-Waddress-of-packed-member]
        return this_cpu_read_stable(cpu_current_top_of_stack);
                                    ^~~~~~~~~~~~~~~~~~~~~~~~
./arch/x86/include/asm/processor.h:374:34: note: expanded from macro 'cpu_current_top_of_stack'
#define cpu_current_top_of_stack cpu_tss_rw.x86_tss.sp1
                                 ^~~~~~~~~~~~~~~~~~~~~~
./arch/x86/include/asm/percpu.h:391:59: note: expanded from macro 'this_cpu_read_stable'
#define this_cpu_read_stable(var) percpu_stable_op("mov", var)
                                                                ^~~
./arch/x86/include/asm/percpu.h:233:16: note: expanded from macro 'percpu_stable_op'
                    : "p" (&(var))); \
                             ^~~
5 warnings generated.
warning: JITed object file architecture unknown is not compatible with target architecture i386:x86-64.

Program received signal SIGSEGV, Segmentation fault.
0x00007ffff4cbf5c4 in llvm::RuntimeDyldELF::resolveRelocation(llvm::RelocationEntry const&, unsigned long) () from /usr/lib/x86_64-linux-gnu/libbcc.so.0

(gdb) bt
#0 0x00007ffff4cbf5c4 in llvm::RuntimeDyldELF::resolveRelocation(llvm::RelocationEntry const&, unsigned long) () from /usr/lib/x86_64-linux-gnu/libbcc.so.0
#1 0x00007ffff4cbf5f4 in llvm::RuntimeDyldELF::resolveRelocation(llvm::RelocationEntry const&, unsigned long) () from /usr/lib/x86_64-linux-gnu/libbcc.so.0
#2 0x00007ffff4cbf5f4 in llvm::RuntimeDyldELF::resolveRelocation(llvm::RelocationEntry const&, unsigned long) () from /usr/lib/x86_64-linux-gnu/libbcc.so.0
#3 0x00007ffff4caa6a8 in llvm::RuntimeDyldImpl::resolveRelocationList(llvm::SmallVector<llvm::RelocationEntry, 64u> const&, unsigned long) () from /usr/lib/x86_64-linux-gnu/libbcc.so.0
#4 0x00007ffff4caaf50 in llvm::RuntimeDyldImpl::resolveRelocations() () from /usr/lib/x86_64-linux-gnu/libbcc.so.0
#5 0x00007ffff4c95b4f in llvm::MCJIT::finalizeLoadedModules() () from /usr/lib/x86_64-linux-gnu/libbcc.so.0
#6 0x00007ffff4c960fd in llvm::MCJIT::finalizeObject() () from /usr/lib/x86_64-linux-gnu/libbcc.so.0
#7 0x00007ffff3b3d5de in ebpf::BPFModule::finalize (this=this@entry=0x555555c89050) at ./src/cc/bpf_module.cc:440
#8 0x00007ffff3b3ddcd in ebpf::BPFModule::load_string (this=this@entry=0x555555c89050, text=..., cflags=cflags@entry=0x7ffff2e89880, ncflags=ncflags@entry=0) at ./src/cc/bpf_module.cc:756
#9 0x00007ffff3b361a8 in bpf_module_create_c_from_string (
    text=0x555555c80424 "\n#include <uapi/linux/ptrace.h>\n#include <linux/sched.h>\n#include <linux/fs.h>\n\n#define MAXARG 20\n#define ARGSIZE 128\n\nenum event_type {\n EVENT_ARG,\n EVENT_RET,\n};\n\nstruct data_t {\n u32 pi"..., flags=<optimised out>, cflags=0x7ffff2e89880, ncflags=0) at ./src/cc/bpf_common.cc:40
#10 0x00007ffff6711e18 in ffi_call_unix64 () from /usr/lib/x86_64-linux-gnu/libffi.so.6
#11 0x00007ffff671187a in ffi_call () from /usr/lib/x86_64-linux-gnu/libffi.so.6
#12 0x00007ffff696c04f in _call_function_pointer (argcount=4, resmem=0x7fffffffd800, restype=<optimised out>, atypes=<optimised out>, avalues=0x7fffffffd7d0,
    pProc=0x7ffff3b36100 <bpf_module_create_c_from_string(char const*, unsigned int, char const**, int)>, flags=<optimised out>) at ./Modules/_ctypes/callproc.c:841
#13 _ctypes_callproc () at ./Modules/_ctypes/callproc.c:1184

(gdb) frame 9; call (void)puts(text)

#include <uapi/linux/ptrace.h>
#include <linux/sched.h>
#include <linux/fs.h>

#define MAXARG 20
#define ARGSIZE 128

enum event_type {
    EVENT_ARG,
    EVENT_RET,
};

struct data_t {
    u32 pid; // PID as in the userspace term (i.e. task->tgid in kernel)
    char comm[TASK_COMM_LEN];
    enum event_type type;
    char argv[ARGSIZE];
    int retval;
};

BPF_PERF_OUTPUT(events);

static int __submit_arg(struct pt_regs *ctx, void *ptr, struct data_t *data)
{
    bpf_probe_read(data->argv, sizeof(data->argv), ptr);
    events.perf_submit(ctx, data, sizeof(struct data_t));
    return 1;
}

static int submit_arg(struct pt_regs *ctx, void *ptr, struct data_t *data)
{
    const char *argp = NULL;
    bpf_probe_read(&argp, sizeof(argp), ptr);
    if (argp) {
        return __submit_arg(ctx, (void *)(argp), data);
    }
    return 0;
}

int kprobe__sys_execve(struct pt_regs *ctx, struct filename *filename,
    const char __user *const __user *__argv,
    const char __user *const __user *__envp)
{
    // create data here and pass to submit_arg to save stack space (#555)
    struct data_t data = {};
    data.pid = bpf_get_current_pid_tgid() >> 32;
    bpf_get_current_comm(&data.comm, sizeof(data.comm));
    data.type = EVENT_ARG;

    __submit_arg(ctx, (void *)filename, &data);

    int i = 1; // skip first arg, as we submitted filename

    // unrolled loop to walk argv[] (MAXARG)
    if (submit_arg(ctx, (void *)&__argv[i], &data) == 0) goto out; i++;
    if (submit_arg(ctx, (void *)&__argv[i], &data) == 0) goto out; i++;
    if (submit_arg(ctx, (void *)&__argv[i], &data) == 0) goto out; i++;
    if (submit_arg(ctx, (void *)&__argv[i], &data) == 0) goto out; i++;
    if (submit_arg(ctx, (void *)&__argv[i], &data) == 0) goto out; i++;
    if (submit_arg(ctx, (void *)&__argv[i], &data) == 0) goto out; i++;
    if (submit_arg(ctx, (void *)&__argv[i], &data) == 0) goto out; i++;
    if (submit_arg(ctx, (void *)&__argv[i], &data) == 0) goto out; i++;
    if (submit_arg(ctx, (void *)&__argv[i], &data) == 0) goto out; i++; // X
    if (submit_arg(ctx, (void *)&__argv[i], &data) == 0) goto out; i++;
    if (submit_arg(ctx, (void *)&__argv[i], &data) == 0) goto out; i++;
    if (submit_arg(ctx, (void *)&__argv[i], &data) == 0) goto out; i++;
    if (submit_arg(ctx, (void *)&__argv[i], &data) == 0) goto out; i++;
    if (submit_arg(ctx, (void *)&__argv[i], &data) == 0) goto out; i++;
    if (submit_arg(ctx, (void *)&__argv[i], &data) == 0) goto out; i++;
    if (submit_arg(ctx, (void *)&__argv[i], &data) == 0) goto out; i++;
    if (submit_arg(ctx, (void *)&__argv[i], &data) == 0) goto out; i++;
    if (submit_arg(ctx, (void *)&__argv[i], &data) == 0) goto out; i++;
    if (submit_arg(ctx, (void *)&__argv[i], &data) == 0) goto out; i++; // XX

    // handle truncated argument list
    char ellipsis[] = "...";
    __submit_arg(ctx, (void *)ellipsis, &data);
out:
    return 0;
}

int kretprobe__sys_execve(struct pt_regs *ctx)
{
    struct data_t data = {};
    data.pid = bpf_get_current_pid_tgid() >> 32;
    bpf_get_current_comm(&data.comm, sizeof(data.comm));
    data.type = EVENT_RET;
    data.retval = PT_REGS_RC(ctx);
    events.perf_submit(ctx, &data, sizeof(data));

    return 0;
}

ProblemType: Bug
DistroRelease: Ubuntu 17.10
Package: bpfcc-tools 0.3.0-1ubuntu1
ProcVersionSignature: Ubuntu 4.13.0-32.35-generic 4.13.13
Uname: Linux 4.13.0-32-generic x86_64
NonfreeKernelModules: nvidia_uvm nvidia_drm nvidia_modeset nvidia
ApportVersion: 2.20.7-0ubuntu3.7
Architecture: amd64
Date: Thu Feb 8 11:52:40 2018
PackageArchitecture: all
SourcePackage: bpfcc
UpgradeStatus: Upgraded to artful on 2017-09-12 (148 days ago)

Revision history for this message
Chris West (faux) wrote :
To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.