arvos-dev / arvos

AI- and Risk-based Vulnerability Management for Trustworthy Open Source Adoption (ARVOS)
Apache License 2.0
8 stars 1 forks source link

Display Call Stack on a vulnerability match #15

Closed emilwareus closed 2 years ago

emilwareus commented 2 years ago

To make it easier for users to understand how they can resolve the problem, and how it affects them we should display the call stack of the VF-call.

moule3053 commented 2 years ago

First, I tried to get the stack traces using eBPF. However, this approach requires additional symbols to be generated using tools like perf-map-agent, perf and jmaps. Plus, it requires the application's container to run in privileged mode for perf to work. But even with all this, the stack traces are not full and very useful as they don't indicate the line numbers to the source code of the called libraries. Here is an example of stack trace with this approach.

reactor-http-ep   267 [005]  2456.743290:   14364333 cycles: 
    ffffffff9ccee5db __fget+0x3b ([kernel.kallsyms])
    ffffffff9ccee8e7 __fget_light+0x57 ([kernel.kallsyms])
    ffffffff9ccee913 __fdget+0x13 ([kernel.kallsyms])
    ffffffff9cd23887 do_epoll_wait+0x57 ([kernel.kallsyms])
    ffffffff9cd2391e __x64_sys_epoll_wait+0x1e ([kernel.kallsyms])
    ffffffff9ca03fd7 do_syscall_64+0x57 ([kernel.kallsyms])
    ffffffff9d60008c entry_SYSCALL_64_after_hwframe+0x44 ([kernel.kallsyms])
        7f78d06615ce epoll_wait+0x5e (/usr/lib/x86_64-linux-gnu/libc-2.31.so)
        7f78b90996b3 Lio/netty/channel/epoll/Native;::epollWait+0xf3 (/tmp/perf-7.map)
        7f78b91a958c Lio/netty/channel/epoll/Native;::epollWait+0x8c (/tmp/perf-7.map)
        7f78b91dfb08 Lio/netty/channel/epoll/Native;::epollWait+0x48 (/tmp/perf-7.map)
        7f78b91cd99c Lio/netty/channel/epoll/EpollEventLoop;::epollWaitNoTimerChange+0xbc (/tmp/perf-7.map)
        7f78b13bd4f2 Interpreter+0x8d2 (/tmp/perf-7.map)
        7f78b13bd3de Interpreter+0x7be (/tmp/perf-7.map)
        7f78b13bd842 Interpreter+0xc22 (/tmp/perf-7.map)
        7f78b13bd842 Interpreter+0xc22 (/tmp/perf-7.map)
        7f78b13bd842 Interpreter+0xc22 (/tmp/perf-7.map)
        7f78b13b4d4a call_stub+0xac (/tmp/perf-7.map)
        7f78cf19a644 JavaCalls::call_helper+0x504 (/jdk/lib/server/libjvm.so)
        7f78cf19aef4 JavaCalls::call_virtual+0x4b4 (/jdk/lib/server/libjvm.so)
        7f78cf19b350 JavaCalls::call_virtual+0x80 (/jdk/lib/server/libjvm.so)
        7f78cf30dcaf thread_entry+0x12f (/jdk/lib/server/libjvm.so)
        7f78cfcbede0 JavaThread::thread_main_inner+0x3e0 (/jdk/lib/server/libjvm.so)
        7f78cfcbf0be JavaThread::run+0x26e (/jdk/lib/server/libjvm.so)
        7f78cfcc67d4 Thread::call_run+0x104 (/jdk/lib/server/libjvm.so)
        7f78cf89b53c thread_native_entry+0x10c (/jdk/lib/server/libjvm.so)
        7f78d0503609 start_thread+0xd9 (/usr/lib/x86_64-linux-gnu/libpthread-2.31.so)

Instead, I added a script that gets the stack trace using jstack in the base Docker image for Java applications https://hub.docker.com/r/moule3053/jdk-docker-jstack. jstack seems to get the stack traces for most of the symbols with line numbers to the source code of the called libraries. Here is an example of a stack trace with jstack.

"reactor-http-epoll-3" #238 daemon prio=5 os_prio=0 cpu=9157.83ms elapsed=207.86s tid=0x00007f3cdc064620 nid=255 runnable  [0x00007f3d10cd2000]
   java.lang.Thread.State: RUNNABLE
Thread: 0x00007f3cdc064620  [0xff] State: _at_safepoint _at_poll_safepoint 0
   JavaThread state: _thread_in_native
    at io.netty.channel.epoll.Native.epollWait(Native Method)
    at io.netty.channel.epoll.Native.epollWait(Native.java:148)
    at io.netty.channel.epoll.Native.epollWait(Native.java:141)
    at io.netty.channel.epoll.EpollEventLoop.epollWaitNoTimerChange(EpollEventLoop.java:290)
    at io.netty.channel.epoll.EpollEventLoop.run(EpollEventLoop.java:347)
    at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:989)
    at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74)
    at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
    at java.lang.Thread.run(java.base@18-internal/Thread.java:833)
moule3053 commented 2 years ago

Also added to arvos-poc the ability to display the stack traces related to an invoked symbol. Take a look at https://github.com/arvos-dev/arvos/commit/4dd7b234960e47661c972677590f1049ac5a2552

cristiklein commented 2 years ago

This works and was really nicely demoed. We only need to check if we actually manage to check all stack traces.