Skip to content

Instantly share code, notes, and snippets.

@alessandrod
Last active September 9, 2019 09:45
Show Gist options
  • Save alessandrod/293bb4dfdf82fd8cc5f7de98e01b10d6 to your computer and use it in GitHub Desktop.
Save alessandrod/293bb4dfdf82fd8cc5f7de98e01b10d6 to your computer and use it in GitHub Desktop.
use core::mem::transmute;
use cty::*;
#[repr(C)]
pub struct pt_regs {
pub r15: c_ulong,
pub r14: c_ulong,
pub r13: c_ulong,
pub r12: c_ulong,
pub bp: c_ulong,
pub bx: c_ulong,
pub r11: c_ulong,
pub r10: c_ulong,
pub r9: c_ulong,
pub r8: c_ulong,
pub ax: c_ulong,
pub cx: c_ulong,
pub dx: c_ulong,
pub si: c_ulong,
pub di: c_ulong,
pub orig_ax: c_ulong,
pub ip: c_ulong,
pub cs: c_ulong,
pub flags: c_ulong,
pub sp: c_ulong,
pub ss: c_ulong,
}
#[repr(C)]
#[derive(Copy, Clone)]
pub struct bpf_map_def {
pub type_: c_uint,
pub key_size: c_uint,
pub value_size: c_uint,
pub max_entries: c_uint,
pub map_flags: c_uint,
pub pinning: c_uint,
pub namespace: [c_char; 256usize],
}
pub type bpf_map_type = u32;
pub const bpf_map_type_BPF_MAP_TYPE_HASH: bpf_map_type = 1;
pub const bpf_map_type_BPF_MAP_TYPE_PERF_EVENT_ARRAY: bpf_map_type = 4;
#[repr(C)]
pub struct Helpers {
pub bpf_trace_printk: unsafe extern "C" fn(
fmt: *const c_char,
fmt_size: c_int,
...
) -> c_int,
pub bpf_map_lookup_elem: unsafe extern "C" fn(
map: *mut c_void,
key: *mut c_void,
) -> *mut c_void,
pub bpf_perf_event_output: unsafe extern "C" fn(
ctx: *mut c_void,
map: *mut c_void,
flags: c_ulonglong,
data: *mut c_void,
size: c_int,
) -> c_int,
pub bpf_get_smp_processor_id: unsafe extern "C" fn() -> c_ulonglong,
pub bpf_get_current_pid_tgid: unsafe extern "C" fn() -> c_ulonglong,
pub bpf_get_current_comm: unsafe extern "C" fn(
buf: *mut c_void,
buf_size: c_int,
) -> c_int,
}
pub type bpf_func_id = u64;
pub const bpf_func_id_BPF_FUNC_unspec: bpf_func_id = 0;
pub const bpf_func_id_BPF_FUNC_map_lookup_elem: bpf_func_id = 1;
pub const bpf_func_id_BPF_FUNC_map_update_elem: bpf_func_id = 2;
pub const bpf_func_id_BPF_FUNC_map_delete_elem: bpf_func_id = 3;
pub const bpf_func_id_BPF_FUNC_probe_read: bpf_func_id = 4;
pub const bpf_func_id_BPF_FUNC_ktime_get_ns: bpf_func_id = 5;
pub const bpf_func_id_BPF_FUNC_trace_printk: bpf_func_id = 6;
pub const bpf_func_id_BPF_FUNC_get_prandom_u32: bpf_func_id = 7;
pub const bpf_func_id_BPF_FUNC_get_smp_processor_id: bpf_func_id = 8;
pub const bpf_func_id_BPF_FUNC_skb_store_bytes: bpf_func_id = 9;
pub const bpf_func_id_BPF_FUNC_l3_csum_replace: bpf_func_id = 10;
pub const bpf_func_id_BPF_FUNC_l4_csum_replace: bpf_func_id = 11;
pub const bpf_func_id_BPF_FUNC_tail_call: bpf_func_id = 12;
pub const bpf_func_id_BPF_FUNC_clone_redirect: bpf_func_id = 13;
pub const bpf_func_id_BPF_FUNC_get_current_pid_tgid: bpf_func_id = 14;
pub const bpf_func_id_BPF_FUNC_get_current_uid_gid: bpf_func_id = 15;
pub const bpf_func_id_BPF_FUNC_get_current_comm: bpf_func_id = 16;
pub const bpf_func_id_BPF_FUNC_get_cgroup_classid: bpf_func_id = 17;
pub const bpf_func_id_BPF_FUNC_skb_vlan_push: bpf_func_id = 18;
pub const bpf_func_id_BPF_FUNC_skb_vlan_pop: bpf_func_id = 19;
pub const bpf_func_id_BPF_FUNC_skb_get_tunnel_key: bpf_func_id = 20;
pub const bpf_func_id_BPF_FUNC_skb_set_tunnel_key: bpf_func_id = 21;
pub const bpf_func_id_BPF_FUNC_perf_event_read: bpf_func_id = 22;
pub const bpf_func_id_BPF_FUNC_redirect: bpf_func_id = 23;
pub const bpf_func_id_BPF_FUNC_get_route_realm: bpf_func_id = 24;
pub const bpf_func_id_BPF_FUNC_perf_event_output: bpf_func_id = 25;
pub const bpf_func_id_BPF_FUNC_skb_load_bytes: bpf_func_id = 26;
pub const bpf_func_id_BPF_FUNC_get_stackid: bpf_func_id = 27;
pub const bpf_func_id_BPF_FUNC_csum_diff: bpf_func_id = 28;
pub const bpf_func_id_BPF_FUNC_skb_get_tunnel_opt: bpf_func_id = 29;
pub const bpf_func_id_BPF_FUNC_skb_set_tunnel_opt: bpf_func_id = 30;
pub const bpf_func_id_BPF_FUNC_skb_change_proto: bpf_func_id = 31;
pub const bpf_func_id_BPF_FUNC_skb_change_type: bpf_func_id = 32;
pub const bpf_func_id_BPF_FUNC_skb_under_cgroup: bpf_func_id = 33;
pub const bpf_func_id_BPF_FUNC_get_hash_recalc: bpf_func_id = 34;
pub const bpf_func_id_BPF_FUNC_get_current_task: bpf_func_id = 35;
pub const bpf_func_id_BPF_FUNC_probe_write_user: bpf_func_id = 36;
pub const bpf_func_id_BPF_FUNC_current_task_under_cgroup: bpf_func_id = 37;
pub const bpf_func_id_BPF_FUNC_skb_change_tail: bpf_func_id = 38;
pub const bpf_func_id_BPF_FUNC_skb_pull_data: bpf_func_id = 39;
pub const bpf_func_id_BPF_FUNC_csum_update: bpf_func_id = 40;
pub const bpf_func_id_BPF_FUNC_set_hash_invalid: bpf_func_id = 41;
pub const bpf_func_id_BPF_FUNC_get_numa_node_id: bpf_func_id = 42;
pub const bpf_func_id_BPF_FUNC_skb_change_head: bpf_func_id = 43;
pub const bpf_func_id_BPF_FUNC_xdp_adjust_head: bpf_func_id = 44;
pub const bpf_func_id_BPF_FUNC_probe_read_str: bpf_func_id = 45;
pub const bpf_func_id_BPF_FUNC_get_socket_cookie: bpf_func_id = 46;
pub const bpf_func_id_BPF_FUNC_get_socket_uid: bpf_func_id = 47;
pub const bpf_func_id_BPF_FUNC_set_hash: bpf_func_id = 48;
pub const bpf_func_id_BPF_FUNC_setsockopt: bpf_func_id = 49;
pub const bpf_func_id_BPF_FUNC_skb_adjust_room: bpf_func_id = 50;
pub const bpf_func_id_BPF_FUNC_redirect_map: bpf_func_id = 51;
pub const bpf_func_id_BPF_FUNC_sk_redirect_map: bpf_func_id = 52;
pub const bpf_func_id_BPF_FUNC_sock_map_update: bpf_func_id = 53;
pub const bpf_func_id_BPF_FUNC_xdp_adjust_meta: bpf_func_id = 54;
pub const bpf_func_id_BPF_FUNC_perf_event_read_value: bpf_func_id = 55;
pub const bpf_func_id_BPF_FUNC_perf_prog_read_value: bpf_func_id = 56;
pub const bpf_func_id_BPF_FUNC_getsockopt: bpf_func_id = 57;
pub const bpf_func_id___BPF_FUNC_MAX_ID: bpf_func_id = 58;
pub const fn helpers() -> Helpers {
Helpers {
bpf_trace_printk: unsafe { transmute(bpf_func_id_BPF_FUNC_trace_printk) },
bpf_map_lookup_elem: unsafe { transmute(bpf_func_id_BPF_FUNC_map_lookup_elem) },
bpf_perf_event_output: unsafe { transmute(bpf_func_id_BPF_FUNC_perf_event_output) },
bpf_get_smp_processor_id: unsafe { transmute(bpf_func_id_BPF_FUNC_get_smp_processor_id) },
bpf_get_current_pid_tgid: unsafe { transmute(bpf_func_id_BPF_FUNC_get_current_pid_tgid) },
bpf_get_current_comm: unsafe { transmute(bpf_func_id_BPF_FUNC_get_current_comm) },
}
}
use core::marker::PhantomData;
use core::mem;
use cty::*;
use crate::bindings::*;
#[repr(transparent)]
pub struct HashMap<K, V> {
def: bpf_map_def,
_k: PhantomData<K>,
_v: PhantomData<V>
}
impl<K, V: Copy> HashMap<K, V> {
pub const fn new() -> Self {
Self {
def: bpf_map_def {
type_: bpf_map_type_BPF_MAP_TYPE_HASH,
key_size: mem::size_of::<K>() as u32,
value_size: mem::size_of::<V>() as u32,
max_entries: 10240u32,
map_flags: 0u32,
pinning: 0u32,
namespace: [0; 256],
},
_k: PhantomData,
_v: PhantomData
}
}
pub fn get(&mut self, mut key: K) -> Option<&V> {
let Helpers {
bpf_map_lookup_elem,
..
} = helpers();
let value = unsafe {
let value = bpf_map_lookup_elem(&mut self.def as *mut _ as *mut c_void, &mut key as *mut _ as *mut c_void);
if value.is_null() {
None
} else {
Some(&*(value as *const V))
}
};
value
}
}
#[repr(transparent)]
pub struct PerfMap<T> {
def: bpf_map_def,
_event: PhantomData<T>
}
impl<T> PerfMap<T> {
pub const fn new() -> Self {
Self {
def: bpf_map_def {
type_: bpf_map_type_BPF_MAP_TYPE_PERF_EVENT_ARRAY,
key_size: mem::size_of::<u32>() as u32,
value_size: mem::size_of::<u32>() as u32,
max_entries: 10240u32,
map_flags: 0u32,
pinning: 0u32,
namespace: [0; 256],
},
_event: PhantomData
}
}
pub fn insert<C>(&mut self, ctx: *mut C, mut data: T) {
let Helpers {
bpf_perf_event_output,
bpf_get_smp_processor_id,
..
} = helpers();
let cpu = unsafe { bpf_get_smp_processor_id() };
unsafe {
bpf_perf_event_output(
ctx as *mut _ as *mut c_void,
&mut self.def as *mut _ as *mut c_void,
cpu,
&mut data as *mut _ as *mut c_void,
mem::size_of::<T>() as i32,
);
};
}
}
#![feature(const_fn)]
#![feature(const_transmute)]
#![no_std]
mod bindings;
mod maps;
use cty::*;
use bindings::*;
use maps::*;
#[no_mangle]
#[link_section = "license"]
pub static _license: [u8; 4] = [71u8, 80, 76, 0]; //b"GPL\0"
#[no_mangle]
#[link_section = "version"]
pub static _version: u32 = 0xFFFFFFFE;
#[no_mangle]
#[link_section = "maps/syscall_tp_trigger"]
static mut syscall_event: PerfMap<_data_syscall_tracepoint> = PerfMap::new();
#[no_mangle]
#[link_section = "maps/host_pid"]
static mut host_pid: HashMap<u8, u64> = HashMap::new();
#[no_mangle]
#[link_section = "kprobe/syscall_enter"]
pub extern "C" fn syscall_enter(ctx: *mut c_void) -> i32 {
let Helpers {
bpf_get_current_pid_tgid,
..
} = helpers();
let ignore_pid = unsafe { host_pid.get(1u8) };
let pid_tgid = unsafe { bpf_get_current_pid_tgid() };
if let Some(pid) = ignore_pid {
if *pid == pid_tgid >> 32 {
return 0;
}
}
let data = _data_syscall_tracepoint::new(ctx, pid_tgid >> 32);
unsafe { syscall_event.insert(ctx, data) };
return 0;
}
#[repr(C)]
struct _data_syscall_tracepoint {
id: c_ulonglong,
syscall_nr: c_ulonglong,
comm: [c_char; 16usize],
}
impl _data_syscall_tracepoint {
fn new<C>(ctx: *mut C, pid: u64) -> Self {
let Helpers {
bpf_get_current_comm,
..
} = helpers();
let mut comm: [c_char; 16usize] = [0i8; 16] ;
unsafe { bpf_get_current_comm(&mut comm as *mut _ as *mut c_void, 16i32) };
let data = _data_syscall_tracepoint {
id: pid,
syscall_nr: unsafe { (*(ctx as *mut pt_regs)).ax },
comm
};
data
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment