Skip to content

Commit

Permalink
libbpf-tools/filelife: Fix error tracking caused by failed unlink
Browse files Browse the repository at this point in the history
When we try to delete a file with a normal user after creating a file as
root (sudo), the deletion of the file fails, but the kprobe:vfs_unlink is
triggered, which leads to incorrect file lifecycle tracking.

This commit makes the same changes [1] as tools/filelife.py, or you can
see bcc [2] commit 076ccf0 ("tools/filelife: Fix error tracking caused
by failed unlink").

[1] #4791
[2] 076ccf0

Signed-off-by: Rong Tao <rongtao@cestc.cn>
  • Loading branch information
Rtoax authored and yonghong-song committed Nov 12, 2023
1 parent cfbc479 commit b2917e6
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 6 deletions.
39 changes: 33 additions & 6 deletions libbpf-tools/filelife.bpf.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,13 @@ struct {
__uint(value_size, sizeof(u32));
} events SEC(".maps");

struct {
__uint(type, BPF_MAP_TYPE_HASH);
__uint(max_entries, 8192);
__type(key, u32); /* tid */
__type(value, struct event);
} currevent SEC(".maps");

static __always_inline int
probe_create(struct dentry *dentry)
{
Expand Down Expand Up @@ -98,6 +105,7 @@ int BPF_KPROBE(vfs_unlink, void *arg0, void *arg1, void *arg2)
struct event event = {};
const u8 *qs_name_ptr;
u32 tgid = id >> 32;
u32 tid = (u32)id;
u64 *tsp, delta_ns;
bool has_arg = renamedata_has_old_mnt_userns_field()
|| renamedata_has_new_mnt_idmap_field();
Expand All @@ -110,11 +118,6 @@ int BPF_KPROBE(vfs_unlink, void *arg0, void *arg1, void *arg2)

delta_ns = bpf_ktime_get_ns() - *tsp;

if (has_arg)
bpf_map_delete_elem(&start, &arg2);
else
bpf_map_delete_elem(&start, &arg1);

qs_name_ptr = has_arg
? BPF_CORE_READ((struct dentry *)arg2, d_name.name)
: BPF_CORE_READ((struct dentry *)arg1, d_name.name);
Expand All @@ -123,10 +126,34 @@ int BPF_KPROBE(vfs_unlink, void *arg0, void *arg1, void *arg2)
bpf_get_current_comm(&event.task, sizeof(event.task));
event.delta_ns = delta_ns;
event.tgid = tgid;
event.dentry = has_arg ? arg2 : arg1;

bpf_map_update_elem(&currevent, &tid, &event, BPF_ANY);
return 0;
}

SEC("kretprobe/vfs_unlink")
int BPF_KRETPROBE(vfs_unlink_ret)
{
u64 id = bpf_get_current_pid_tgid();
u32 tid = (u32)id;
int ret = PT_REGS_RC(ctx);
struct event *event;

event = bpf_map_lookup_elem(&currevent, &tid);
if (!event)
return 0;
bpf_map_delete_elem(&currevent, &tid);

/* skip failed unlink */
if (ret)
return 0;

bpf_map_delete_elem(&start, &event->dentry);

/* output */
bpf_perf_event_output(ctx, &events, BPF_F_CURRENT_CPU,
&event, sizeof(event));
event, sizeof(*event));
return 0;
}

Expand Down
1 change: 1 addition & 0 deletions libbpf-tools/filelife.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
// 20-Mar-2020 Wenbo Zhang Created this.
// 13-Nov-2022 Rong Tao Check btf struct field for CO-RE and add vfs_open()
// 23-Aug-2023 Rong Tao Add vfs_* 'struct mnt_idmap' support.(CO-RE)
// 08-Nov-2023 Rong Tao Support unlink failed
#include <argp.h>
#include <signal.h>
#include <stdio.h>
Expand Down
2 changes: 2 additions & 0 deletions libbpf-tools/filelife.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ struct event {
char task[TASK_COMM_LEN];
__u64 delta_ns;
pid_t tgid;
/* private */
void *dentry;
};

#endif /* __FILELIFE_H */

0 comments on commit b2917e6

Please sign in to comment.