5
5
#include <bpf/bpf_helpers.h>
6
6
#include <bpf/bpf_tracing.h>
7
7
#include <bpf/bpf_core_read.h>
8
+ #include <errno.h>
8
9
#include "bpf_misc.h"
9
10
11
+ u32 dynamic_sz = 1 ;
10
12
int kprobe2_res = 0 ;
11
13
int kretprobe2_res = 0 ;
12
14
int uprobe_byname_res = 0 ;
13
15
int uretprobe_byname_res = 0 ;
14
16
int uprobe_byname2_res = 0 ;
15
17
int uretprobe_byname2_res = 0 ;
16
18
int uprobe_byname3_sleepable_res = 0 ;
19
+ int uprobe_byname3_str_sleepable_res = 0 ;
17
20
int uprobe_byname3_res = 0 ;
18
21
int uretprobe_byname3_sleepable_res = 0 ;
22
+ int uretprobe_byname3_str_sleepable_res = 0 ;
19
23
int uretprobe_byname3_res = 0 ;
20
24
void * user_ptr = 0 ;
21
25
26
+ int bpf_copy_from_user_str (void * dst , u32 , const void * , u64 ) __weak __ksym ;
27
+
22
28
SEC ("ksyscall/nanosleep" )
23
29
int BPF_KSYSCALL (handle_kprobe_auto , struct __kernel_timespec * req , struct __kernel_timespec * rem )
24
30
{
@@ -87,11 +93,61 @@ static __always_inline bool verify_sleepable_user_copy(void)
87
93
return bpf_strncmp (data , sizeof (data ), "test_data" ) == 0 ;
88
94
}
89
95
96
+ static __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
+
90
144
SEC ("uprobe.s//proc/self/exe:trigger_func3" )
91
145
int handle_uprobe_byname3_sleepable (struct pt_regs * ctx )
92
146
{
93
147
if (verify_sleepable_user_copy ())
94
148
uprobe_byname3_sleepable_res = 9 ;
149
+ if (verify_sleepable_user_copy_str ())
150
+ uprobe_byname3_str_sleepable_res = 10 ;
95
151
return 0 ;
96
152
}
97
153
@@ -102,22 +158,24 @@ int handle_uprobe_byname3_sleepable(struct pt_regs *ctx)
102
158
SEC ("uprobe//proc/self/exe:trigger_func3" )
103
159
int handle_uprobe_byname3 (struct pt_regs * ctx )
104
160
{
105
- uprobe_byname3_res = 10 ;
161
+ uprobe_byname3_res = 11 ;
106
162
return 0 ;
107
163
}
108
164
109
165
SEC ("uretprobe.s//proc/self/exe:trigger_func3" )
110
166
int handle_uretprobe_byname3_sleepable (struct pt_regs * ctx )
111
167
{
112
168
if (verify_sleepable_user_copy ())
113
- uretprobe_byname3_sleepable_res = 11 ;
169
+ uretprobe_byname3_sleepable_res = 12 ;
170
+ if (verify_sleepable_user_copy_str ())
171
+ uretprobe_byname3_str_sleepable_res = 13 ;
114
172
return 0 ;
115
173
}
116
174
117
175
SEC ("uretprobe//proc/self/exe:trigger_func3" )
118
176
int handle_uretprobe_byname3 (struct pt_regs * ctx )
119
177
{
120
- uretprobe_byname3_res = 12 ;
178
+ uretprobe_byname3_res = 14 ;
121
179
return 0 ;
122
180
}
123
181
0 commit comments