<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Falco – Syscalls</title><link>https://v0-43--falcosecurity.netlify.app/tags/syscalls/</link><description>Recent content in Syscalls on Falco</description><generator>Hugo -- gohugo.io</generator><language>en</language><lastBuildDate>Fri, 06 Oct 2023 00:00:00 +0000</lastBuildDate><atom:link href="https://v0-43--falcosecurity.netlify.app/tags/syscalls/feed.xml" rel="self" type="application/rss+xml"/><item><title>Blog: Tracing System Calls Using eBPF - Part 2</title><link>https://v0-43--falcosecurity.netlify.app/blog/tracing-system-calls-using-ebpf-part-2/</link><pubDate>Fri, 06 Oct 2023 00:00:00 +0000</pubDate><guid>https://v0-43--falcosecurity.netlify.app/blog/tracing-system-calls-using-ebpf-part-2/</guid><description>
&lt;h2 id="introduction"&gt;Introduction&lt;/h2&gt;
&lt;p&gt;In &lt;a href="https://falco.org/blog/tracing-syscalls-using-ebpf-part-1/"&gt;Tracing System Calls Using eBPF Part 1&lt;/a&gt;, we lay the groundwork, introducing you to the fundamentals of &lt;code&gt;eBPF&lt;/code&gt; and its predecessor, &lt;code&gt;BPF (Berkeley Packet Filter)&lt;/code&gt;. We delve into the evolution of this technology, its safety, performance, and observability advantages over traditional kernel modules, and its pivotal role in securing modern cloud native environments. We guide you through the intricate process of working with eBPF programs, from compilation to execution, highlighting its power in tracing system calls.&lt;/p&gt;
&lt;p&gt;In the second installment, &lt;code&gt;Tracing System Calls Using eBPF Part 2&lt;/code&gt;, we elevate our understanding of eBPF's capabilities. We unravel the world of &lt;code&gt;Uprobes&lt;/code&gt; and &lt;code&gt;Uretprobes&lt;/code&gt;, demonstrating how these features empower developers to instrument and monitor user-space applications seamlessly. We then venture into &lt;code&gt;Kprobes&lt;/code&gt; and &lt;code&gt;Kretprobes&lt;/code&gt;, unlocking the potential to dynamically trace and debug kernel functions, offering insights into system behavior and performance analysis.&lt;/p&gt;
&lt;h2 id="uprobes"&gt;Uprobes&lt;/h2&gt;
&lt;p&gt;Uprobes, short for user probes, are a feature in the Linux kernel that enables developers to instrument and monitor user-space applications without modifying their code directly. They allow for the insertion of breakpoints at specific points of interest within an application, facilitating the collection of data, tracing of function calls, debugging, and performance analysis.&lt;/p&gt;
&lt;h2 id="uretprobes"&gt;Uretprobes&lt;/h2&gt;
&lt;p&gt;Uretprobes, short for User Return Probes, are a feature in the Linux kernel that allows developers to trace and monitor the return paths of functions in user-space applications. While uprobes are used to instrument and intercept the entry points of functions, URETprobes specifically focus on the exit points or return paths. They enable developers to set up probes that are triggered when a specific function returns to its caller.&lt;/p&gt;
&lt;p&gt;Here is an eBPF program that uses user probes to trace the printf function present in &lt;code&gt;glibc (the standard GNU C Library)&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;br&gt;&lt;a target="_blank" href="images/ebpf2-01.png"&gt;
&lt;img style="border: 2px solid #00b4c8"
alt="An eBPF program that uses user probes to trace the printf function present in `glibc (the standard GNU C Library)`"
src="images/ebpf2-01.png"&gt;
&lt;/img&gt;
&lt;/a&gt;&lt;br&gt;&lt;br&gt;&lt;/p&gt;
&lt;p&gt;In accordance with the instructions outlined in our &lt;a href="https://falco.org/blog/tracing-syscalls-using-ebpf-part-1/"&gt;Tracing System Calls Using eBPF Part 1&lt;/a&gt; blog, we can create a loader to effectively load this eBPF program and read the logs from the file &lt;code&gt;/sys/kernel/tracing/trace_pipe&lt;/code&gt; .&lt;/p&gt;
&lt;h2 id="kprobes"&gt;Kprobes&lt;/h2&gt;
&lt;p&gt;Kprobes, short for Kernel Probes, are a feature in the Linux kernel that allow dynamic tracing and debugging of kernel functions. They are particularly useful for tasks like performance analysis, bug diagnosis, and system monitoring. They provide a non-intrusive way to gather runtime information from the kernel without requiring modifications to the kernel code itself. Additionally, they can be used to trace specific function calls, track parameters and return values, and gather statistical data on function execution&lt;/p&gt;
&lt;h2 id="kretprobes"&gt;Kretprobes&lt;/h2&gt;
&lt;p&gt;Kretprobes, short for Kernel Return Probes, are a feature in the Linux kernel that complements Kprobes by allowing dynamic tracing and debugging of kernel function return points. While Kprobes focus on probing the entry points of kernel functions, kretprobes specifically target the return points of these functions.Similar to Kprobes, kretprobes work by inserting a probe handler function that gets executed when a specific kernel function is about to return. This allows developers and system administrators to gather information, modify return values, or perform additional actions at the point of function return.&lt;/p&gt;
&lt;p&gt;Here is an eBPF program that uses kernel probes to trace a kernel function named &lt;code&gt;prepare_kernel_cred&lt;/code&gt;. This function is used to create a new &lt;code&gt;struct cred object&lt;/code&gt; that represents the credentials or privileges associated with a kernel task. It is commonly used in &lt;code&gt;privilege escalation exploits&lt;/code&gt; for gaining root access. By tracing this function, we can identify all processes that invoke it, providing valuable insight for analyzing potential malicious activity.&lt;/p&gt;
&lt;p&gt;&lt;br&gt;&lt;a target="_blank" href="images/ebpf2-02.png"&gt;
&lt;img style="border: 2px solid #00b4c8"
alt="An eBPF program that uses kernel probes to trace a kernel function"
src="images/ebpf2-02.png"&gt;
&lt;/img&gt;
&lt;/a&gt;&lt;br&gt;&lt;br&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;SEC(“kprobe/prepare_kernel_cred”)&lt;/code&gt; indicates that an eBPF program is associated with the kprobe event for the &lt;code&gt;&amp;quot;prepare_kernel_cred&amp;quot;&lt;/code&gt; kernel function. This event allows dynamic tracing and debugging by intercepting the entry point of the function.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;struct pt_regs&lt;/code&gt; is a data structure that provides access to the register state of the program when it is executed. It contains information about the &lt;code&gt;CPU registers&lt;/code&gt; at the time of the eBPF program invocation. It is defined as :&lt;/p&gt;
&lt;p&gt;&lt;br&gt;&lt;a target="_blank" href="images/ebpf2-03.png"&gt;
&lt;img style="border: 2px solid #00b4c8"
alt="Consolidated rule"
src="images/ebpf2-03.png"&gt;
&lt;/img&gt;
&lt;/a&gt;&lt;br&gt;&lt;br&gt;&lt;/p&gt;
&lt;p&gt;To facilitate the loading of the aforementioned eBPF program, we’ll use the following program.&lt;/p&gt;
&lt;p&gt;&lt;br&gt;&lt;a target="_blank" href="images/ebpf2-04.png"&gt;
&lt;img style="border: 2px solid #00b4c8"
alt="Loader for the above program"
src="images/ebpf2-04.png"&gt;
&lt;/img&gt;
&lt;/a&gt;&lt;br&gt;&lt;br&gt;&lt;/p&gt;
&lt;p&gt;Here is a Makefile for compiling the eBPF program and the loader&lt;/p&gt;
&lt;p&gt;&lt;br&gt;&lt;a target="_blank" href="images/ebpf2-05.png"&gt;
&lt;img style="border: 2px solid #00b4c8"
alt="A Makefile for compiling the eBPF program and the loader"
src="images/ebpf2-05.png"&gt;
&lt;/img&gt;
&lt;/a&gt;&lt;br&gt;&lt;br&gt;&lt;/p&gt;
&lt;h2 id="conclusion"&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;In this two-part exploration of &lt;strong&gt;Tracing System Calls Using eBPF&lt;/strong&gt;, we've embarked on a fascinating journey through the inner workings of this powerful technology. &lt;code&gt;Part 1&lt;/code&gt; laid the foundation by introducing us to the fundamentals of eBPF and its predecessor, BPF, shedding light on their evolution and significance in modern cloud native environments. We uncovered how eBPF's safety, performance, and observability advantages empower us to trace system calls with unmatched efficiency.&lt;/p&gt;
&lt;p&gt;In &lt;code&gt;Part 2&lt;/code&gt;, we took our understanding to new heights. We delved into the world of &lt;code&gt;Uprobes&lt;/code&gt; and &lt;code&gt;Uretprobes&lt;/code&gt;, showcasing how they enable seamless instrumentation and monitoring of user-space applications. We then ventured into &lt;code&gt;Kprobes&lt;/code&gt; and &lt;code&gt;Kretprobes&lt;/code&gt;, unlocking the ability to dynamically trace and debug kernel functions. Armed with these advanced techniques, we gained valuable insights into system behavior, performance analysis, and even the detection of potential malicious activity.&lt;/p&gt;
&lt;p&gt;As we conclude this journey into the heart of eBPF, we stand equipped with a powerful set of tools and knowledge. Whether you're a seasoned sysadmin, a curious developer, or a vigilant security enthusiast, the capabilities of eBPF open new doors to real-time monitoring and analysis.&lt;/p&gt;
&lt;p&gt;Stay tuned for further insights and practical guidance in the world of eBPF, where innovation meets security, and the future of system monitoring becomes a reality.&lt;/p&gt;</description></item><item><title>Blog: Tracing System Calls Using eBPF - Part 1</title><link>https://v0-43--falcosecurity.netlify.app/blog/tracing-syscalls-using-ebpf-part-1/</link><pubDate>Mon, 11 Sep 2023 00:00:00 +0000</pubDate><guid>https://v0-43--falcosecurity.netlify.app/blog/tracing-syscalls-using-ebpf-part-1/</guid><description>
&lt;h2 id="introduction"&gt;Introduction:&lt;/h2&gt;
&lt;p&gt;In this article, we will delve into the details of eBPF (extended Berkeley Packet Filter) and explore its significance in tracing system calls. This particular blog will be in two parts; in the first blog, we will discuss eBPF, and in the subsequent section, we will delve into probes. eBPF is a powerful technology that allows for the dynamic and efficient tracing of events within the kernel space of an operating system. You have probably heard of the acronyms BPF and eBPF being used interchangeably. That's why we will aim to address both BPF and eBPF before discussing how and why Falco uses this technology.&lt;/p&gt;
&lt;h2 id="bpf-berkeley-packet-filter"&gt;BPF (Berkeley Packet Filter)&lt;/h2&gt;
&lt;p&gt;BPF is a technology used for network packet filtering and analysis. It is a powerful tool for implementing network security features, such as firewalls and intrusion detection systems. It can also be used to examine network traffic in real-time, detect suspicious patterns, and take appropriate actions to protect the network.&lt;/p&gt;
&lt;h2 id="ebpf-extended-berkeley-packet-filter"&gt;eBPF (Extended Berkeley Packet Filter)&lt;/h2&gt;
&lt;p&gt;The Extended Berkeley Filter (eBPF) is an evolution of the original BPF technology. It extends the capabilities of BPF by providing a more powerful and flexible way to perform dynamic tracing, network analysis, and performance monitoring. It allows developers to write and load programs into the kernel which can be attached to various hooks and events in the system. These programs can provide real-time insights and control over system activities.&lt;/p&gt;
&lt;h2 id="working-on-an-ebpf-program"&gt;Working on an eBPF program&lt;/h2&gt;
&lt;p&gt;The process of compiling and running an eBPF program involves several steps:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;The eBPF program is converted into bytecode by using a compiler, ready to be loaded by a loader program.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The eBPF verifier checks the program for safety, correctness and adherence to specific rules and constraints. First of all, it performs a depth-first search on all possible execution paths to ensure that the program always proceeds to completion. Next, it performs a static analysis on the bytecode and ensures that the program doesn't violate memory access rules, and doesn't cause instability.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Once the eBPF program passes the verification process, it can be loaded into the kernel. The loader ensures that the program is securely loaded and attached to the desired hooks or targets in the system.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;At runtime, the eBPF bytecode is further optimised through JIT (Just-in-time) compilation. This step converts the eBPF bytecode into machine code that can be executed by the CPU.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="kernel-modules"&gt;Kernel Modules&lt;/h2&gt;
&lt;p&gt;Apart from eBPF, the other approach we previously discussed for process tracing in Linux is the use of kernel modules. Kernel modules allow developers to write custom code that can be loaded into the kernel to extend its functionality.&lt;/p&gt;
&lt;p&gt;By leveraging kernel modules, it is possible to hook into various points of the kernel's process management code and capture detailed information about process execution. This includes events such as process creation, termination, and context switches.&lt;/p&gt;
&lt;p&gt;By accessing the kernel's internal data structures and functions, the module can gather valuable insights such as process IDs, parent-child relationships, execution time, system calls, and more.&lt;/p&gt;
&lt;h2 id="so-why-does-falco-use-ebpf"&gt;So why does Falco use eBPF?&lt;/h2&gt;
&lt;p&gt;The integration of eBPF brings significant advantages to projects like Falco, empowering them to securely and efficiently monitor and analyze system calls in real-time. You might be wondering why eBPF is necessary when Falco already has real-time detection capabilities through its kprobe (kernel probe) that handles syscall events.&lt;/p&gt;
&lt;p&gt;One compelling reason for incorporating eBPF support is to enable Falco to seamlessly operate in modern cloud native environments, where the traditional kernel probe may encounter limitations or face restrictions imposed by the control plane nodes.&lt;/p&gt;
&lt;p&gt;By embracing eBPF, Falco ensures the continuity of its real-time detection capabilities in a secure manner, allowing for the prompt and accurate identification of security incidents, regardless of the underlying environment.&lt;/p&gt;
&lt;p&gt;Later in the article, we will delve into the various considerations surrounding the adoption of an eBPF probe for Falco, providing valuable insights for determining when it becomes advantageous to leverage this functionality.&lt;/p&gt;
&lt;h2 id="ebpf-programs-vs-kernel-modules"&gt;eBPF programs vs kernel modules&lt;/h2&gt;
&lt;h3 id="safety-and-isolation"&gt;Safety and Isolation&lt;/h3&gt;
&lt;p&gt;eBPF programs are subjected to a thorough verification process before they are loaded into the kernel. This step provides an extra layer of protection and helps prevent security vulnerabilities. In contrast, kernel modules have direct access to the kernel code, which can pose a threat to the system if not implemented correctly.&lt;/p&gt;
&lt;h3 id="performance"&gt;Performance&lt;/h3&gt;
&lt;p&gt;eBPF programs are JIT compiled into machine code, which significantly improves the performance. JIT compilation optimizes the program for the specific CPU architecture, enabling efficient execution. Despite all these efforts, an eBPF instrumentation will always cause a greater overhead in the system than a kernel module one, the reason is that in the kernel module instrumentation there are no calls to the BPF subsystem.&lt;/p&gt;
&lt;h3 id="observability-and-debugging"&gt;Observability and Debugging&lt;/h3&gt;
&lt;p&gt;eBPF provides powerful tracing and observability capabilities. eBPF programs can be attached to various events, such as network packets, system calls, or kernel functions, allowing detailed visibility into the system behaviour. This makes eBPF a valuable tool for debugging, performance analysis, and security monitoring. Kernel modules typically require more invasive and complex mechanisms for achieving similar observability.&lt;/p&gt;
&lt;h2 id="attaching-ebpf-programs-to-hooks-and-events"&gt;Attaching eBPF programs to hooks and events&lt;/h2&gt;
&lt;p&gt;There are various instrumentation points defined in the Linux kernel. An instrumentation is a specific point in a computer program where additional code, known as instrumentation code, is inserted to gather information about the program's execution. Instrumentation code can be injected at runtime using JIT compilation. Kernel probes, tracepoints, user-space probes, kretprobes are examples of instrumentation points.&lt;/p&gt;
&lt;p&gt;Here is an eBPF program that runs when the execve system call is made.&lt;/p&gt;
&lt;p&gt;&lt;br&gt;&lt;a target="_blank" href="images/ebpf-01.png"&gt;
&lt;img style="border: 2px solid #00b4c8"
alt="An eBPF program that runs when the execve system call is made"
src="images/ebpf-01.png"&gt;
&lt;/img&gt;
&lt;/a&gt;&lt;br&gt;&lt;br&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;In the eBPF programming context, the &lt;code&gt;macro SEC()&lt;/code&gt; from the &lt;code&gt;bpf/bpf_helper.h&lt;/code&gt; header file plays a crucial role. It allows the programmer to specify the section in which a function or variable will be placed within the &lt;code&gt;eBPF object file&lt;/code&gt;. This becomes essential when loading eBPF programs into the kernel using mechanisms like the &lt;code&gt;bpf() system call&lt;/code&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;By organizing functions and variables into named sections, the eBPF loader can efficiently locate and load the required code and data. Specifically, when dealing with tracepoint events, the &lt;code&gt;SEC&lt;/code&gt; format follows the pattern &lt;code&gt;SEC(&amp;quot;tp/&amp;lt;category&amp;gt;/&amp;lt;name&amp;gt;&amp;quot;)&lt;/code&gt;, where &lt;code&gt;&amp;lt;category&amp;gt;&lt;/code&gt; and &lt;code&gt;&amp;lt;name&amp;gt;&lt;/code&gt; represent the respective tracepoint category and event name.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;tp/syscalls/sys_enter_execve&lt;/code&gt; refers to a tracepoint that records when a process spawns the execve system call.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;A list of all the available tracepoints is present in the &lt;code&gt;/sys/kernel/debug/tracing/available_events&lt;/code&gt; file. The format for each line in the file is &lt;code&gt;&amp;lt;category&amp;gt;:&amp;lt;name&amp;gt;&lt;/code&gt;. For example, syscalls:sys_enter_execve.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Before compiling the program, we need to do some basic configuration:&lt;/p&gt;
&lt;p&gt;&lt;br&gt;&lt;a target="_blank" href="images/ebpf-02.png"&gt;
&lt;img style="border: 2px solid #00b4c8"
alt="Basic configurations."
src="images/ebpf-02.png"&gt;
&lt;/img&gt;
&lt;/a&gt;&lt;br&gt;&lt;br&gt;&lt;/p&gt;
&lt;p&gt;Let's compile the program.
The following command can be used to do this task:&lt;/p&gt;
&lt;p&gt;&lt;br&gt;&lt;a target="_blank" href="images/ebpf-03.png"&gt;
&lt;img style="border: 2px solid #00b4c8"
alt="Command to compile the program."
src="images/ebpf-03.png"&gt;
&lt;/img&gt;
&lt;/a&gt;&lt;br&gt;&lt;br&gt;&lt;/p&gt;
&lt;p&gt;Now, we need to write a loader program that loads and attaches this program. This loader program is used to load and attach an eBPF program to the Linux kernel. It opens and loads the eBPF object file, checks for errors during the process, finds a specific eBPF program within the loaded object, and attaches it to the kernel. Once attached, the eBPF program will be executed when certain events occur. The program enters an infinite loop at the end, indicating that it will continue running until it is manually terminated.&lt;/p&gt;
&lt;p&gt;&lt;br&gt;&lt;a target="_blank" href="images/ebpf-04.png"&gt;
&lt;img style="border: 2px solid #00b4c8"
alt="Loader program for eBPF."
src="images/ebpf-04.png"&gt;
&lt;/img&gt;
&lt;/a&gt;&lt;br&gt;&lt;br&gt;&lt;/p&gt;
&lt;p&gt;Let's compile and run this program&lt;/p&gt;
&lt;p&gt;&lt;br&gt;&lt;a target="_blank" href="images/ebpf-05.png"&gt;
&lt;img style="border: 2px solid #00b4c8"
alt="Command to compile loader program for eBPF."
src="images/ebpf-05.png"&gt;
&lt;/img&gt;
&lt;/a&gt;&lt;br&gt;&lt;br&gt;&lt;/p&gt;
&lt;p&gt;To get the logs generated by the function &lt;code&gt;bpf_printk&lt;/code&gt;, we can read the file:
&lt;code&gt;/sys/kernel/tracing/trace_pipe&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;br&gt;&lt;a target="_blank" href="images/ebpf-06.png"&gt;
&lt;img style="border: 2px solid #00b4c8"
alt="Reading '/sys/kernel/tracing/trace_pipe' file."
src="images/ebpf-06.png"&gt;
&lt;/img&gt;
&lt;/a&gt;&lt;br&gt;&lt;br&gt;&lt;/p&gt;
&lt;p&gt;&lt;br&gt;&lt;a target="_blank" href="images/ebpf-res-01.png"&gt;
&lt;img style="border: 2px solid #00b4c8"
alt="Messages we got after reading the 'trace_pipe' file."
src="images/ebpf-res-01.png"&gt;
&lt;/img&gt;
&lt;/a&gt;&lt;br&gt;&lt;br&gt;&lt;/p&gt;
&lt;p&gt;Manually reading messages from the tracepipe doesn't seem to be an efficient approach. It would be advantageous to establish a mechanism for the eBPF program to send messages to the loader program. One viable solution is to utilize ring buffers. Let’s review more details about ring buffers.&lt;/p&gt;
&lt;h2 id="ring-buffers"&gt;Ring buffers&lt;/h2&gt;
&lt;p&gt;eBPF ring buffer, also known as &lt;code&gt;bpf_ringbuf&lt;/code&gt;, is a mechanism provided by the Linux kernel for efficient communication between eBPF programs and user-space programs.&lt;/p&gt;
&lt;p&gt;It allows the exchange of data and events between eBPF programs running in the kernel and user-space applications. It is a &lt;code&gt;MPSC (Multi Producer Single Consumer)&lt;/code&gt; queue and can be safely shared across multiple CPUs simultaneously.&lt;/p&gt;
&lt;p&gt;The eBPF ring buffer, being shared across all CPUs, offers a unified and efficient solution for managing memory utilisation, mitigating issues of overuse or under-allocation that commonly occur with perfbuf.&lt;/p&gt;
&lt;p&gt;Let's have a look at a few functions that we'll be using to write an eBPF program that sends data to userspace.&lt;/p&gt;
&lt;h3 id="bpf-ringbuf-reserve"&gt;bpf_ringbuf_reserve&lt;/h3&gt;
&lt;p&gt;This function is used to reserve &lt;code&gt;size&lt;/code&gt; bytes of space in a BPF ring buffer.&lt;/p&gt;
&lt;p&gt;&lt;br&gt;&lt;a target="_blank" href="images/ebpf-08.png"&gt;
&lt;img style="border: 2px solid #00b4c8"
alt="Function which is used to reserve `size` bytes of space in a BPF ring buffer."
src="images/ebpf-08.png"&gt;
&lt;/img&gt;
&lt;/a&gt;&lt;br&gt;&lt;br&gt;&lt;/p&gt;
&lt;h3 id="bpf-probe-read-user-str"&gt;bpf_probe_read_user_str&lt;/h3&gt;
&lt;p&gt;This function is used to read a null terminated string from user-space memory into the destination &lt;code&gt;dst&lt;/code&gt;. The dst parameter is a pointer to the destination buffer in the kernel space. &lt;code&gt;unsafe_ptr&lt;/code&gt; is a pointer to the source string in the user-space.&lt;/p&gt;
&lt;p&gt;&lt;br&gt;&lt;a target="_blank" href="images/ebpf-09.png"&gt;
&lt;img style="border: 2px solid #00b4c8"
alt="Function which is used to read a null terminated string from user-space memory into the destination `dst`."
src="images/ebpf-09.png"&gt;
&lt;/img&gt;
&lt;/a&gt;&lt;br&gt;&lt;br&gt;&lt;/p&gt;
&lt;h3 id="bpf-ringbuf-submit"&gt;bpf_ringbuf_submit&lt;/h3&gt;
&lt;p&gt;This function is used to submit data that had previously been reserved in a &lt;code&gt;ringbuf&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;br&gt;&lt;a target="_blank" href="images/ebpf-10.png"&gt;
&lt;img style="border: 2px solid #00b4c8"
alt="Function ehich is used to submit data that had previously been reserved in a ringbuf."
src="images/ebpf-10.png"&gt;
&lt;/img&gt;
&lt;/a&gt;&lt;br&gt;&lt;br&gt;&lt;/p&gt;
&lt;h3 id="bpf-object-find-map-fd-by-name"&gt;bpf_object__find_map_fd_by_name&lt;/h3&gt;
&lt;p&gt;This function is used to find the file descriptor of a named map.&lt;/p&gt;
&lt;p&gt;&lt;br&gt;&lt;a target="_blank" href="images/ebpf-11.png"&gt;
&lt;img style="border: 2px solid #00b4c8"
alt="Function which is used to find the file descriptor of a named map."
src="images/ebpf-11.png"&gt;
&lt;/img&gt;
&lt;/a&gt;&lt;br&gt;&lt;br&gt;&lt;/p&gt;
&lt;h3 id="bpf-program-attach-tracepoint"&gt;bpf_program__attach_tracepoint&lt;/h3&gt;
&lt;p&gt;This function is used to attach an eBPF program to a kernel tracepoint.&lt;/p&gt;
&lt;p&gt;&lt;br&gt;&lt;a target="_blank" href="images/ebpf-12.png"&gt;
&lt;img style="border: 2px solid #00b4c8"
alt="Function which is used to attach an eBPF program to a kernel tracepoint."
src="images/ebpf-12.png"&gt;
&lt;/img&gt;
&lt;/a&gt;&lt;br&gt;&lt;br&gt;&lt;/p&gt;
&lt;h3 id="ring-buffer-new"&gt;ring_buffer__new&lt;/h3&gt;
&lt;p&gt;This function is used for creating and opening a new ringbuf manager.&lt;/p&gt;
&lt;p&gt;&lt;br&gt;&lt;a target="_blank" href="images/ebpf-13.png"&gt;
&lt;img style="border: 2px solid #00b4c8"
alt="Function which is used for creating and opening a new ringbuf manager."
src="images/ebpf-13.png"&gt;
&lt;/img&gt;
&lt;/a&gt;&lt;br&gt;&lt;br&gt;&lt;/p&gt;
&lt;h3 id="ring-buf-consume"&gt;ring_buf__consume&lt;/h3&gt;
&lt;p&gt;Used to remove or consume data from a &lt;code&gt;ring buffer&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;br&gt;&lt;a target="_blank" href="images/ebpf-14.png"&gt;
&lt;img style="border: 2px solid #00b4c8"
alt="Program used to remove or consume data from a ring buffer."
src="images/ebpf-14.png"&gt;
&lt;/img&gt;
&lt;/a&gt;&lt;br&gt;&lt;br&gt;&lt;/p&gt;
&lt;h2 id="btf-bpf-type-format"&gt;BTF (BPF Type Format)&lt;/h2&gt;
&lt;p&gt;It provides a way to describe the types of data structures used by eBPF programs, allowing for improved type safety, debugging, and introspection.&lt;/p&gt;
&lt;p&gt;Now, let's write a program that sends data to userspace using ringbuf.&lt;/p&gt;
&lt;p&gt;&lt;br&gt;&lt;a target="_blank" href="images/ebpf-15.png"&gt;
&lt;img style="border: 2px solid #00b4c8"
alt="Program that sends data to userspace using ringbuf"
src="images/ebpf-15.png"&gt;
&lt;/img&gt;
&lt;/a&gt;&lt;br&gt;&lt;br&gt;&lt;/p&gt;
&lt;p&gt;Having created the program, we can write a loader to load this eBPF program.&lt;/p&gt;
&lt;p&gt;&lt;br&gt;&lt;a target="_blank" href="images/ebpf-16.png"&gt;
&lt;img style="border: 2px solid #00b4c8"
alt="A loader to load this eBPF program."
src="images/ebpf-16.png"&gt;
&lt;/img&gt;
&lt;/a&gt;&lt;br&gt;&lt;br&gt;&lt;/p&gt;
&lt;p&gt;The infinite loop is necessary to ensure that the program continuously checks for new events in the ring buffer. Without the loop, the program would only consume events that were already in the buffer at the time of the initial &lt;code&gt;ring_buffer__consume()&lt;/code&gt; call. By looping and calling &lt;code&gt;ring_buffer__consume()&lt;/code&gt; repeatedly, the program can retrieve events as soon as they become available and process them in real-time. The &lt;code&gt;sleep(1)&lt;/code&gt; call within the loop serves to reduce the CPU usage of the program by introducing a one-second delay between each call to &lt;code&gt;ring_buffer__consume()&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;br&gt;&lt;a target="_blank" href="images/ebpf-17.png"&gt;
&lt;img style="border: 2px solid #00b4c8"
alt="Commands to compile and run the above program."
src="images/ebpf-17.png"&gt;
&lt;/img&gt;
&lt;/a&gt;&lt;br&gt;&lt;br&gt;&lt;/p&gt;
&lt;p&gt;&lt;br&gt;&lt;a target="_blank" href="images/ebpf-res-02.png"&gt;
&lt;img style="border: 2px solid #00b4c8"
alt="Results after compiling and executing the above program."
src="images/ebpf-res-02.png"&gt;
&lt;/img&gt;
&lt;/a&gt;&lt;br&gt;&lt;br&gt;&lt;/p&gt;
&lt;p&gt;Great, we were able to recover the process name as well as the PID!&lt;/p&gt;
&lt;h2 id="conclusion"&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;In conclusion, this article has provided a comprehensive overview of eBPF (extended Berkeley Packet Filter) and its significance in tracing system calls. We have explored the evolution from BPF to eBPF, discussed why Falco uses this technology, and delved into the process of working with eBPF programs and ring buffers for efficient data communication between the kernel and user-space applications.&lt;/p&gt;
&lt;p&gt;As we journeyed through the capabilities of eBPF in this first part, we uncovered its benefits in terms of safety, performance, and observability when compared to traditional kernel modules. eBPF empowers us to securely and efficiently monitor and analyze system calls in real-time, making it a valuable tool in modern cloud native environments.&lt;/p&gt;
&lt;p&gt;In the upcoming second part of this blog series, we will further expand our exploration by delving into the realm of probes and additional advanced topics. We will dive deeper into how eBPF probes can be leveraged for enhanced system tracing, performance analysis, and security monitoring. Stay tuned for more insights and practical guidance on harnessing the power of eBPF.&lt;/p&gt;
&lt;p&gt;Keep an eye out for Part 2, where we'll continue our journey into the world of eBPF and system call tracing.&lt;/p&gt;</description></item></channel></rss>