From 64ffca5b6a0f429d5d81bd23c60ad7201f16d1ef Mon Sep 17 00:00:00 2001 From: Nicholas Berlin Date: Fri, 27 Jun 2025 17:32:47 -0400 Subject: [PATCH 1/4] Rename btf.c to btf_helper.c --- Makefile | 2 +- btf.c => btf_helper.c | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename btf.c => btf_helper.c (100%) diff --git a/Makefile b/Makefile index aaf4d90..87d94f7 100644 --- a/Makefile +++ b/Makefile @@ -91,7 +91,7 @@ endif LIBQUARK_DEPS:= $(filter-out manpages.h, $(LIBQUARK_DEPS)) LIBQUARK_SRCS:= \ bpf_queue.c \ - btf.c \ + btf_helper.c \ btfhub.c \ compat.c \ kprobe_queue.c \ diff --git a/btf.c b/btf_helper.c similarity index 100% rename from btf.c rename to btf_helper.c From f8d0fa1e3dedaed480c1fb53b8f9bb93a85b125d Mon Sep 17 00:00:00 2001 From: Nicholas Berlin Date: Fri, 27 Jun 2025 17:35:26 -0400 Subject: [PATCH 2/4] Add new func to count op func params --- btf_helper.c | 44 ++++++++++++++++++++++++++++++++++++++++++++ quark.h | 1 + 2 files changed, 45 insertions(+) diff --git a/btf_helper.c b/btf_helper.c index b75d118..a408679 100644 --- a/btf_helper.c +++ b/btf_helper.c @@ -292,6 +292,50 @@ btf_enum_value(struct btf *btf, const char *dotname, ssize_t *uv) return (-1); } +int +btf_number_of_params_op_ptr(struct btf *btf, const char *ops_struct, const char* op_name) +{ + const char *name; + struct btf_type const *ops_t; + struct btf_member *m; + int i; + + ops_t = btf_type_by_name_kind(btf, NULL, ops_struct, BTF_KIND_STRUCT); + + if (!btf_is_struct(ops_t)) { + errno = EINVAL; + goto fail; + } + + m = btf_members(ops_t); + + for (i = 0; i < btf_vlen(ops_t); i++, m++) { + name = btf__name_by_offset(btf, m->name_off); + if (name == NULL) + continue; + + if (!strcmp(op_name, name)) { + const struct btf_type *t; + + t = btf__type_by_id(btf, m->type); + if (t == NULL) + return (-1); + + t = btf__type_by_id(btf, t->type); + if (t == NULL) + return (-1); + + if (!btf_is_func_proto(t)) + return (-1); + + return (btf_vlen(t)); + } + } + +fail: + return (-1); +} + int btf_number_of_params(struct btf *btf, const char *func) { diff --git a/quark.h b/quark.h index 838df0e..eb659cf 100644 --- a/quark.h +++ b/quark.h @@ -80,6 +80,7 @@ ssize_t quark_btf_offset(struct quark_btf *, const char *); struct btf; s32 btf_root_offset(struct btf *, const char *, int); int btf_number_of_params(struct btf *, const char *); +int btf_number_of_params_op_ptr(struct btf *, const char *, const char *); int btf_index_of_param(struct btf *, const char *, const char *); /* bpf_queue.c */ From 09a965ad0cfcc8f3de621dd2c13329c032a8f1a7 Mon Sep 17 00:00:00 2001 From: Nicholas Berlin Date: Fri, 27 Jun 2025 17:36:58 -0400 Subject: [PATCH 3/4] Probe fsnotify_create --- bpf_queue.c | 7 +++++ elastic-ebpf/GPL/Events/File/Probe.bpf.c | 38 ++++++++++++++++++++++++ elastic-ebpf/GPL/Events/State.h | 2 ++ 3 files changed, 47 insertions(+) diff --git a/bpf_queue.c b/bpf_queue.c index c934c67..6f03077 100644 --- a/bpf_queue.c +++ b/bpf_queue.c @@ -667,9 +667,14 @@ bpf_queue_open1(struct quark_queue *qq, int use_fentry) } if (qq->flags & QQ_FILE) { + int use_fsnotify = + (6 == btf_number_of_params_op_ptr(btf, "inode_operations", "atomic_open")); + if (use_fentry) { bpf_program__set_autoload(p->progs.fentry__do_renameat2, 1); bpf_program__set_autoload(p->progs.fentry__do_unlinkat, 1); + if (use_fsnotify) + bpf_program__set_autoload(p->progs.fentry__fsnotify, 1); bpf_program__set_autoload(p->progs.fentry__mnt_want_write, 1); bpf_program__set_autoload(p->progs.fentry__vfs_rename, 1); bpf_program__set_autoload(p->progs.fentry__vfs_unlink, 1); @@ -688,6 +693,8 @@ bpf_queue_open1(struct quark_queue *qq, int use_fentry) bpf_program__set_autoload(p->progs.kretprobe__chown_common, 1); bpf_program__set_autoload(p->progs.kprobe__do_truncate, 1); bpf_program__set_autoload(p->progs.kretprobe__do_truncate, 1); + if (use_fsnotify) + bpf_program__set_autoload(p->progs.kprobe__fsnotify, 1); bpf_program__set_autoload(p->progs.kprobe__vfs_writev, 1); bpf_program__set_autoload(p->progs.kretprobe__vfs_writev, 1); bpf_program__set_autoload(p->progs.kprobe__vfs_rename, 1); diff --git a/elastic-ebpf/GPL/Events/File/Probe.bpf.c b/elastic-ebpf/GPL/Events/File/Probe.bpf.c index bca6ef7..0725f6a 100644 --- a/elastic-ebpf/GPL/Events/File/Probe.bpf.c +++ b/elastic-ebpf/GPL/Events/File/Probe.bpf.c @@ -289,6 +289,10 @@ static int do_filp_open__exit(struct file *f) if (fmode & (fmode_t)0x100000) { // FMODE_CREATED // generate a file creation event prepare_and_send_file_event(f, EBPF_EVENT_FILE_CREATE, NULL, 0); + } else if (ebpf_events_state__get(EBPF_EVENTS_STATE_FS_CREATE) != NULL) { + // generate a file creation event + prepare_and_send_file_event(f, EBPF_EVENT_FILE_CREATE, NULL, 0); + ebpf_events_state__del(EBPF_EVENTS_STATE_FS_CREATE); } else { // check if memfd file is being opened struct path p = BPF_CORE_READ(f, f_path); @@ -333,6 +337,40 @@ static int do_filp_open__exit(struct file *f) return 0; } +static int fsnotify__enter(u32 mask) +{ + if (mask & 0x100) { // FS_CREATE + struct ebpf_events_state state = {}; + ebpf_events_state__set(EBPF_EVENTS_STATE_FS_CREATE, &state); + } + + return 0; +} + +SEC("kprobe/fsnotify") +int BPF_KPROBE(kprobe__fsnotify, + struct inode *to_tell, + u32 mask, + const void *data, + int data_is, + const unsigned char *file_name, + u32 cookie) +{ + return fsnotify__enter(mask); +} + +SEC("fentry/fsnotify") +int BPF_PROG(fentry__fsnotify, + struct inode *to_tell, + u32 mask, + const void *data, + int data_is, + const unsigned char *file_name, + u32 cookie) +{ + return fsnotify__enter(mask); +} + SEC("fexit/do_filp_open") int BPF_PROG(fexit__do_filp_open, int dfd, diff --git a/elastic-ebpf/GPL/Events/State.h b/elastic-ebpf/GPL/Events/State.h index 45e6c50..c3ae0e5 100644 --- a/elastic-ebpf/GPL/Events/State.h +++ b/elastic-ebpf/GPL/Events/State.h @@ -22,6 +22,7 @@ enum ebpf_events_state_op { EBPF_EVENTS_STATE_WRITEV = 8, EBPF_EVENTS_STATE_CHOWN = 9, EBPF_EVENTS_STATE_GROUP_DEAD = 10, + EBPF_EVENTS_STATE_FS_CREATE = 11, }; struct ebpf_events_key { @@ -93,6 +94,7 @@ struct ebpf_events_state { struct ebpf_events_writev_state writev; struct ebpf_events_chown_state chown; /* struct ebpf_events_group_dead group_dead; nada */ + /* struct ebpf_events_fs_create fs_create; nada */ }; }; From 342ad7d186bda1c93a70813feb7652686dc09a07 Mon Sep 17 00:00:00 2001 From: Nicholas Berlin Date: Sat, 28 Jun 2025 11:43:13 -0400 Subject: [PATCH 4/4] Re-enable file creation tests in CI --- .buildkite/.pipeline.yml.swp | Bin 0 -> 24576 bytes .buildkite/pipeline.yml | 12 ++++++------ 2 files changed, 6 insertions(+), 6 deletions(-) create mode 100644 .buildkite/.pipeline.yml.swp diff --git a/.buildkite/.pipeline.yml.swp b/.buildkite/.pipeline.yml.swp new file mode 100644 index 0000000000000000000000000000000000000000..d3dbf6d05020f00acb9a89da8867ceb314278884 GIT binary patch literal 24576 zcmeI)32YqI9mnw@b;wcd2HH^6BTSs6Kw;N=+1a%cBGNzwDUE7k7h0*?@y^&Dd9Tjy zhT1teLQ0FHDuuKWBC!HQQ3{os7*#|HqD@N5Sz0O7!D`D<8W0kMAW>*(lJ@&%-{Q6R z@K!RAdS;|g?0DymJ->N7e*ZTw>GXA6eXSby1{AhAit?@c@AkAU4k$-%K1)e<8dls) zidU*`Jt;k2bqD$426@1yZZq5Ty_{zCHhDX9W?b(zvqn?eOdEVR!`qjr>1eflM|U4L z0XG3Vfn2uB6RuZ+0l!cDeL>@V_0#9IyWzMAxCyukxCyukxCyukxCyukxCuBYfo!@? zxry_gCeQgc`SGlAAM51bH_DHj#=SmW{=LwCraVC5IG>QOuaF-%k9%Ey+5O-q;3nWE z;3nWE;3nWE;3nWE;3nWE;3nWE;3n`PB%tYv@@0dxN4piy;i+M_7;Ru>uRwh!gdS@(1j}cHD>ISKtyHpQR`-;3+(cyRiv6 zmSPDS@a{}SIe-VT4Fl*x8~m7!S@`n|ejfY~--nLt5yXW!eKtQchOq}*(2gtN$08_r zgGrUAu?zQO1G?bFJj}-FIz<`5VeGtR91>b|tmswM-TOjb+knx%UJN`8m5m0Dx!hSjQe$I|j^ zWtF*LmI0J4`E^)8b~omNogg)U1^=b~s=!WmOqysEjPsqQOBf$rwj1v{dbuXY@TP#`r3gS*(bR|F^-^ z*s#RVh=Y{-9rwZce-xvi(TgmGimDb*Gb}B-sP+Id|J5-+uDqh+N~>m)ODmhIu~agv zaSZF@JdON_*Auf+nT$uX5-r8U)}k?S)ZQa%?@{jbL`yY)6oN{daYGkpn?L+VdV->> z6pgC$S4gw6W|tPrM$=lhM~?c(T~OIy$6wLWZamrp$6r!a?({KTQu~a}q?xs}L|4Y! z-Cy%L7cLKPQPnO~imrIMt6b>Bg?1DrY0?z+ze!E{Q|eYx|F4im-iy@r`|&VD?ca~( z2w)!0!<*FfBiN6hU<;xUHUHUomwNth7{)&Az&f;JH7By-JU524s`P5Hb+Rq_hemRJ4|4#_J}C9gnjdF2n`ki2|V^77S|SN;&r$jcul zuQF4E@)qU~*A!X)D2|y^wR()W>Zh9&%~jYpe(^%oPdB6URJ!XIHJ-FCChGqS`Bnba zY5YO`zft~LAECZ~9uMIj#Bd#!A&3UNPmM3?fAQRZA2uV4CAbV1;2gY0jei6~7{DDc za4qIyI^L$nKZf7n7Z`w!7%s<`aGVJnz3B;+emN z?_ep;$6TDC&VL>|u?6dp#!4)Pm}PpcX+P<5}v~^aS!@&9on!6 z4S0^{`j25RcHt)U;uZ-Z znOAVq9*LdtYijamT>c%XO!WS1bjad|P^C2@p&HhRh{hx-wyAoPk_)p!{_*`tF3bwm zus}pKR_v6fd`u;y%R)@mMwf+*Y3z)cf{_ZnDOkfo5YgBnF@-C|RKwzrAdMXo)8a}o ziFFi}hMDqB7o@R6Vrr=rQ%emo(byp|mDDWq79Oltv=n+1jcbib)c+oeyBntQN74HK z;^+T&QR}b6m1xF%h_(MGsO|rP1K5hYkb+qEKOg7fl&J0T4EAFi(nw(?LO4Zj|0YK8 zd+fnhWFXc6ti(l_gAwZcC-E!%9Je8jRk#>p&Hr?WHU9_jAVmE?fWle;KcCOWEF7c8 ze-_(tJ2L3Ta(GdXSE=uh;UFGB1~II{S1=D^?f>i4_=j*1JMaUn!ZKV6vG)IcYWr7l z7=ze>K6K(zd>%9KZ)*Hu9KyZmM;{7v05kafJ?i^ca1=urgjoOIfp+-uIf%9YNAPPr zgdd|HHy{8%8t_m0z#$A_5O*R0(KmdsH`U%MRsZE)J>zBs{3YWfyK>_{#;bgzw#yjN zkbT59RY%(Pc}6NsnM5X@GO?Q~c0^M>qmqYrb}x!dJYN#=($pCl@vl5YUl{$DG%}+J z=SU)6nmQw+lG