Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

kprobe+eBPF tracing as an event source #5218

Closed
akindyakov opened this issue Sep 14, 2018 · 3 comments
Closed

kprobe+eBPF tracing as an event source #5218

akindyakov opened this issue Sep 14, 2018 · 3 comments
Assignees
Labels
blueprint Blueprints. For details see CONTRIBUTING.md. Linux

Comments

@akindyakov
Copy link
Contributor

Blueprint

To extend the type of information receiving from systems I'd like to propose the new way to get information about system events on Linux.

Existing mechanism

osquery already has event collection system for linux based on Linux Auditing System. It provides a lot of extremely useful information. However auditd has some well known limits by design.

Restrictions of auditd

The main constraint is a notable performance penalty. Audit information is received from the system via unix socket in text form. Which means kernel waste CPU resources to create those strings and filter them. osquery in it's turn has to parse them. Sounds ridiculous but in the scale of system events it has a big performance issue on high load systems.

Suggested solution

The possible substitution could be to use kprobes / kretprobes with eBPF to fetch intended data in kernel mode. With kprobe we could watch and trace almost any syscall with arguments, return values and some contexts like PID and TID of the caller.

Performance hit

I did the rough test to compare the system performance hit of considerable mechanisms: current osquery system event collection mechanism (aka auditd), kprobe watching every open syscall in the system. Both systems can trace the system call open, so I did a small binary which is open and close a file many times. Run it with auditd and with kprobe, also run it without anything to compare (etalon run).

parameter etalon kprobe auditd
samples 13 13 14
average system time, s 1.54 2.71 (+76%) 6.23 (+304%)
min system time, s 1.46 2.59 (+77%) 6.06 (+315%)
variance system time, s 2.50 7.60 39.21

Performance hit for kprobe is notable lower than for auditd, thereby using kprobe can probably help us to reduce performance hit of system event recording mechanism.

Implementation plan

  • Implement elementary wrapping eBPF structures such as maps, progs, output points based on perf events
  • Implement kprobe managing code to connect it to eBPF program
  • Implement on top of two previous parts event source for execve
  • Create instruments to produce eBPF bytecode for any other system events
@akindyakov akindyakov added Linux blueprint Blueprints. For details see CONTRIBUTING.md. labels Sep 14, 2018
@akindyakov akindyakov self-assigned this Sep 14, 2018
akindyakov added a commit to akindyakov/osquery that referenced this issue Sep 14, 2018
  - Platform dependent `perf_event_open` and `bpf` syscalls definitions
  - `isSupportedBySystem` function definition to determine if current system supports required eBPF features

Issue: osquery#5218
akindyakov added a commit to akindyakov/osquery that referenced this issue Jan 15, 2019
Summary:
eBPF system call osquery wrapper with Expected as a return value and function to check if functionality is supported by current kernel.

