184 lines · c
1// SPDX-License-Identifier: GPL-2.02// Copyright (c) 2017 Facebook3 4#include "vmlinux.h"5#include <bpf/bpf_helpers.h>6#include <bpf/bpf_tracing.h>7#include <bpf/bpf_core_read.h>8#include <errno.h>9#include "bpf_misc.h"10 11u32 dynamic_sz = 1;12int kprobe2_res = 0;13int kretprobe2_res = 0;14int uprobe_byname_res = 0;15int uretprobe_byname_res = 0;16int uprobe_byname2_res = 0;17int uretprobe_byname2_res = 0;18int uprobe_byname3_sleepable_res = 0;19int uprobe_byname3_str_sleepable_res = 0;20int uprobe_byname3_res = 0;21int uretprobe_byname3_sleepable_res = 0;22int uretprobe_byname3_str_sleepable_res = 0;23int uretprobe_byname3_res = 0;24void *user_ptr = 0;25 26int bpf_copy_from_user_str(void *dst, u32, const void *, u64) __weak __ksym;27 28SEC("ksyscall/nanosleep")29int BPF_KSYSCALL(handle_kprobe_auto, struct __kernel_timespec *req, struct __kernel_timespec *rem)30{31 kprobe2_res = 11;32 return 0;33}34 35SEC("kretsyscall/nanosleep")36int BPF_KRETPROBE(handle_kretprobe_auto, int ret)37{38 kretprobe2_res = 22;39 return ret;40}41 42SEC("uprobe")43int handle_uprobe_ref_ctr(struct pt_regs *ctx)44{45 return 0;46}47 48SEC("uretprobe")49int handle_uretprobe_ref_ctr(struct pt_regs *ctx)50{51 return 0;52}53 54SEC("uprobe")55int handle_uprobe_byname(struct pt_regs *ctx)56{57 uprobe_byname_res = 5;58 return 0;59}60 61/* use auto-attach format for section definition. */62SEC("uretprobe//proc/self/exe:trigger_func2")63int handle_uretprobe_byname(struct pt_regs *ctx)64{65 uretprobe_byname_res = 6;66 return 0;67}68 69SEC("uprobe")70int BPF_UPROBE(handle_uprobe_byname2, const char *pathname, const char *mode)71{72 char mode_buf[2] = {};73 74 /* verify fopen mode */75 bpf_probe_read_user(mode_buf, sizeof(mode_buf), mode);76 if (mode_buf[0] == 'r' && mode_buf[1] == 0)77 uprobe_byname2_res = 7;78 return 0;79}80 81SEC("uretprobe")82int BPF_URETPROBE(handle_uretprobe_byname2, void *ret)83{84 uretprobe_byname2_res = 8;85 return 0;86}87 88static __always_inline bool verify_sleepable_user_copy(void)89{90 char data[9];91 92 bpf_copy_from_user(data, sizeof(data), user_ptr);93 return bpf_strncmp(data, sizeof(data), "test_data") == 0;94}95 96static __always_inline bool verify_sleepable_user_copy_str(void)97{98 int ret;99 char data_long[20];100 char data_long_pad[20];101 char data_long_err[20];102 char data_short[4];103 char data_short_pad[4];104 105 ret = bpf_copy_from_user_str(data_short, sizeof(data_short), user_ptr, 0);106 107 if (bpf_strncmp(data_short, 4, "tes\0") != 0 || ret != 4)108 return false;109 110 ret = bpf_copy_from_user_str(data_short_pad, sizeof(data_short_pad), user_ptr, BPF_F_PAD_ZEROS);111 112 if (bpf_strncmp(data_short, 4, "tes\0") != 0 || ret != 4)113 return false;114 115 /* Make sure this passes the verifier */116 ret = bpf_copy_from_user_str(data_long, dynamic_sz & sizeof(data_long), user_ptr, 0);117 118 if (ret != 0)119 return false;120 121 ret = bpf_copy_from_user_str(data_long, sizeof(data_long), user_ptr, 0);122 123 if (bpf_strncmp(data_long, 10, "test_data\0") != 0 || ret != 10)124 return false;125 126 ret = bpf_copy_from_user_str(data_long_pad, sizeof(data_long_pad), user_ptr, BPF_F_PAD_ZEROS);127 128 if (bpf_strncmp(data_long_pad, 10, "test_data\0") != 0 || ret != 10 || data_long_pad[19] != '\0')129 return false;130 131 ret = bpf_copy_from_user_str(data_long_err, sizeof(data_long_err), (void *)data_long, BPF_F_PAD_ZEROS);132 133 if (ret > 0 || data_long_err[19] != '\0')134 return false;135 136 ret = bpf_copy_from_user_str(data_long, sizeof(data_long), user_ptr, 2);137 138 if (ret != -EINVAL)139 return false;140 141 return true;142}143 144SEC("uprobe.s//proc/self/exe:trigger_func3")145int handle_uprobe_byname3_sleepable(struct pt_regs *ctx)146{147 if (verify_sleepable_user_copy())148 uprobe_byname3_sleepable_res = 9;149 if (verify_sleepable_user_copy_str())150 uprobe_byname3_str_sleepable_res = 10;151 return 0;152}153 154/**155 * same target as the uprobe.s above to force sleepable and non-sleepable156 * programs in the same bpf_prog_array157 */158SEC("uprobe//proc/self/exe:trigger_func3")159int handle_uprobe_byname3(struct pt_regs *ctx)160{161 uprobe_byname3_res = 11;162 return 0;163}164 165SEC("uretprobe.s//proc/self/exe:trigger_func3")166int handle_uretprobe_byname3_sleepable(struct pt_regs *ctx)167{168 if (verify_sleepable_user_copy())169 uretprobe_byname3_sleepable_res = 12;170 if (verify_sleepable_user_copy_str())171 uretprobe_byname3_str_sleepable_res = 13;172 return 0;173}174 175SEC("uretprobe//proc/self/exe:trigger_func3")176int handle_uretprobe_byname3(struct pt_regs *ctx)177{178 uretprobe_byname3_res = 14;179 return 0;180}181 182 183char _license[] SEC("license") = "GPL";184