This article is the 10th day article of Linux Advent Calendar 2016.
Uprobes that can be used from ftrace, eBPF / bcc, Systemtap, etc. I can't find a sample (kernel module) that can be executed by uprobes alone like kprobes. So, Christmas is near, so this time I will introduce a sample of uprobes that anyone can easily use (I do not say that you should feel free to make a kernel module). The detailed implementation explanation is omitted, but the corresponding instruction is rewritten to 0xcc and skipped.
Distribution: Ubuntu 16.04 Kernel used for investigation and verification: 4.4.0-45-generic
uprobes is a Linux kernel mechanism that probes user processes from kernel space. Normally uprobes is used from a user-space configurable interface like ftrace A kernel module that uses uprobes is generated from a unique script like Systemtap, and is used in it.
Since Christmas is near this time, I will write a kernel module for direct contact with uprobes.
First, let's take a look at the kernel-side API for using the uprobes mechanism.
/*
* uprobe_register - register a probe
* @inode: the file in which the probe has to be placed.
* @offset: offset from the start of the file.
* @uc: information on howto handle the probe..
*
* Apart from the access refcount, uprobe_register() takes a creation
* refcount (thro alloc_uprobe) if and only if this @uprobe is getting
* inserted into the rbtree (i.e first consumer for a @inode:@offset
* tuple). Creation refcount stops uprobe_unregister from freeing the
* @uprobe even before the register operation is complete. Creation
* refcount is released when the last @uc for the @uprobe
* unregisters.
*
* Return errno if it cannot successully install probes
* else return 0 (success)
*/
int uprobe_register(struct inode *inode, loff_t offset, struct uprobe_consumer *uc)
It can be seen that the information that needs to be set is roughly the inode of the probe target file, the probe target offset of the probe target file, and the handler to be executed when the probe is performed.
Next, let's look at the uprobe_consumer structure that sets the function at the time of probe.
struct uprobe_consumer {
int (*handler)(struct uprobe_consumer *self, struct pt_regs *regs);
int (*ret_handler)(struct uprobe_consumer *self,
unsigned long func,
struct pt_regs *regs);
bool (*filter)(struct uprobe_consumer *self,
enum uprobe_filter_ctx ctx,
struct mm_struct *mm);
struct uprobe_consumer *next;
};
From the definition of the uprobe_consumer structure, it can be seen that the pt_regs structure is passed via the handler at the time of probe.
This time, run the following appropriate C sample application and try to probe the debuggee_func function call.
#include <stdio.h>
int debuggee_func(int a, int b)
{
int result;
result = a + b;
return result;
}
void main()
{
int result;
result = debuggee_func(1, 2);
printf("result: %d", result);
}
Next, the sample kernel module that uses uprobes is placed below. Please check the sample code below for processing such as conversion from file path to inode.
https://github.com/kentaost/uprobes_sample/blob/master/uprobes_sample.c
The following DEBUGGEE_FILE in this uprobes sample kernel module represents the file to be debugged, and DEBUGGEE_FILE_OFFSET represents the offset. The offset is obtained from the address of the target function and the start address of the text segment for the target binary using readelf or the like. In my environment, the debuggee_func function was 0x526 (0x400526 --0x400000), so I embedded this value and made it.
#define DEBUGGEE_FILE "/home/kentaost/debuggee_app"
#define DEBUGGEE_FILE_OFFSET (0x526)
After insmoding this sample kernel module, if you run the sample application and look at dmesg, you can see the evidence of probing as follows.
…
[xxxx.xxxxxx] handler is executed
[xxxx.xxxxxx] ret_handler is executed
As you can see from the uprobe_register function, it is not a mechanism to set the probe for each user process. For example, you can see that even if you launch the same program multiple times, it will be probed.
As an aside, if you do your best, you can prepare a user space stack trace in the same way as Systemtap below. (Systemtap prepares tapset so that you don't have to work hard, so usually use Systemtap and tapset)
http://qiita.com/kentaost/items/a2e882d2978fba9e17d3
Although omitted this time, if you also understand the internal implementation of uprobes, you can understand the behavior when probing a user process with Systemtap etc. (when using uprobes). There is no use for direct use, but you should use ftrace and Systemtap obediently except for Christmas.
Recommended Posts