@@ -1355,55 +1355,116 @@ static bool bpf_net_capable(void)
13551355 return capable (CAP_NET_ADMIN ) || capable (CAP_SYS_ADMIN );
13561356}
13571357
1358+ struct bpf_vlog_wrapper {
1359+ struct bpf_common_attr * attr ;
1360+ struct bpf_verifier_log * log ;
1361+ };
1362+
1363+ static void bpf_vlog_wrapper_destructor (struct bpf_vlog_wrapper * w )
1364+ {
1365+ if (!w -> log )
1366+ return ;
1367+
1368+ (void ) bpf_vlog_finalize (w -> log , & w -> attr -> log_true_size );
1369+ kfree (w -> log );
1370+ }
1371+
1372+ #define DEFINE_BPF_VLOG_WRAPPER (name , common_attrs ) \
1373+ struct bpf_vlog_wrapper name __cleanup(bpf_vlog_wrapper_destructor) = { \
1374+ .attr = common_attrs, \
1375+ }
1376+
1377+ static int bpf_vlog_wrapper_init (struct bpf_vlog_wrapper * w )
1378+ {
1379+ struct bpf_common_attr * attr = w -> attr ;
1380+ struct bpf_verifier_log * log ;
1381+ int err ;
1382+
1383+ if (!attr -> log_buf )
1384+ return 0 ;
1385+
1386+ log = kzalloc (sizeof (* log ), GFP_KERNEL );
1387+ if (!log )
1388+ return - ENOMEM ;
1389+
1390+ err = bpf_vlog_init (log , attr -> log_level , u64_to_user_ptr (attr -> log_buf ), attr -> log_size );
1391+ if (err ) {
1392+ kfree (log );
1393+ return err ;
1394+ }
1395+
1396+ w -> log = log ;
1397+ return 0 ;
1398+ }
1399+
13581400#define BPF_MAP_CREATE_LAST_FIELD excl_prog_hash_size
13591401/* called via syscall */
1360- static int map_create (union bpf_attr * attr , bpfptr_t uattr )
1402+ static int map_create (union bpf_attr * attr , bpfptr_t uattr , struct bpf_common_attr * common_attrs )
13611403{
13621404 const struct bpf_map_ops * ops ;
13631405 struct bpf_token * token = NULL ;
13641406 int numa_node = bpf_map_attr_numa_node (attr );
13651407 u32 map_type = attr -> map_type ;
1408+ struct bpf_verifier_log * log ;
13661409 struct bpf_map * map ;
13671410 bool token_flag ;
13681411 int f_flags ;
13691412 int err ;
1413+ DEFINE_BPF_VLOG_WRAPPER (log_wrapper , common_attrs );
13701414
13711415 err = CHECK_ATTR (BPF_MAP_CREATE );
13721416 if (err )
13731417 return - EINVAL ;
13741418
1419+ err = bpf_vlog_wrapper_init (& log_wrapper );
1420+ if (err )
1421+ return err ;
1422+ log = log_wrapper .log ;
1423+
13751424 /* check BPF_F_TOKEN_FD flag, remember if it's set, and then clear it
13761425 * to avoid per-map type checks tripping on unknown flag
13771426 */
13781427 token_flag = attr -> map_flags & BPF_F_TOKEN_FD ;
13791428 attr -> map_flags &= ~BPF_F_TOKEN_FD ;
13801429
13811430 if (attr -> btf_vmlinux_value_type_id ) {
1382- if (attr -> map_type != BPF_MAP_TYPE_STRUCT_OPS ||
1383- attr -> btf_key_type_id || attr -> btf_value_type_id )
1431+ if (attr -> map_type != BPF_MAP_TYPE_STRUCT_OPS ) {
1432+ bpf_log (log , "btf_vmlinux_value_type_id can only be used with struct_ops maps.\n" );
1433+ return - EINVAL ;
1434+ }
1435+ if (attr -> btf_key_type_id || attr -> btf_value_type_id ) {
1436+ bpf_log (log , "btf_vmlinux_value_type_id is mutually exclusive with btf_key_type_id and btf_value_type_id.\n" );
13841437 return - EINVAL ;
1438+ }
13851439 } else if (attr -> btf_key_type_id && !attr -> btf_value_type_id ) {
1440+ bpf_log (log , "Invalid btf_value_type_id.\n" );
13861441 return - EINVAL ;
13871442 }
13881443
13891444 if (attr -> map_type != BPF_MAP_TYPE_BLOOM_FILTER &&
13901445 attr -> map_type != BPF_MAP_TYPE_ARENA &&
1391- attr -> map_extra != 0 )
1446+ attr -> map_extra != 0 ) {
1447+ bpf_log (log , "Invalid map_extra.\n" );
13921448 return - EINVAL ;
1449+ }
13931450
13941451 f_flags = bpf_get_file_flag (attr -> map_flags );
13951452 if (f_flags < 0 )
13961453 return f_flags ;
13971454
13981455 if (numa_node != NUMA_NO_NODE &&
13991456 ((unsigned int )numa_node >= nr_node_ids ||
1400- !node_online (numa_node )))
1457+ !node_online (numa_node ))) {
1458+ bpf_log (log , "Invalid numa_node.\n" );
14011459 return - EINVAL ;
1460+ }
14021461
14031462 /* find map type and init map: hashtable vs rbtree vs bloom vs ... */
14041463 map_type = attr -> map_type ;
1405- if (map_type >= ARRAY_SIZE (bpf_map_types ))
1464+ if (map_type >= ARRAY_SIZE (bpf_map_types )) {
1465+ bpf_log (log , "Invalid map_type.\n" );
14061466 return - EINVAL ;
1467+ }
14071468 map_type = array_index_nospec (map_type , ARRAY_SIZE (bpf_map_types ));
14081469 ops = bpf_map_types [map_type ];
14091470 if (WARN_ON_ONCE (!ops ))
@@ -1421,8 +1482,10 @@ static int map_create(union bpf_attr *attr, bpfptr_t uattr)
14211482
14221483 if (token_flag ) {
14231484 token = bpf_token_get_from_fd (attr -> map_token_fd );
1424- if (IS_ERR (token ))
1485+ if (IS_ERR (token )) {
1486+ bpf_log (log , "Invalid map_token_fd.\n" );
14251487 return PTR_ERR (token );
1488+ }
14261489
14271490 /* if current token doesn't grant map creation permissions,
14281491 * then we can't use this token, so ignore it and rely on
@@ -1504,8 +1567,10 @@ static int map_create(union bpf_attr *attr, bpfptr_t uattr)
15041567
15051568 err = bpf_obj_name_cpy (map -> name , attr -> map_name ,
15061569 sizeof (attr -> map_name ));
1507- if (err < 0 )
1570+ if (err < 0 ) {
1571+ bpf_log (log , "Invalid map_name.\n" );
15081572 goto free_map ;
1573+ }
15091574
15101575 preempt_disable ();
15111576 map -> cookie = gen_cookie_next (& bpf_map_cookie );
@@ -1528,6 +1593,7 @@ static int map_create(union bpf_attr *attr, bpfptr_t uattr)
15281593
15291594 btf = btf_get_by_fd (attr -> btf_fd );
15301595 if (IS_ERR (btf )) {
1596+ bpf_log (log , "Invalid btf_fd.\n" );
15311597 err = PTR_ERR (btf );
15321598 goto free_map ;
15331599 }
@@ -6132,6 +6198,15 @@ static int __copy_common_attr_log_true_size(bpfptr_t uattr, unsigned int size, u
61326198 return 0 ;
61336199}
61346200
6201+ static int copy_common_attr_log_true_size (bpfptr_t uattr , unsigned int size ,
6202+ struct bpf_common_attr * attr )
6203+ {
6204+ if (!attr -> log_true_size )
6205+ return 0 ;
6206+
6207+ return __copy_common_attr_log_true_size (uattr , size , & attr -> log_true_size );
6208+ }
6209+
61356210static int copy_prog_load_log_true_size (union bpf_attr * attr , bpfptr_t uattr , unsigned int size ,
61366211 struct bpf_common_attr * common_attrs , bpfptr_t uattr_common ,
61376212 unsigned int size_common , bool log_common_attrs )
@@ -6226,7 +6301,10 @@ static int __sys_bpf(enum bpf_cmd cmd, bpfptr_t uattr, unsigned int size,
62266301
62276302 switch (cmd ) {
62286303 case BPF_MAP_CREATE :
6229- err = map_create (& attr , uattr );
6304+ common_attrs .log_true_size = 0 ;
6305+ err = map_create (& attr , uattr , & common_attrs );
6306+ ret = copy_common_attr_log_true_size (uattr_common , size_common , & common_attrs );
6307+ err = ret ? ret : err ;
62306308 break ;
62316309 case BPF_MAP_LOOKUP_ELEM :
62326310 err = map_lookup_elem (& attr );
0 commit comments