55#include <bpf/bpf_helpers.h>
66#include <bpf/bpf_tracing.h>
77#include <bpf/bpf_core_read.h>
8+ #include <errno.h>
89#include "bpf_misc.h"
910
11+ u32 dynamic_sz = 1 ;
1012int kprobe2_res = 0 ;
1113int kretprobe2_res = 0 ;
1214int uprobe_byname_res = 0 ;
1315int uretprobe_byname_res = 0 ;
1416int uprobe_byname2_res = 0 ;
1517int uretprobe_byname2_res = 0 ;
1618int uprobe_byname3_sleepable_res = 0 ;
19+ int uprobe_byname3_str_sleepable_res = 0 ;
1720int uprobe_byname3_res = 0 ;
1821int uretprobe_byname3_sleepable_res = 0 ;
22+ int uretprobe_byname3_str_sleepable_res = 0 ;
1923int uretprobe_byname3_res = 0 ;
2024void * user_ptr = 0 ;
2125
26+ int bpf_copy_from_user_str (void * dst , u32 , const void * , u64 ) __weak __ksym ;
27+
2228SEC ("ksyscall/nanosleep" )
2329int BPF_KSYSCALL (handle_kprobe_auto , struct __kernel_timespec * req , struct __kernel_timespec * rem )
2430{
@@ -87,11 +93,61 @@ static __always_inline bool verify_sleepable_user_copy(void)
8793 return bpf_strncmp (data , sizeof (data ), "test_data" ) == 0 ;
8894}
8995
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+
90144SEC ("uprobe.s//proc/self/exe:trigger_func3" )
91145int handle_uprobe_byname3_sleepable (struct pt_regs * ctx )
92146{
93147 if (verify_sleepable_user_copy ())
94148 uprobe_byname3_sleepable_res = 9 ;
149+ if (verify_sleepable_user_copy_str ())
150+ uprobe_byname3_str_sleepable_res = 10 ;
95151 return 0 ;
96152}
97153
@@ -102,22 +158,24 @@ int handle_uprobe_byname3_sleepable(struct pt_regs *ctx)
102158SEC ("uprobe//proc/self/exe:trigger_func3" )
103159int handle_uprobe_byname3 (struct pt_regs * ctx )
104160{
105- uprobe_byname3_res = 10 ;
161+ uprobe_byname3_res = 11 ;
106162 return 0 ;
107163}
108164
109165SEC ("uretprobe.s//proc/self/exe:trigger_func3" )
110166int handle_uretprobe_byname3_sleepable (struct pt_regs * ctx )
111167{
112168 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 ;
114172 return 0 ;
115173}
116174
117175SEC ("uretprobe//proc/self/exe:trigger_func3" )
118176int handle_uretprobe_byname3 (struct pt_regs * ctx )
119177{
120- uretprobe_byname3_res = 12 ;
178+ uretprobe_byname3_res = 14 ;
121179 return 0 ;
122180}
123181
0 commit comments