mirror of
https://github.com/varun-r-mallya/Python-BPF.git
synced 2025-12-31 21:06:25 +00:00
add bpf_passthrough generation
This commit is contained in:
@ -2,6 +2,7 @@ import ast
|
|||||||
import logging
|
import logging
|
||||||
import importlib
|
import importlib
|
||||||
import inspect
|
import inspect
|
||||||
|
import llvmlite.ir as ir
|
||||||
|
|
||||||
from .assignment_info import AssignmentInfo, AssignmentType
|
from .assignment_info import AssignmentInfo, AssignmentType
|
||||||
from .dependency_handler import DependencyHandler
|
from .dependency_handler import DependencyHandler
|
||||||
@ -76,9 +77,28 @@ def detect_import_statement(tree: ast.AST) -> list[tuple[str, ast.ImportFrom]]:
|
|||||||
return vmlinux_imports
|
return vmlinux_imports
|
||||||
|
|
||||||
|
|
||||||
|
def bpf_passthrough_gen(module):
|
||||||
|
i32_ty = ir.IntType(32)
|
||||||
|
ptr_ty = ir.PointerType(ir.IntType(8))
|
||||||
|
fnty = ir.FunctionType(ptr_ty, [i32_ty, ptr_ty])
|
||||||
|
|
||||||
|
# Declare the intrinsic
|
||||||
|
passthrough = ir.Function(module, fnty, "llvm.bpf.passthrough.p0.p0")
|
||||||
|
|
||||||
|
# Set function attributes
|
||||||
|
# TODO: the ones commented are supposed to be there but cannot be added due to llvmlite limitations at the moment
|
||||||
|
# passthrough.attributes.add("nofree")
|
||||||
|
# passthrough.attributes.add("nosync")
|
||||||
|
passthrough.attributes.add("nounwind")
|
||||||
|
# passthrough.attributes.add("memory(none)")
|
||||||
|
|
||||||
|
return passthrough
|
||||||
|
|
||||||
|
|
||||||
def vmlinux_proc(tree: ast.AST, module):
|
def vmlinux_proc(tree: ast.AST, module):
|
||||||
import_statements = detect_import_statement(tree)
|
import_statements = detect_import_statement(tree)
|
||||||
|
|
||||||
|
bpf_passthrough_gen(module)
|
||||||
# initialise dependency handler
|
# initialise dependency handler
|
||||||
handler = DependencyHandler()
|
handler = DependencyHandler()
|
||||||
# initialise assignment dictionary of name to type
|
# initialise assignment dictionary of name to type
|
||||||
|
|||||||
@ -1,25 +0,0 @@
|
|||||||
#define __TARGET_ARCH_arm64
|
|
||||||
|
|
||||||
#include "vmlinux.h"
|
|
||||||
#include <bpf/bpf_helpers.h>
|
|
||||||
#include <bpf/bpf_tracing.h>
|
|
||||||
#include <bpf/bpf_core_read.h>
|
|
||||||
|
|
||||||
// Map: key = struct request*, value = u64 timestamp
|
|
||||||
struct {
|
|
||||||
__uint(type, BPF_MAP_TYPE_HASH);
|
|
||||||
__type(key, struct request *);
|
|
||||||
__type(value, u64);
|
|
||||||
__uint(max_entries, 1024);
|
|
||||||
} start SEC(".maps");
|
|
||||||
|
|
||||||
// Attach to kprobe for blk_start_request
|
|
||||||
SEC("kprobe/blk_start_request")
|
|
||||||
int BPF_KPROBE(trace_start, struct request *req)
|
|
||||||
{
|
|
||||||
u64 ts = bpf_ktime_get_ns();
|
|
||||||
bpf_map_update_elem(&start, &req, &ts, BPF_ANY);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
char LICENSE[] SEC("license") = "GPL";
|
|
||||||
@ -4,9 +4,33 @@
|
|||||||
#include <bpf/bpf_helpers.h>
|
#include <bpf/bpf_helpers.h>
|
||||||
#include <bpf/bpf_tracing.h>
|
#include <bpf/bpf_tracing.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
Information gained from reversing this (multiple kernel versions):
|
||||||
|
There is no point of
|
||||||
|
```llvm
|
||||||
|
tail call void @llvm.dbg.value(metadata ptr %0, metadata !60, metadata !DIExpression()), !dbg !70
|
||||||
|
```
|
||||||
|
and the first argument of passthrough is fucking useless. It just needs to be a distinct integer:
|
||||||
|
```llvm
|
||||||
|
%9 = tail call ptr @llvm.bpf.passthrough.p0.p0(i32 3, ptr %8)
|
||||||
|
```
|
||||||
|
*/
|
||||||
|
|
||||||
SEC("tp/syscalls/sys_enter_execve")
|
SEC("tp/syscalls/sys_enter_execve")
|
||||||
int handle_setuid_entry(struct trace_event_raw_sys_enter *ctx) {
|
int handle_setuid_entry(struct trace_event_raw_sys_enter *ctx) {
|
||||||
bpf_printk("args: %u", (unsigned int)ctx->args[0]);
|
// Access each argument separately with clear variable assignments
|
||||||
|
unsigned long arg0 = ctx->args[0];
|
||||||
|
bpf_printk("args[0]: %u", arg0);
|
||||||
|
|
||||||
|
unsigned long arg1 = ctx->args[1];
|
||||||
|
bpf_printk("args[1]: %u", arg1);
|
||||||
|
|
||||||
|
// Remove the duplicate access to args[1]
|
||||||
|
|
||||||
|
unsigned long arg2 = ctx->args[2];
|
||||||
|
bpf_printk("args[3]: %u", arg2);
|
||||||
|
bpf_printk("args[4]: %u", ctx->args[2]);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
149976
tests/c-form/vmlinux.h
vendored
149976
tests/c-form/vmlinux.h
vendored
File diff suppressed because it is too large
Load Diff
@ -4,12 +4,12 @@ from pythonbpf import bpf, section, bpfglobal, compile_to_ir
|
|||||||
from pythonbpf import compile # noqa: F401
|
from pythonbpf import compile # noqa: F401
|
||||||
from vmlinux import TASK_COMM_LEN # noqa: F401
|
from vmlinux import TASK_COMM_LEN # noqa: F401
|
||||||
from vmlinux import struct_trace_event_raw_sys_enter # noqa: F401
|
from vmlinux import struct_trace_event_raw_sys_enter # noqa: F401
|
||||||
from ctypes import c_uint64, c_int32, c_int64
|
from ctypes import c_int64
|
||||||
from pythonbpf.maps import HashMap
|
|
||||||
|
|
||||||
# from vmlinux import struct_uinput_device
|
# from vmlinux import struct_uinput_device
|
||||||
# from vmlinux import struct_blk_integrity_iter
|
# from vmlinux import struct_blk_integrity_iter
|
||||||
|
|
||||||
|
|
||||||
@bpf
|
@bpf
|
||||||
@section("tracepoint/syscalls/sys_enter_execve")
|
@section("tracepoint/syscalls/sys_enter_execve")
|
||||||
def hello_world(ctx: struct_trace_event_raw_sys_enter) -> c_int64:
|
def hello_world(ctx: struct_trace_event_raw_sys_enter) -> c_int64:
|
||||||
|
|||||||
Reference in New Issue
Block a user