Simple App: a Linux toy application for user and kernel space

Figure 1 – Simple App architecture

In the context of the Open Source Study Group, we decided to explore some Linux kernel APIs related to IPC and namespaces. An effective approach to this is exercising APIs from a crafted user-space application, while debugging at the kernel level. After some progress and setting breakpoints here and there, a challenge became evident: breakpoints in common functions are hit all the time from different processes. We need to filter out non-relevant hits, while staying focused on our application. This can be done, perhaps, by means of a conditional breakpoint in the debugger. Checking the binary image associated to the current task (looking into the mm_struct) should make it, but debugging complexity starts growing rapidly.

Continue reading “Simple App: a Linux toy application for user and kernel space”

How terminal emulators work on Linux?

A few days back, while debugging the delivery of a SIGINT signal from the kernel to a foreground process, I wondered how terminal emulators work. In this article I’ll be using gnome-terminalbash and the yes application as an example; but the same concept should apply to any combination of a terminal emulator, a shell and a console application.

Gnome-terminal runs under a graphic environment (such as Xorg), so any key pressed on the keyboard has to turn into a character obtainable from there. Bash runs as a child process of gnome-terminal, and yes as child process of bash. Console application developers are used to reading input from STDINT and writing to STDOUT or STDERR. But, how are characters delivered from one end to the other?

Continue reading “How terminal emulators work on Linux?”

Global Descriptor Table (GDT) in Linux x86-64

Even though x86 memory segmentation is largely unused in 64 bits mode, the Linux kernel still initializes the CPU’s Global Descriptor Table (GDT) and points the gdt register to it. I was curious about its content and how segment selectors can be used today. This article is a brief summary of my experiments and findings.

To begin with, we can read the gdt register calling native_store_gdt in kernel space (arch/x86/include/asm/desc.h):

We see there that the register contains a virtual address, so segmentation is previous to pagination in protected mode.

Continue reading “Global Descriptor Table (GDT) in Linux x86-64”

Hardware breakpoints in the Linux kernel through perf_events

Hardware breakpoints are quite useful while developing user or kernel space software. An interesting feature, which makes them be also known as memory breakpoints, is interrupting execution whenever the processor executes, reads or writes a specific virtual address. This feature is not available in software breakpoints.

Once a breakpoint is hit, there might be cases in which we want the execution to stop, so single-stepping or memory analysis is possible; and cases in which we want traces to be generated without a full-stop. I won’t make a distinction between these use cases, given that the underlying mechanism is the same.

Continue reading “Hardware breakpoints in the Linux kernel through perf_events”

Who prints “(core dumped)” after a segmentation fault?

When a CLI process in Linux exits after a segmentation fault, the following message is typically printed to stdout: “Segmentation fault (core dumped)”. We are assuming here that the process did not register a handler for the SIGSEGV signal. I was a bit curious about who was printing the message so started to dig a bit.

My first hypothesis was that libc had a default handler for this signal. After running the application with strace, I found no sys_write system call: the application and its libraries were not printing anything.

If a process registers no handler for SIGSEGV, do_coredump function (fs/coredump.c – Linux kernel) is executed. Caught my attention that the Kernel creates a new task and launches a user mode application. This application is /usr/libexec/abrt-hook-ccpp in Fedora, and the goal is to record and report the crash. I ran strings over its binary and dynamically linked libraries (libc, libreport, libabrt, etc.) but no clues.

Continue reading “Who prints “(core dumped)” after a segmentation fault?”

Wildcard support for MAC addresses in netfilter (Linux kernel) and iptables

Some time ago Riki from Netlabs proposed a simple challenge: add wildcard support for MAC addresses when specifying netfilter rules in Linux.

Netfilter and iptables -its user-space counter part- let you filter network packets based on their source MAC address. However, there is currently no option to match all packets that meet a specific pattern (i.e.: those with prefix from a certain vendor). A wildcards syntax would be enough to accomplish this goal. In example, the following rule should drop every incoming packet on the ens3 interface:

A quick lookup in the Linux kernel source and in iptables brought me to a couple of files probably required by the implementation of this functionality: net/netfilter/xt_mac.c (kernel) and libxtables/xtoptions.c (iptables). The former is related to the decision of whether a packet should pass or not when filtering by MAC address. The latter has the iptables options parsing code, through which we can specify matching rules.

Continue reading “Wildcard support for MAC addresses in netfilter (Linux kernel) and iptables”