Skip to content

Commit

Permalink
libbpf-tools/mountsnoop: Support fsopen,fsconfig,fsmount,move_mount s…
Browse files Browse the repository at this point in the history
…yscalls

Do the same thing of bcc commit 60ebaf4 ("tools/mountsnoop: Support
fsopen(2), fsmount(2), fsconfig(2), move_mount(2)")

    $ sudo ./mountsnoop
    COMM             PID     TID     MNT_NS      CALL
    fsmount          431216  431216  4026531841  fsopen("ext4", 0x0) = 5
    fsmount          431216  431216  4026531841  fsconfig(5, "FSCONFIG_SET_FLAG", "rw", "", 0) = 0
    fsmount          431216  431216  4026531841  fsconfig(5, "FSCONFIG_SET_STRING", "source", "/dev/loop0", 0) = 0
    fsmount          431216  431216  4026531841  fsconfig(5, "FSCONFIG_CMD_CREATE", "", "", 0) = 0
    fsmount          431216  431216  4026531841  fsmount(5, "0x0", "MOUNT_ATTR_RDONLY") = 6
    fsmount          431216  431216  4026531841  move_mount(6, "", AT_FDCWD, "./tmp-dir/", "") = 0
    fsmount          431216  431216  4026531841  umount("./tmp-dir/", 0x0) = 0

In the above test, the C program is more complicated, so I will not show it
here, but a test example is given in the link [1].

[1] https://github.com/torvalds/linux/blob/master/samples/vfs/test-fsmount.c

Signed-off-by: Rong Tao <[email protected]>
  • Loading branch information
Rtoax authored and yonghong-song committed Jan 8, 2025
1 parent 464f89b commit eabed37
Show file tree
Hide file tree
Showing 3 changed files with 463 additions and 54 deletions.
172 changes: 146 additions & 26 deletions libbpf-tools/mountsnoop.bpf.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,7 @@ struct {
__type(value, struct arg);
} args SEC(".maps");

static int probe_entry(const char *src, const char *dest, const char *fs,
__u64 flags, const char *data, enum op op)
static int probe_entry(union sys_arg *sys_arg, enum op op)
{
__u64 pid_tgid = bpf_get_current_pid_tgid();
__u32 pid = pid_tgid >> 32;
Expand All @@ -35,18 +34,19 @@ static int probe_entry(const char *src, const char *dest, const char *fs,

switch (op) {
case MOUNT:
arg.mount.flags = flags;
arg.mount.src = src;
arg.mount.dest = dest;
arg.mount.fs = fs;
arg.mount.data= data;
break;
case UMOUNT:
arg.umount.flags = flags;
arg.umount.dest = dest;
case FSOPEN:
case FSCONFIG:
case FSMOUNT:
case MOVE_MOUNT:
__builtin_memcpy(&arg.sys, sys_arg, sizeof(*sys_arg));
break;
default:
goto skip;
}

bpf_map_update_elem(&args, &tid, &arg, BPF_ANY);
skip:
return 0;
};

Expand Down Expand Up @@ -78,15 +78,57 @@ static int probe_exit(void *ctx, int ret)

switch (argp->op) {
case MOUNT:
eventp->mount.flags = argp->mount.flags;
bpf_probe_read_user_str(eventp->mount.src, sizeof(eventp->mount.src), argp->mount.src);
bpf_probe_read_user_str(eventp->mount.dest, sizeof(eventp->mount.dest), argp->mount.dest);
bpf_probe_read_user_str(eventp->mount.fs, sizeof(eventp->mount.fs), argp->mount.fs);
bpf_probe_read_user_str(eventp->mount.data, sizeof(eventp->mount.data), argp->mount.data);
eventp->mount.flags = argp->sys.mount.flags;
bpf_probe_read_user_str(eventp->mount.src,
sizeof(eventp->mount.src),
argp->sys.mount.src);
bpf_probe_read_user_str(eventp->mount.dest,
sizeof(eventp->mount.dest),
argp->sys.mount.dest);
bpf_probe_read_user_str(eventp->mount.fs,
sizeof(eventp->mount.fs),
argp->sys.mount.fs);
bpf_probe_read_user_str(eventp->mount.data,
sizeof(eventp->mount.data),
argp->sys.mount.data);
break;
case UMOUNT:
eventp->umount.flags = argp->umount.flags;
bpf_probe_read_user_str(eventp->umount.dest, sizeof(eventp->umount.dest), argp->umount.dest);
eventp->umount.flags = argp->sys.umount.flags;
bpf_probe_read_user_str(eventp->umount.dest,
sizeof(eventp->umount.dest),
argp->sys.umount.dest);
break;
case FSOPEN:
eventp->fsopen.flags = argp->sys.fsopen.flags;
bpf_probe_read_user_str(eventp->fsopen.fs,
sizeof(eventp->fsopen.fs),
argp->sys.fsopen.fs);
break;
case FSCONFIG:
eventp->fsconfig.fd = argp->sys.fsconfig.fd;
eventp->fsconfig.cmd = argp->sys.fsconfig.cmd;
bpf_probe_read_user_str(eventp->fsconfig.key,
sizeof(eventp->fsconfig.key),
argp->sys.fsconfig.key);
bpf_probe_read_user_str(eventp->fsconfig.value,
sizeof(eventp->fsconfig.value),
argp->sys.fsconfig.value);
eventp->fsconfig.aux = argp->sys.fsconfig.aux;
break;
case FSMOUNT:
eventp->fsmount.fs_fd = argp->sys.fsmount.fs_fd;
eventp->fsmount.flags = argp->sys.fsmount.flags;
eventp->fsmount.attr_flags = argp->sys.fsmount.attr_flags;
break;
case MOVE_MOUNT:
eventp->move_mount.from_dfd = argp->sys.move_mount.from_dfd;
bpf_probe_read_user_str(eventp->move_mount.from_pathname,
sizeof(eventp->move_mount.from_pathname),
argp->sys.move_mount.from_pathname);
eventp->move_mount.to_dfd = argp->sys.move_mount.to_dfd;
bpf_probe_read_user_str(eventp->move_mount.to_pathname,
sizeof(eventp->move_mount.to_pathname),
argp->sys.move_mount.to_pathname);
break;
}

Expand All @@ -100,13 +142,15 @@ static int probe_exit(void *ctx, int ret)
SEC("tracepoint/syscalls/sys_enter_mount")
int mount_entry(struct syscall_trace_enter *ctx)
{
const char *src = (const char *)ctx->args[0];
const char *dest = (const char *)ctx->args[1];
const char *fs = (const char *)ctx->args[2];
__u64 flags = (__u64)ctx->args[3];
const char *data = (const char *)ctx->args[4];
union sys_arg arg = {};

return probe_entry(src, dest, fs, flags, data, MOUNT);
arg.mount.src = (const char *)ctx->args[0];
arg.mount.dest = (const char *)ctx->args[1];
arg.mount.fs = (const char *)ctx->args[2];
arg.mount.flags = (__u64)ctx->args[3];
arg.mount.data = (const char *)ctx->args[4];

return probe_entry(&arg, MOUNT);
}

SEC("tracepoint/syscalls/sys_exit_mount")
Expand All @@ -118,10 +162,12 @@ int mount_exit(struct syscall_trace_exit *ctx)
SEC("tracepoint/syscalls/sys_enter_umount")
int umount_entry(struct syscall_trace_enter *ctx)
{
const char *dest = (const char *)ctx->args[0];
__u64 flags = (__u64)ctx->args[1];
union sys_arg arg = {};

arg.umount.dest = (const char *)ctx->args[0];
arg.umount.flags = (__u64)ctx->args[1];

return probe_entry(NULL, dest, NULL, flags, NULL, UMOUNT);
return probe_entry(&arg, UMOUNT);
}

SEC("tracepoint/syscalls/sys_exit_umount")
Expand All @@ -130,4 +176,78 @@ int umount_exit(struct syscall_trace_exit *ctx)
return probe_exit(ctx, (int)ctx->ret);
}

SEC("tracepoint/syscalls/sys_enter_fsopen")
int fsopen_entry(struct syscall_trace_enter *ctx)
{
union sys_arg arg = {};

arg.fsopen.fs = (const char *)ctx->args[0];
arg.fsopen.flags = (__u32)ctx->args[1];

return probe_entry(&arg, FSOPEN);
}

SEC("tracepoint/syscalls/sys_exit_fsopen")
int fsopen_exit(struct syscall_trace_exit *ctx)
{
return probe_exit(ctx, (int)ctx->ret);
}

SEC("tracepoint/syscalls/sys_enter_fsconfig")
int fsconfig_entry(struct syscall_trace_enter *ctx)
{
union sys_arg arg = {};

arg.fsconfig.fd = (int)ctx->args[0];
arg.fsconfig.cmd = (int)ctx->args[1];
arg.fsconfig.key = (const char *)ctx->args[2];
arg.fsconfig.value = (const char *)ctx->args[3];
arg.fsconfig.aux = (int)ctx->args[4];

return probe_entry(&arg, FSCONFIG);
}

SEC("tracepoint/syscalls/sys_exit_fsconfig")
int fsconfig_exit(struct syscall_trace_exit *ctx)
{
return probe_exit(ctx, (int)ctx->ret);
}

SEC("tracepoint/syscalls/sys_enter_fsmount")
int fsmount_entry(struct syscall_trace_enter *ctx)
{
union sys_arg arg = {};

arg.fsmount.fs_fd = (__u32)ctx->args[0];
arg.fsmount.flags = (__u32)ctx->args[1];
arg.fsmount.attr_flags = (__u32)ctx->args[2];

return probe_entry(&arg, FSMOUNT);
}

SEC("tracepoint/syscalls/sys_exit_fsmount")
int fsmount_exit(struct syscall_trace_exit *ctx)
{
return probe_exit(ctx, (int)ctx->ret);
}

SEC("tracepoint/syscalls/sys_enter_move_mount")
int move_mount_entry(struct syscall_trace_enter *ctx)
{
union sys_arg arg = {};

arg.move_mount.from_dfd = (int)ctx->args[0];
arg.move_mount.from_pathname = (const char *)ctx->args[1];
arg.move_mount.to_dfd = (int)ctx->args[2];
arg.move_mount.to_pathname = (const char *)ctx->args[3];

return probe_entry(&arg, MOVE_MOUNT);
}

SEC("tracepoint/syscalls/sys_exit_move_mount")
int move_mount_exit(struct syscall_trace_exit *ctx)
{
return probe_exit(ctx, (int)ctx->ret);
}

char LICENSE[] SEC("license") = "Dual BSD/GPL";
Loading

0 comments on commit eabed37

Please sign in to comment.