Blueprint: [osquery#5218](osquery#5218)

Reviewed By: mkareta

Differential Revision: D13607442

fbshipit-source-id: 33103c704f760e569f21a6b322d7358d61cfbd55
akindyakov added a commit to akindyakov/osquery that referenced this issue Jan 15, 2019
Summary:
C++ wrapper to load and keep track of eBPF program in order to close if afterwards.

Blueprint: [osquery#5218](osquery#5218)

Reviewed By: guliashvili

Differential Revision: D13609628

fbshipit-source-id: 59a7ac3669018087cf15029ddb43a0786f75fc51
akindyakov added a commit to akindyakov/osquery that referenced this issue Jan 15, 2019
Summary:
To make the process of interacting with eBPF map structure more clear

Blueprint: [osquery#5218](osquery#5218)

Reviewed By: guliashvili

Differential Revision: D13608479

fbshipit-source-id: d31d2c4e277ea9f37b41246a1a5176c98098957d
akindyakov added a commit to akindyakov/osquery that referenced this issue Jan 16, 2019
)

Summary:
Pull Request resolved: osquery#5354

eBPF system call osquery wrapper with Expected as a return value and function to check if functionality is supported by current kernel.

Blueprint: [osquery#5218](osquery#5218)

Reviewed By: mkareta

Differential Revision: D13607442

fbshipit-source-id: 270a2f7c51c2cb8d6c3ecc6fd070b4a173093656
akindyakov added a commit to akindyakov/osquery that referenced this issue Jan 16, 2019
Summary:
Pull Request resolved: osquery#5355

C++ wrapper to load and keep track of eBPF program in order to close if afterwards.

Blueprint: [osquery#5218](osquery#5218)

Reviewed By: guliashvili

Differential Revision: D13609628

fbshipit-source-id: 536d908da8f9a55961aee4e04864d2c1da704f3d
akindyakov added a commit to akindyakov/osquery that referenced this issue Jan 16, 2019
Summary:
Pull Request resolved: osquery#5356

To make the process of interacting with eBPF map structure more clear

Blueprint: [osquery#5218](osquery#5218)

Reviewed By: guliashvili

Differential Revision: D13608479

fbshipit-source-id: 03a1d5b0fd8f254ddd4cd0644e4672d4e53cc309
@akindyakov
Copy link
Contributor Author

Implementation details of eBPF based event collection from linux kernel

The good new is the osquery lockdown is almost over, therefore I resume work on the new event source for the osquery on Linux. This is short term plan to have it done. Feel free to comment it or ask a questions. And also to comment coming PRs about topic.

host_based_event_chains_impl_arch

Definitions:

  • The arrows on the picture are to show data (events) flow.
  • The "3d" boxes are for the osquery classes.
  • And the ovals are for the linux kernel constructs which osquery use to retrieve event information.

On Linux since v4 we have direct access to the class of native tracing events in order to collect them in userspace. There is a set of Linux tracing event (see /sys/kernel/debug/tracing/events) which we can use to track syscalls, net connections and other things. To use them we should know the data format of the event (file format in event directory) and id number (file id). Also, the event should be enabled in kernel configuration and switched on by writing 1 to a file enabled. To make it easy to handle tracing events there is an osquery class tracing::NativeEvent.

To parse event and retrieve some context like PID, UID of the process caused the event eBPF program can be attached to the event by Linux performance monitoring mechanism (perf_event_open()). An osquery class was made to do it from cpp code: events::EbpfTracepoint. To load eBPF program the class ebpf::Program was made. The output of eBPF program could be received in userspace by Linux performance monitoring mechanism set up for every active CPU core (ebpf::PerfOutput). To find out to which perv channel program should write there is an eBPF map was made (ebpf::Map) to define a mapping from the CPU core number to file descriptor of the perf channel. Also to be able to read from the set of ebpf::PerfOutput file descriptors the ebpf::PerfOutputsPoll class was made.

For now, the main goal is to track syscalls from the kernel. We gonna start with kill (program code: events::genLinuxKillEnterProgram) and setuid (program code: events::genLinuxKillEnterProgram). Unfortunately the event of entering to a syscall and event of returning from it comes separately. They have to be joined. There are two main approaches to do it: in the kernel space by eBPF programs and in userspace. I chose the second one in order to keep eBPF programs small and lightweight and the number of eBPF structs less (in in-kernel approach one additional ebpf map is required for every syscall). To parse and receive "exit" events in user space there is an eBPF program: events::genLinuxExitProgram. It is exactly the same byte code for all exit events besides the code of the watching syscall. And of course, there is gonna be a matching class to quickly join exit and enter events to one syscall event.

This event is gonna be yet another event producer in new event framework from @fmanco.

facebook-github-bot pushed a commit that referenced this issue Jan 18, 2019
Summary:
Pull Request resolved: #5354

eBPF system call osquery wrapper with Expected as a return value and function to check if functionality is supported by current kernel.

Blueprint: [#5218](#5218)

Reviewed By: mkareta

Differential Revision: D13607442

fbshipit-source-id: 58be84a86aba3fe5e33ca5ab15418976fd36107c
facebook-github-bot pushed a commit that referenced this issue Jan 18, 2019
Summary:
Pull Request resolved: #5356

To make the process of interacting with eBPF map structure more clear

Blueprint: [#5218](#5218)

Reviewed By: guliashvili

Differential Revision: D13608479

fbshipit-source-id: cffe76883c280a947da12641b7db6824a571ab1e
facebook-github-bot pushed a commit that referenced this issue Jan 18, 2019
Summary:
Pull Request resolved: #5355

C++ wrapper to load and keep track of eBPF program in order to close if afterwards.

Blueprint: [#5218](#5218)

Reviewed By: guliashvili

Differential Revision: D13609628

fbshipit-source-id: dd4ecb547a37c7d83753249e156b0d2c56194ec0
akindyakov added a commit to akindyakov/osquery that referenced this issue Jan 18, 2019
Summary:
Handler to enable event with certain type, get an id of the event and make sure it will be disables afterwards.

Part of a linux `syscalls` tracing system, blueprint: [osquery#5218](osquery#5218)

Reviewed By: mkareta

Differential Revision: D13621388

fbshipit-source-id: c22c67e29a0edb2ba368e68ce3c41488835fc97f
facebook-github-bot pushed a commit that referenced this issue Jan 21, 2019
Summary:
Pull Request resolved: #5370

Handler to enable event with certain type, get an id of the event and make sure it will be disables afterwards.

Part of a linux `syscalls` tracing system, blueprint: [#5218](#5218)

Reviewed By: mkareta

Differential Revision: D13621388

fbshipit-source-id: 8adfbe3cc1d87f70538851c5036eae51c93bede8
akindyakov added a commit to akindyakov/osquery that referenced this issue Jan 21, 2019
Summary: Part of a linux `syscalls` tracing system, blueprint: [osquery#5218](osquery#5218)

Reviewed By: mkareta

Differential Revision: D13622579

fbshipit-source-id: 43e6f3c9b6e43882d817799b6a43390d10862e83
facebook-github-bot pushed a commit that referenced this issue Jan 22, 2019
Summary:
Pull Request resolved: #5374

Part of a linux `syscalls` tracing system, blueprint: [#5218](#5218)

Reviewed By: mkareta

Differential Revision: D13622579

fbshipit-source-id: d88b49d785e532b0dbcc42d9245bfee2a9209145
akindyakov added a commit to akindyakov/osquery that referenced this issue Jan 22, 2019
…vent

Summary: Part of a linux `syscalls` tracing system, blueprint: [osquery#5218](osquery#5218)

Differential Revision: D13622999

fbshipit-source-id: 8bb9d11dce9bbd71100a8a4f15797d7a69957c71
akindyakov added a commit to akindyakov/osquery that referenced this issue Jan 22, 2019
…vent

Summary: Part of a linux `syscalls` tracing system, blueprint: [osquery#5218](osquery#5218)

Differential Revision: D13622999

fbshipit-source-id: 1e673cd7bafcd7d77b1bfe35866c05a379f4d5b0
akindyakov added a commit to akindyakov/osquery that referenced this issue Jan 22, 2019
Summary: Part of a linux  tracing system, blueprint: [osquery#5218](osquery#5218)

Differential Revision: D13654124

fbshipit-source-id: c1f2b9fe6059f1bcb7f6d48b89e162974460a3ea
muffins pushed a commit to muffins/osquery that referenced this issue Feb 1, 2019
Summary:
Pull Request resolved: osquery#5356

To make the process of interacting with eBPF map structure more clear

Blueprint: [osquery#5218](osquery#5218)

Reviewed By: guliashvili

Differential Revision: D13608479

fbshipit-source-id: cffe76883c280a947da12641b7db6824a571ab1e
muffins pushed a commit to muffins/osquery that referenced this issue Feb 1, 2019
Summary:
Pull Request resolved: osquery#5355

C++ wrapper to load and keep track of eBPF program in order to close if afterwards.

Blueprint: [osquery#5218](osquery#5218)

Reviewed By: guliashvili

Differential Revision: D13609628

fbshipit-source-id: dd4ecb547a37c7d83753249e156b0d2c56194ec0
muffins pushed a commit to muffins/osquery that referenced this issue Feb 1, 2019
Summary:
Pull Request resolved: osquery#5370

Handler to enable event with certain type, get an id of the event and make sure it will be disables afterwards.

Part of a linux `syscalls` tracing system, blueprint: [osquery#5218](osquery#5218)

Reviewed By: mkareta

Differential Revision: D13621388

fbshipit-source-id: 8adfbe3cc1d87f70538851c5036eae51c93bede8
muffins pushed a commit to muffins/osquery that referenced this issue Feb 1, 2019
Summary:
Pull Request resolved: osquery#5374

Part of a linux `syscalls` tracing system, blueprint: [osquery#5218](osquery#5218)

Reviewed By: mkareta

Differential Revision: D13622579

fbshipit-source-id: d88b49d785e532b0dbcc42d9245bfee2a9209145
muffins pushed a commit to muffins/osquery that referenced this issue Feb 1, 2019
…vent (osquery#5384)

Summary:
Pull Request resolved: osquery#5384

Part of a linux `syscalls` tracing system, blueprint: [osquery#5218](osquery#5218)

Reviewed By: guliashvili

Differential Revision: D13622999

fbshipit-source-id: 905bbb3a3763fdd6fbe2ba5211f091184275f246
muffins pushed a commit to muffins/osquery that referenced this issue Feb 1, 2019
Summary:
Pull Request resolved: osquery#5386

 Part of a linux  tracing system, blueprint: [osquery#5218](osquery#5218)

Reviewed By: SAlexandru

Differential Revision: D13654124

fbshipit-source-id: 8db63e584bd772132c1ba1c80853c60613e8036a
muffins pushed a commit to muffins/osquery that referenced this issue Feb 1, 2019
Summary:
Pull Request resolved: osquery#5403

Part of a linux  tracing system, blueprint: [osquery#5218](osquery#5218)

Reviewed By: SAlexandru

Differential Revision: D13690684

fbshipit-source-id: 039fc89929de49fcc7bd2287a98ffc68450fcada
muffins pushed a commit to muffins/osquery that referenced this issue Feb 1, 2019
Summary:
Pull Request resolved: osquery#5403

Part of a linux  tracing system, blueprint: [osquery#5218](osquery#5218)

Reviewed By: SAlexandru

Differential Revision: D13690684

fbshipit-source-id: 039fc89929de49fcc7bd2287a98ffc68450fcada
muffins pushed a commit to muffins/osquery that referenced this issue Feb 1, 2019
Summary:
Pull Request resolved: osquery#5403

Part of a linux  tracing system, blueprint: [osquery#5218](osquery#5218)

Reviewed By: SAlexandru

Differential Revision: D13690684

fbshipit-source-id: 039fc89929de49fcc7bd2287a98ffc68450fcada
akindyakov added a commit to akindyakov/osquery that referenced this issue Feb 4, 2019
Summary: Part of a linux  tracing system, blueprint: [osquery#5218](osquery#5218)

Reviewed By: SAlexandru

Differential Revision: D13669863

fbshipit-source-id: ca07e625d3a5a64effb227dcdf583aad7b98560f
akindyakov added a commit to akindyakov/osquery that referenced this issue Feb 4, 2019
Summary: Part of a linux  tracing system, blueprint: [osquery#5218](osquery#5218)

Differential Revision: D13669863

fbshipit-source-id: e6b400c258616edf8da725cf5c398556af660810
akindyakov added a commit to akindyakov/osquery that referenced this issue Feb 4, 2019
Summary:
To able to invert type from enter to exit and determine if type is exit or enter.

Part of a linux  tracing system, blueprint: [osquery#5218](osquery#5218)

Reviewed By: SAlexandru

Differential Revision: D13761673

fbshipit-source-id: 88920888dc2fb7cf050b1141480752aded692676
facebook-github-bot pushed a commit that referenced this issue Feb 4, 2019
Summary:
Pull Request resolved: #5415

Part of a linux  tracing system, blueprint: [#5218](#5218)

Reviewed By: SAlexandru

Differential Revision: D13669863

fbshipit-source-id: aadd14734cdc3586526be59f76f3176fa981a57f
facebook-github-bot pushed a commit that referenced this issue Feb 4, 2019
…5416)

Summary:
Pull Request resolved: #5416

To able to invert type from enter to exit and determine if type is exit or enter.

Part of a linux  tracing system, blueprint: [#5218](#5218)

Reviewed By: SAlexandru

Differential Revision: D13761673

fbshipit-source-id: 2bf668219fd996d9d5b67e0e1ccf5c1161a41481
akindyakov added a commit to akindyakov/osquery that referenced this issue Feb 4, 2019
Summary:
Hash multimap based joiner with ability to perform clean up old unpaired events from time to time.

Part of a linux  tracing system, blueprint: [osquery#5218](osquery#5218)

Reviewed By: SAlexandru

Differential Revision: D13761675

fbshipit-source-id: 8be920f2059ead508c5530a4f427db130b7e826c
akindyakov added a commit to akindyakov/osquery that referenced this issue Feb 4, 2019
Summary: Part of a linux  tracing system, blueprint: [osquery#5218](osquery#5218)

Reviewed By: SAlexandru

Differential Revision: D13787759

fbshipit-source-id: 726075e04474b4148c0292d6e9e8f10cf60b9214
akindyakov added a commit to akindyakov/osquery that referenced this issue Feb 5, 2019
Summary: Part of a linux  tracing system, blueprint: [osquery#5218](osquery#5218)

Differential Revision: D13787759

fbshipit-source-id: 2758f4fb385d65c2d85d8bae96b0e69531b620ae
facebook-github-bot pushed a commit that referenced this issue Feb 5, 2019
Summary:
Pull Request resolved: #5417

Hash multimap based joiner with ability to perform clean up old unpaired events from time to time.

Part of a linux  tracing system, blueprint: [#5218](#5218)

Reviewed By: SAlexandru

Differential Revision: D13761675

fbshipit-source-id: f4b17cbeed495b2a9e6616a005f001963849875e
facebook-github-bot pushed a commit that referenced this issue Feb 5, 2019
…5418)

Summary:
Pull Request resolved: #5418

Part of a linux  tracing system, blueprint: [#5218](#5218)

Reviewed By: SAlexandru

Differential Revision: D13787759

fbshipit-source-id: 35bb4b41f7cebfeb91aa848a1583c9eae3e2a363
akindyakov added a commit to akindyakov/osquery that referenced this issue Feb 11, 2019
…class

Summary:
This is a final diff to be able to track syscalls by using eBPF + kernel events. Basically that one and previous are about to join high level initialisation routine in one place.

Part of a linux  tracing system, blueprint: [osquery#5218](osquery#5218)

Reviewed By: SAlexandru

Differential Revision: D13801093

fbshipit-source-id: d9f09aabe0055aa43c44fb57ad9cd9b3952da4f8
facebook-github-bot pushed a commit that referenced this issue Feb 13, 2019
…class (#5428)

Summary:
Pull Request resolved: #5428

This is a final diff to be able to track syscalls by using eBPF + kernel events. Basically that one and previous are about to join high level initialisation routine in one place.

Part of a linux  tracing system, blueprint: [#5218](#5218)

Reviewed By: SAlexandru

Differential Revision: D13801093

fbshipit-source-id: db8503b0d42127281a975ff517600872e9ed4302
@mike-myers-tob
Copy link
Member

Related: #6571

@mike-myers-tob
Copy link
Member

Closing because we have retired this approach in Remove unused/experimental ebpf code in favor of the ebpfpub library approach and Alessandro's BPF-based socket and process events tables (#6571) that were released in 4.6.0.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
blueprint Blueprints. For details see CONTRIBUTING.md. Linux
Projects
None yet
Development

No branches or pull requests

2 participants