小编pch*_*gno的帖子

bpf_trace_printk 格式指针

中是如何"%p"实施的bpf_trace_printk?看起来很不一样printf。

#include <uapi/linux/ptrace.h>

int print_args(struct pt_regs *ctx) {
    void *ptr = (void*)PT_REGS_PARM1(ctx);
    bpf_trace_printk("args: %lx %p %ld\n", ptr, ptr, ptr);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

我使用这个 eBPF 程序来跟踪一个函数的参数。参数的类型是指向某个结构的指针。

一种输出是: args: 7ffde047d6c4 00000000ec7e9023 140728366257860

我们可以注意到 的输出"%p"非常奇怪。如果我们使用标准 C 程序来检查输出:

#include <stdio.h>

int main() {
    void *ptr = (void*)0x7ffde047d6c4;
    printf("args: %lx %p %ld\n", ptr, ptr, ptr);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

我们将获得: args: 7ffde047d6c4 0x7ffde047d6c4 140728366257860

c bpf ebpf

5
推荐指数
1
解决办法
846
查看次数

在没有分支操作码的情况下测试一个整数与 eBPF 中的其他两个整数不同

我正在编写一个检查任务 UID 的 eBPF kprobe,即在 execve 调用之间唯一允许的 UID 更改是 setuid()、seteuid() 和 setreuid() 调用所允许的 UID 更改。

由于探测器检查所有任务,因此它使用从 init_task 开始迭代的展开循环,并且最多必须使用 1024 或 8192 个分支,具体取决于内核版本。

我的问题是,如果存在非法更改,如何实现返回非零的检查,定义为:

(new_ruid != old_euid && new_ruid != old_ruid) ||
(new_euid != old_euid && new_euid != old_ruid && new_euid != old_suid)
Run Code Online (Sandbox Code Playgroud)

但不使用分支(clang 使用跳转来短路检查之间的任何表达式是否&&计算为 true)。

assembly clang linux-kernel bpf ebpf

5
推荐指数
1
解决办法
211
查看次数

bpf_probe_read_user() 在 ebpf 程序中抛出“权限被拒绝:对映射值的访问无效”

在kretprobe/sys_read探测器中,我尝试读取 BPF_MAP_TYPE_ARRAY 中的请求缓冲区(用户空间)。eBPF 验证程序抛出以下错误:

{"error": "field SyscallProbeRetRead: program syscall__probe_ret_read: load program: permission denied: invalid access to map value, value_size=70 off=0 size=16383: R1 min value is outside of the allowed memory range (truncated, 73 line(s) omitted)"}
Run Code Online (Sandbox Code Playgroud)

逻辑:如果 buf_size 大于MAX_MSG_SIZE,那么我们将读取TRACE_PARENT_SIZE或更少(取决于缓冲区的大小)到seventy_bytes_array->data,否则,我们将不会读取任何内容。

#define MAX_MSG_SIZE 16383 
#define TRACE_PARENT_SIZE 70

SEC("kretprobe/sys_read")
int syscall__probe_ret_read(struct pt_regs *ctx)
{
    size_t buf_size = PT_REGS_RC(ctx);
    u64 id = bpf_get_current_pid_tgid();
    struct data_args_t *read_args = bpf_map_lookup_elem(&active_read_args_map, &id);

    if (read_args)
    {
        char *buf = read_args->buf; …
Run Code Online (Sandbox Code Playgroud)

c bpf ebpf libbpf

5
推荐指数
0
解决办法
108
查看次数

在kprobes支持ftrace之后,Linux内核中的跟踪点是否冗余?

在Linux内核中提供kprobe事件支持ftrace时使用跟踪点事件的用例有哪些?似乎可以使用"跟踪点事件"使用kprobe事件完成所有可能的事情,因为可以在跟踪点事件可用的同一点设置kprobe事件.

我错过了什么吗?

ftrace linux-kernel kprobe

4
推荐指数
1
解决办法
423
查看次数

简单的 eBPF 操作未对 tc 生效

samples/bpf/pare_simple.c我通过非常简单的更改(来自 Linux 内核树)编译了 BPF 示例:

SEC("simple")
int handle_ingress(struct __sk_buff *skb)
{
   return TC_ACT_SHOT;
}
Run Code Online (Sandbox Code Playgroud)

所以我希望丢弃任何数据包。我安装它如下:

这种情况发生在 Ubuntu 16.04.3 LTS 上,内核为 4.4.0-98,从软件包安装了 llvm 和 clang 版本 3.8,iproute2 是来自 github 的最新版本。

$ tc qdisc add dev eth0 clsact
$ tc filter add dev eth0 ingress bpf \
      object-file ./net-next.git/samples/bpf/parse_simple.o \
      section simple verbose

Prog section 'simple' loaded (5)!
 - Type:         3
 - Instructions: 2 (0 over limit)
 - License:      GPL

Verifier analysis:

0: (b7) r0 = 2
1: (95) exit
processed …
Run Code Online (Sandbox Code Playgroud)

linux-kernel bpf ebpf

4
推荐指数
1
解决办法
2386
查看次数

bpf_printk() 的输出

在运行一些示例时,samples/bpf我注意到bpf_printk输出带有一些额外的信息,例如:

telnet-470   [001] .N.. 419421.045894: 0x00000001: BPF command: 2
Run Code Online (Sandbox Code Playgroud)

BPF command: 2实际的字符串是传递给bpf_printkbpf 程序的,但其余的是什么?我假设这来自内核的 JIT ?

我在哪里可以仔细查看这些位的含义?谢谢。

linux-kernel llvm-clang bpf ebpf

4
推荐指数
1
解决办法
3652
查看次数

谁在BPF中创建地图

在阅读man bpf了一些其他文档来源后,我的印象是a map只能由用户进程创建.然而,以下小程序似乎神奇地创建了bpf地图:

struct bpf_map_def SEC("maps") my_map = {
        .type = BPF_MAP_TYPE_ARRAY,
        .key_size = sizeof(u32),
        .value_size = sizeof(long),
        .max_entries = 10,
};

SEC("sockops")
int my_prog(struct bpf_sock_ops *skops)
{
   u32 key = 1;
   long *value;
   ...

   value = bpf_map_lookup_elem(&my_map, &key);
   ...
   return 1;
}
Run Code Online (Sandbox Code Playgroud)

所以我用内核加载程序,tools/bpf/bpftool并验证程序是否已加载:

$ bpftool prog show
1: sock_ops  name my_prog  tag f3a3583cdd82ae8d
        loaded_at Jan 02/18:46  uid 0
        xlated 728B  not jited  memlock 4096B

$ bpftool map show
1: array …
Run Code Online (Sandbox Code Playgroud)

linux-kernel bpf ebpf

4
推荐指数
2
解决办法
678
查看次数

eBPF:理解验证器代码中的两个宏

我正在查看ebpf验证器代码,但无法理解以下宏:

#define offsetof(TYPE, MEMBER)  ((size_t)&((TYPE *)0)->MEMBER)
#define offsetofend(TYPE, MEMBER) \
    (offsetof(TYPE, MEMBER) + sizeof(((TYPE *)0)->MEMBER))

<...>

#define bpf_ctx_range(TYPE, MEMBER)                     \
    offsetof(TYPE, MEMBER) ... offsetofend(TYPE, MEMBER) - 1
#define bpf_ctx_range_till(TYPE, MEMBER1, MEMBER2)              \
    offsetof(TYPE, MEMBER1) ... offsetofend(TYPE, MEMBER2) - 1
Run Code Online (Sandbox Code Playgroud)

我理解offsetof宏offsetofend,但是什么...意思呢?

谢谢。

c macros linux-kernel bpf ebpf

4
推荐指数
1
解决办法
219
查看次数

ebpf 的受限 C 中不允许什么?

来自 bpf 手册页:

eBPF 程序可以用受限制的 C 语言编写,并编译(使用 clang 编译器)为 eBPF 字节码。此受限 C 语言省略了各种功能,例如循环、全局变量、可变参数函数、浮点数以及将结构体作为函数参数传递。

AFAIK 手册页尚未更新。我想知道使用受限C编写eBPF程序时到底禁止什么?手册页所说的仍然正确吗?

c manpage linux-kernel bpf ebpf

4
推荐指数
1
解决办法
4859
查看次数

为什么bpf代码无法访问cpumap_enqueue_ctx的前8个字节?

阅读一些附加到跟踪点的ebpf示例后,我注意到每个结构都是从这样的填充开始构建的(来自samples/bpf/xdp_redirect_cpu_kern.c)

/* Tracepoint: /sys/kernel/debug/tracing/events/xdp/xdp_cpumap_enqueue/format
 * Code in:         kernel/include/trace/events/xdp.h
 */
struct cpumap_enqueue_ctx {
        u64 __pad;              // First 8 bytes are not accessible by bpf code
        int map_id;             //      offset:8;  size:4; signed:1;
        u32 act;                //      offset:12; size:4; signed:0;
        int cpu;                //      offset:16; size:4; signed:1;
        unsigned int drops;     //      offset:20; size:4; signed:0;
        unsigned int processed; //      offset:24; size:4; signed:0;
        int to_cpu;             //      offset:28; size:4; signed:1;
};
Run Code Online (Sandbox Code Playgroud)

我发现的所有评论都是bpf代码无法访问前8个字节,但我不明白为什么。

c bpf tracepoint ebpf

4
推荐指数
1
解决办法
61
查看次数

标签 统计

bpf ×9

ebpf ×9

linux-kernel ×7

c ×5

assembly ×1

clang ×1

ftrace ×1

kprobe ×1

libbpf ×1

llvm-clang ×1

macros ×1

manpage ×1

tracepoint ×1