@@ -2229,6 +2229,59 @@ struct bpf_kprobe_multi_run_ctx {
22292229 unsigned long entry_ip ;
22302230};
22312231
2232+ struct user_syms {
2233+ const char * * syms ;
2234+ char * buf ;
2235+ };
2236+
2237+ static int copy_user_syms (struct user_syms * us , unsigned long __user * usyms , u32 cnt )
2238+ {
2239+ unsigned long __user usymbol ;
2240+ const char * * syms = NULL ;
2241+ char * buf = NULL , * p ;
2242+ int err = - ENOMEM ;
2243+ unsigned int i ;
2244+
2245+ syms = kvmalloc (cnt * sizeof (* syms ), GFP_KERNEL );
2246+ if (!syms )
2247+ goto error ;
2248+
2249+ buf = kvmalloc (cnt * KSYM_NAME_LEN , GFP_KERNEL );
2250+ if (!buf )
2251+ goto error ;
2252+
2253+ for (p = buf , i = 0 ; i < cnt ; i ++ ) {
2254+ if (__get_user (usymbol , usyms + i )) {
2255+ err = - EFAULT ;
2256+ goto error ;
2257+ }
2258+ err = strncpy_from_user (p , (const char __user * ) usymbol , KSYM_NAME_LEN );
2259+ if (err == KSYM_NAME_LEN )
2260+ err = - E2BIG ;
2261+ if (err < 0 )
2262+ goto error ;
2263+ syms [i ] = p ;
2264+ p += err + 1 ;
2265+ }
2266+
2267+ us -> syms = syms ;
2268+ us -> buf = buf ;
2269+ return 0 ;
2270+
2271+ error :
2272+ if (err ) {
2273+ kvfree (syms );
2274+ kvfree (buf );
2275+ }
2276+ return err ;
2277+ }
2278+
2279+ static void free_user_syms (struct user_syms * us )
2280+ {
2281+ kvfree (us -> syms );
2282+ kvfree (us -> buf );
2283+ }
2284+
22322285static void bpf_kprobe_multi_link_release (struct bpf_link * link )
22332286{
22342287 struct bpf_kprobe_multi_link * kmulti_link ;
@@ -2349,53 +2402,12 @@ kprobe_multi_link_handler(struct fprobe *fp, unsigned long entry_ip,
23492402 kprobe_multi_link_prog_run (link , entry_ip , regs );
23502403}
23512404
2352- static int
2353- kprobe_multi_resolve_syms (const void __user * usyms , u32 cnt ,
2354- unsigned long * addrs )
2405+ static int symbols_cmp (const void * a , const void * b )
23552406{
2356- unsigned long addr , size ;
2357- const char __user * * syms ;
2358- int err = - ENOMEM ;
2359- unsigned int i ;
2360- char * func ;
2361-
2362- size = cnt * sizeof (* syms );
2363- syms = kvzalloc (size , GFP_KERNEL );
2364- if (!syms )
2365- return - ENOMEM ;
2407+ const char * * str_a = (const char * * ) a ;
2408+ const char * * str_b = (const char * * ) b ;
23662409
2367- func = kmalloc (KSYM_NAME_LEN , GFP_KERNEL );
2368- if (!func )
2369- goto error ;
2370-
2371- if (copy_from_user (syms , usyms , size )) {
2372- err = - EFAULT ;
2373- goto error ;
2374- }
2375-
2376- for (i = 0 ; i < cnt ; i ++ ) {
2377- err = strncpy_from_user (func , syms [i ], KSYM_NAME_LEN );
2378- if (err == KSYM_NAME_LEN )
2379- err = - E2BIG ;
2380- if (err < 0 )
2381- goto error ;
2382- err = - EINVAL ;
2383- addr = kallsyms_lookup_name (func );
2384- if (!addr )
2385- goto error ;
2386- if (!kallsyms_lookup_size_offset (addr , & size , NULL ))
2387- goto error ;
2388- addr = ftrace_location_range (addr , addr + size - 1 );
2389- if (!addr )
2390- goto error ;
2391- addrs [i ] = addr ;
2392- }
2393-
2394- err = 0 ;
2395- error :
2396- kvfree (syms );
2397- kfree (func );
2398- return err ;
2410+ return strcmp (* str_a , * str_b );
23992411}
24002412
24012413int bpf_kprobe_multi_link_attach (const union bpf_attr * attr , struct bpf_prog * prog )
@@ -2441,7 +2453,15 @@ int bpf_kprobe_multi_link_attach(const union bpf_attr *attr, struct bpf_prog *pr
24412453 goto error ;
24422454 }
24432455 } else {
2444- err = kprobe_multi_resolve_syms (usyms , cnt , addrs );
2456+ struct user_syms us ;
2457+
2458+ err = copy_user_syms (& us , usyms , cnt );
2459+ if (err )
2460+ goto error ;
2461+
2462+ sort (us .syms , cnt , sizeof (* us .syms ), symbols_cmp , NULL );
2463+ err = ftrace_lookup_symbols (us .syms , cnt , addrs );
2464+ free_user_syms (& us );
24452465 if (err )
24462466 goto error ;
24472467 }
0 commit comments