eBPF 정리
eBPF 는 Berkeley Packet Filter에 e(extend)를 붙여서 만든 이름인 듯 하다. wiki 의 내용을 보면 BPF 는 network traffic 분석용으로 많이 쓰였던 것 같다.
이 부분이 확장돼서 이제는 kernel mode 에서 실행돼야 하는 script 를 실행할 수 있게 해주는 기술이 됐다.
이전에 kernel 에 기능을 넣으려면, code 를 수정해서 다시 빌드 하던지, kernel module들을 load 해야 했다.[ref. 1]
static code analysis 와 crash, hang 또는 다른 kernel 에 부정적인 영향을 미치는 것들을 reject 하는 것으로 안정성(safety)을 제공한다.
자동으로 거부되는 프로그램의 예
- 강력한 종료 보장이 없는 프로그램(즉, 종료 조건이 없는 for/while 루프)
- safety-checks 없는 pointers들을 dereference하는 프로그램
verifier를 통과한 loaded program 은, 빠른 성능을 위해서, interpreted 되거나 in-kernel JIT compiled 된다. 그리고 나서, program들은 os kernel 의 여러 hook point 들에 attached 돼서 event 가 발생할 때 실행된다.
대략적인 개념은
system call 에서 함수를 호출할 때 마다, eBPF 함수를 호출하도록 만들어 놓은 듯 하다. 그래서 정의된 handler 가 없으면, 그냥 넘어가고, 있으면 실행하게 되는 듯 하다.
windows 에서 ebpf
windows 에서도 ebpf 를 만들고 있다. 기존 ebpf 위에 layer를 추가해서 windows 에서도 실행되도록 한다.
지원버전:
- windows 10 이상
- windows server 2019 이상
wsl
helloworld for wsl2
#!/usr/bin/python3
from bcc import BPF
from time import sleep
program = """
BPF_HASH(clones);
int hello_world(void *ctx) {
u64 uid;
u64 counter = 0;
u64 *p;
uid = bpf_get_current_uid_gid() & 0xFFFFFFFF;
p = clones.lookup(&uid);
if (p != 0){
counter = *p;
}
counter++;
clones.update(&uid, &counter);
return 0;
}
"""
b = BPF(text=program)
clone = b.get_syscall_fnname("clone")
b.attach_kprobe(event=clone, fn_name="hello_world")
b.trace_print()
sleep(1000)
while True:
sleep(2)
s = ""
if len(b["clones"].items()):
for k,v in b["clones"].items():
s += "ID {}: {}\t".format(k.value, v.value)
print(s)
else:
print("No entries yet")
댓글 없음:
댓글 쓰기