@@ -4161,6 +4161,66 @@ static int bpf_iter_create(union bpf_attr *attr)
41614161 return err ;
41624162}
41634163
4164+ #define BPF_PROG_BIND_MAP_LAST_FIELD prog_bind_map.flags
4165+
4166+ static int bpf_prog_bind_map (union bpf_attr * attr )
4167+ {
4168+ struct bpf_prog * prog ;
4169+ struct bpf_map * map ;
4170+ struct bpf_map * * used_maps_old , * * used_maps_new ;
4171+ int i , ret = 0 ;
4172+
4173+ if (CHECK_ATTR (BPF_PROG_BIND_MAP ))
4174+ return - EINVAL ;
4175+
4176+ if (attr -> prog_bind_map .flags )
4177+ return - EINVAL ;
4178+
4179+ prog = bpf_prog_get (attr -> prog_bind_map .prog_fd );
4180+ if (IS_ERR (prog ))
4181+ return PTR_ERR (prog );
4182+
4183+ map = bpf_map_get (attr -> prog_bind_map .map_fd );
4184+ if (IS_ERR (map )) {
4185+ ret = PTR_ERR (map );
4186+ goto out_prog_put ;
4187+ }
4188+
4189+ mutex_lock (& prog -> aux -> used_maps_mutex );
4190+
4191+ used_maps_old = prog -> aux -> used_maps ;
4192+
4193+ for (i = 0 ; i < prog -> aux -> used_map_cnt ; i ++ )
4194+ if (used_maps_old [i ] == map )
4195+ goto out_unlock ;
4196+
4197+ used_maps_new = kmalloc_array (prog -> aux -> used_map_cnt + 1 ,
4198+ sizeof (used_maps_new [0 ]),
4199+ GFP_KERNEL );
4200+ if (!used_maps_new ) {
4201+ ret = - ENOMEM ;
4202+ goto out_unlock ;
4203+ }
4204+
4205+ memcpy (used_maps_new , used_maps_old ,
4206+ sizeof (used_maps_old [0 ]) * prog -> aux -> used_map_cnt );
4207+ used_maps_new [prog -> aux -> used_map_cnt ] = map ;
4208+
4209+ prog -> aux -> used_map_cnt ++ ;
4210+ prog -> aux -> used_maps = used_maps_new ;
4211+
4212+ kfree (used_maps_old );
4213+
4214+ out_unlock :
4215+ mutex_unlock (& prog -> aux -> used_maps_mutex );
4216+
4217+ if (ret )
4218+ bpf_map_put (map );
4219+ out_prog_put :
4220+ bpf_prog_put (prog );
4221+ return ret ;
4222+ }
4223+
41644224SYSCALL_DEFINE3 (bpf , int , cmd , union bpf_attr __user * , uattr , unsigned int , size )
41654225{
41664226 union bpf_attr attr ;
@@ -4294,6 +4354,9 @@ SYSCALL_DEFINE3(bpf, int, cmd, union bpf_attr __user *, uattr, unsigned int, siz
42944354 case BPF_LINK_DETACH :
42954355 err = link_detach (& attr );
42964356 break ;
4357+ case BPF_PROG_BIND_MAP :
4358+ err = bpf_prog_bind_map (& attr );
4359+ break ;
42974360 default :
42984361 err = - EINVAL ;
42994362 break ;
0 commit comments