Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'bpf-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf

Pull bpf fixes from Daniel Borkmann::

- Fix several issues for BPF LPM trie map which were found by syzbot
and during addition of new test cases (Hou Tao)

- Fix a missing process_iter_arg register type check in the BPF
verifier (Kumar Kartikeya Dwivedi, Tao Lyu)

- Fix several correctness gaps in the BPF verifier when interacting
with the BPF stack without CAP_PERFMON (Kumar Kartikeya Dwivedi,
Eduard Zingerman, Tao Lyu)

- Fix OOB BPF map writes when deleting elements for the case of xsk map
as well as devmap (Maciej Fijalkowski)

- Fix xsk sockets to always clear DMA mapping information when
unmapping the pool (Larysa Zaremba)

- Fix sk_mem_uncharge logic in tcp_bpf_sendmsg to only uncharge after
sent bytes have been finalized (Zijian Zhang)

- Fix BPF sockmap with vsocks which was missing a queue check in poll
and sockmap cleanup on close (Michal Luczaj)

- Fix tools infra to override makefile ARCH variable if defined but
empty, which addresses cross-building tools. (Björn Töpel)

- Fix two resolve_btfids build warnings on unresolved bpf_lsm symbols
(Thomas Weißschuh)

- Fix a NULL pointer dereference in bpftool (Amir Mohammadi)

- Fix BPF selftests to check for CONFIG_PREEMPTION instead of
CONFIG_PREEMPT (Sebastian Andrzej Siewior)

* tag 'bpf-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf: (31 commits)
selftests/bpf: Add more test cases for LPM trie
selftests/bpf: Move test_lpm_map.c to map_tests
bpf: Use raw_spinlock_t for LPM trie
bpf: Switch to bpf mem allocator for LPM trie
bpf: Fix exact match conditions in trie_get_next_key()
bpf: Handle in-place update for full LPM trie correctly
bpf: Handle BPF_EXIST and BPF_NOEXIST for LPM trie
bpf: Remove unnecessary kfree(im_node) in lpm_trie_update_elem
bpf: Remove unnecessary check when updating LPM trie
selftests/bpf: Add test for narrow spill into 64-bit spilled scalar
selftests/bpf: Add test for reading from STACK_INVALID slots
selftests/bpf: Introduce __caps_unpriv annotation for tests
bpf: Fix narrow scalar spill onto 64-bit spilled scalar slots
bpf: Don't mark STACK_INVALID as STACK_MISC in mark_stack_slot_misc
samples/bpf: Remove unnecessary -I flags from libbpf EXTRA_CFLAGS
bpf: Zero index arg error string for dynptr and iter
selftests/bpf: Add tests for iter arg check
bpf: Ensure reg is PTR_TO_STACK in process_iter_arg
tools: Override makefile ARCH variable if defined, but empty
selftests/bpf: Add apply_bytes test to test_txmsg_redir_wait_sndmem in test_sockmap
...

+813 -174
-2
kernel/bpf/bpf_lsm.c
··· 375 375 376 376 BTF_ID(func, bpf_lsm_syslog) 377 377 BTF_ID(func, bpf_lsm_task_alloc) 378 - BTF_ID(func, bpf_lsm_current_getsecid_subj) 379 - BTF_ID(func, bpf_lsm_task_getsecid_obj) 380 378 BTF_ID(func, bpf_lsm_task_prctl) 381 379 BTF_ID(func, bpf_lsm_task_setscheduler) 382 380 BTF_ID(func, bpf_lsm_task_to_inode)
+3 -3
kernel/bpf/devmap.c
··· 184 184 static void dev_map_free(struct bpf_map *map) 185 185 { 186 186 struct bpf_dtab *dtab = container_of(map, struct bpf_dtab, map); 187 - int i; 187 + u32 i; 188 188 189 189 /* At this point bpf_prog->aux->refcnt == 0 and this map->refcnt == 0, 190 190 * so the programs (can be more than one that used this map) were ··· 821 821 { 822 822 struct bpf_dtab *dtab = container_of(map, struct bpf_dtab, map); 823 823 struct bpf_dtab_netdev *old_dev; 824 - int k = *(u32 *)key; 824 + u32 k = *(u32 *)key; 825 825 826 826 if (k >= map->max_entries) 827 827 return -EINVAL; ··· 838 838 { 839 839 struct bpf_dtab *dtab = container_of(map, struct bpf_dtab, map); 840 840 struct bpf_dtab_netdev *old_dev; 841 - int k = *(u32 *)key; 841 + u32 k = *(u32 *)key; 842 842 unsigned long flags; 843 843 int ret = -ENOENT; 844 844
+85 -48
kernel/bpf/lpm_trie.c
··· 15 15 #include <net/ipv6.h> 16 16 #include <uapi/linux/btf.h> 17 17 #include <linux/btf_ids.h> 18 + #include <linux/bpf_mem_alloc.h> 18 19 19 20 /* Intermediate node */ 20 21 #define LPM_TREE_NODE_FLAG_IM BIT(0) ··· 23 22 struct lpm_trie_node; 24 23 25 24 struct lpm_trie_node { 26 - struct rcu_head rcu; 27 25 struct lpm_trie_node __rcu *child[2]; 28 26 u32 prefixlen; 29 27 u32 flags; ··· 32 32 struct lpm_trie { 33 33 struct bpf_map map; 34 34 struct lpm_trie_node __rcu *root; 35 + struct bpf_mem_alloc ma; 35 36 size_t n_entries; 36 37 size_t max_prefixlen; 37 38 size_t data_size; 38 - spinlock_t lock; 39 + raw_spinlock_t lock; 39 40 }; 40 41 41 42 /* This trie implements a longest prefix match algorithm that can be used to ··· 288 287 return found->data + trie->data_size; 289 288 } 290 289 291 - static struct lpm_trie_node *lpm_trie_node_alloc(const struct lpm_trie *trie, 292 - const void *value) 290 + static struct lpm_trie_node *lpm_trie_node_alloc(struct lpm_trie *trie, 291 + const void *value, 292 + bool disable_migration) 293 293 { 294 294 struct lpm_trie_node *node; 295 - size_t size = sizeof(struct lpm_trie_node) + trie->data_size; 296 295 297 - if (value) 298 - size += trie->map.value_size; 296 + if (disable_migration) 297 + migrate_disable(); 298 + node = bpf_mem_cache_alloc(&trie->ma); 299 + if (disable_migration) 300 + migrate_enable(); 299 301 300 - node = bpf_map_kmalloc_node(&trie->map, size, GFP_NOWAIT | __GFP_NOWARN, 301 - trie->map.numa_node); 302 302 if (!node) 303 303 return NULL; 304 304 ··· 312 310 return node; 313 311 } 314 312 313 + static int trie_check_add_elem(struct lpm_trie *trie, u64 flags) 314 + { 315 + if (flags == BPF_EXIST) 316 + return -ENOENT; 317 + if (trie->n_entries == trie->map.max_entries) 318 + return -ENOSPC; 319 + trie->n_entries++; 320 + return 0; 321 + } 322 + 315 323 /* Called from syscall or from eBPF program */ 316 324 static long trie_update_elem(struct bpf_map *map, 317 325 void *_key, void *value, u64 flags) 318 326 { 319 327 struct lpm_trie *trie = container_of(map, struct lpm_trie, map); 320 - struct lpm_trie_node *node, *im_node = NULL, *new_node = NULL; 328 + struct lpm_trie_node *node, *im_node, *new_node; 321 329 struct lpm_trie_node *free_node = NULL; 322 330 struct lpm_trie_node __rcu **slot; 323 331 struct bpf_lpm_trie_key_u8 *key = _key; ··· 342 330 if (key->prefixlen > trie->max_prefixlen) 343 331 return -EINVAL; 344 332 345 - spin_lock_irqsave(&trie->lock, irq_flags); 333 + /* Allocate and fill a new node. Need to disable migration before 334 + * invoking bpf_mem_cache_alloc(). 335 + */ 336 + new_node = lpm_trie_node_alloc(trie, value, true); 337 + if (!new_node) 338 + return -ENOMEM; 346 339 347 - /* Allocate and fill a new node */ 348 - 349 - if (trie->n_entries == trie->map.max_entries) { 350 - ret = -ENOSPC; 351 - goto out; 352 - } 353 - 354 - new_node = lpm_trie_node_alloc(trie, value); 355 - if (!new_node) { 356 - ret = -ENOMEM; 357 - goto out; 358 - } 359 - 360 - trie->n_entries++; 340 + raw_spin_lock_irqsave(&trie->lock, irq_flags); 361 341 362 342 new_node->prefixlen = key->prefixlen; 363 343 RCU_INIT_POINTER(new_node->child[0], NULL); ··· 368 364 matchlen = longest_prefix_match(trie, node, key); 369 365 370 366 if (node->prefixlen != matchlen || 371 - node->prefixlen == key->prefixlen || 372 - node->prefixlen == trie->max_prefixlen) 367 + node->prefixlen == key->prefixlen) 373 368 break; 374 369 375 370 next_bit = extract_bit(key->data, node->prefixlen); ··· 379 376 * simply assign the @new_node to that slot and be done. 380 377 */ 381 378 if (!node) { 379 + ret = trie_check_add_elem(trie, flags); 380 + if (ret) 381 + goto out; 382 + 382 383 rcu_assign_pointer(*slot, new_node); 383 384 goto out; 384 385 } ··· 391 384 * which already has the correct data array set. 392 385 */ 393 386 if (node->prefixlen == matchlen) { 387 + if (!(node->flags & LPM_TREE_NODE_FLAG_IM)) { 388 + if (flags == BPF_NOEXIST) { 389 + ret = -EEXIST; 390 + goto out; 391 + } 392 + } else { 393 + ret = trie_check_add_elem(trie, flags); 394 + if (ret) 395 + goto out; 396 + } 397 + 394 398 new_node->child[0] = node->child[0]; 395 399 new_node->child[1] = node->child[1]; 396 - 397 - if (!(node->flags & LPM_TREE_NODE_FLAG_IM)) 398 - trie->n_entries--; 399 400 400 401 rcu_assign_pointer(*slot, new_node); 401 402 free_node = node; 402 403 403 404 goto out; 404 405 } 406 + 407 + ret = trie_check_add_elem(trie, flags); 408 + if (ret) 409 + goto out; 405 410 406 411 /* If the new node matches the prefix completely, it must be inserted 407 412 * as an ancestor. Simply insert it between @node and *@slot. ··· 425 406 goto out; 426 407 } 427 408 428 - im_node = lpm_trie_node_alloc(trie, NULL); 409 + /* migration is disabled within the locked scope */ 410 + im_node = lpm_trie_node_alloc(trie, NULL, false); 429 411 if (!im_node) { 412 + trie->n_entries--; 430 413 ret = -ENOMEM; 431 414 goto out; 432 415 } ··· 450 429 rcu_assign_pointer(*slot, im_node); 451 430 452 431 out: 453 - if (ret) { 454 - if (new_node) 455 - trie->n_entries--; 432 + raw_spin_unlock_irqrestore(&trie->lock, irq_flags); 456 433 457 - kfree(new_node); 458 - kfree(im_node); 459 - } 460 - 461 - spin_unlock_irqrestore(&trie->lock, irq_flags); 462 - kfree_rcu(free_node, rcu); 434 + migrate_disable(); 435 + if (ret) 436 + bpf_mem_cache_free(&trie->ma, new_node); 437 + bpf_mem_cache_free_rcu(&trie->ma, free_node); 438 + migrate_enable(); 463 439 464 440 return ret; 465 441 } ··· 477 459 if (key->prefixlen > trie->max_prefixlen) 478 460 return -EINVAL; 479 461 480 - spin_lock_irqsave(&trie->lock, irq_flags); 462 + raw_spin_lock_irqsave(&trie->lock, irq_flags); 481 463 482 464 /* Walk the tree looking for an exact key/length match and keeping 483 465 * track of the path we traverse. We will need to know the node ··· 553 535 free_node = node; 554 536 555 537 out: 556 - spin_unlock_irqrestore(&trie->lock, irq_flags); 557 - kfree_rcu(free_parent, rcu); 558 - kfree_rcu(free_node, rcu); 538 + raw_spin_unlock_irqrestore(&trie->lock, irq_flags); 539 + 540 + migrate_disable(); 541 + bpf_mem_cache_free_rcu(&trie->ma, free_parent); 542 + bpf_mem_cache_free_rcu(&trie->ma, free_node); 543 + migrate_enable(); 559 544 560 545 return ret; 561 546 } ··· 580 559 static struct bpf_map *trie_alloc(union bpf_attr *attr) 581 560 { 582 561 struct lpm_trie *trie; 562 + size_t leaf_size; 563 + int err; 583 564 584 565 /* check sanity of attributes */ 585 566 if (attr->max_entries == 0 || ··· 604 581 offsetof(struct bpf_lpm_trie_key_u8, data); 605 582 trie->max_prefixlen = trie->data_size * 8; 606 583 607 - spin_lock_init(&trie->lock); 584 + raw_spin_lock_init(&trie->lock); 608 585 586 + /* Allocate intermediate and leaf nodes from the same allocator */ 587 + leaf_size = sizeof(struct lpm_trie_node) + trie->data_size + 588 + trie->map.value_size; 589 + err = bpf_mem_alloc_init(&trie->ma, leaf_size, false); 590 + if (err) 591 + goto free_out; 609 592 return &trie->map; 593 + 594 + free_out: 595 + bpf_map_area_free(trie); 596 + return ERR_PTR(err); 610 597 } 611 598 612 599 static void trie_free(struct bpf_map *map) ··· 648 615 continue; 649 616 } 650 617 651 - kfree(node); 618 + /* No bpf program may access the map, so freeing the 619 + * node without waiting for the extra RCU GP. 620 + */ 621 + bpf_mem_cache_raw_free(node); 652 622 RCU_INIT_POINTER(*slot, NULL); 653 623 break; 654 624 } 655 625 } 656 626 657 627 out: 628 + bpf_mem_alloc_destroy(&trie->ma); 658 629 bpf_map_area_free(trie); 659 630 } 660 631 ··· 670 633 struct lpm_trie_node **node_stack = NULL; 671 634 int err = 0, stack_ptr = -1; 672 635 unsigned int next_bit; 673 - size_t matchlen; 636 + size_t matchlen = 0; 674 637 675 638 /* The get_next_key follows postorder. For the 4 node example in 676 639 * the top of this file, the trie_get_next_key() returns the following ··· 709 672 next_bit = extract_bit(key->data, node->prefixlen); 710 673 node = rcu_dereference(node->child[next_bit]); 711 674 } 712 - if (!node || node->prefixlen != key->prefixlen || 675 + if (!node || node->prefixlen != matchlen || 713 676 (node->flags & LPM_TREE_NODE_FLAG_IM)) 714 677 goto find_leftmost; 715 678
+18 -9
kernel/bpf/verifier.c
··· 1202 1202 /* Mark stack slot as STACK_MISC, unless it is already STACK_INVALID, in which 1203 1203 * case they are equivalent, or it's STACK_ZERO, in which case we preserve 1204 1204 * more precise STACK_ZERO. 1205 - * Note, in uprivileged mode leaving STACK_INVALID is wrong, so we take 1206 - * env->allow_ptr_leaks into account and force STACK_MISC, if necessary. 1205 + * Regardless of allow_ptr_leaks setting (i.e., privileged or unprivileged 1206 + * mode), we won't promote STACK_INVALID to STACK_MISC. In privileged case it is 1207 + * unnecessary as both are considered equivalent when loading data and pruning, 1208 + * in case of unprivileged mode it will be incorrect to allow reads of invalid 1209 + * slots. 1207 1210 */ 1208 1211 static void mark_stack_slot_misc(struct bpf_verifier_env *env, u8 *stype) 1209 1212 { 1210 1213 if (*stype == STACK_ZERO) 1211 1214 return; 1212 - if (env->allow_ptr_leaks && *stype == STACK_INVALID) 1215 + if (*stype == STACK_INVALID) 1213 1216 return; 1214 1217 *stype = STACK_MISC; 1215 1218 } ··· 4703 4700 */ 4704 4701 if (!env->allow_ptr_leaks && 4705 4702 is_spilled_reg(&state->stack[spi]) && 4703 + !is_spilled_scalar_reg(&state->stack[spi]) && 4706 4704 size != BPF_REG_SIZE) { 4707 4705 verbose(env, "attempt to corrupt spilled pointer on stack\n"); 4708 4706 return -EACCES; ··· 8075 8071 if (reg->type != PTR_TO_STACK && reg->type != CONST_PTR_TO_DYNPTR) { 8076 8072 verbose(env, 8077 8073 "arg#%d expected pointer to stack or const struct bpf_dynptr\n", 8078 - regno); 8074 + regno - 1); 8079 8075 return -EINVAL; 8080 8076 } 8081 8077 ··· 8129 8125 if (!is_dynptr_reg_valid_init(env, reg)) { 8130 8126 verbose(env, 8131 8127 "Expected an initialized dynptr as arg #%d\n", 8132 - regno); 8128 + regno - 1); 8133 8129 return -EINVAL; 8134 8130 } 8135 8131 ··· 8137 8133 if (!is_dynptr_type_expected(env, reg, arg_type & ~MEM_RDONLY)) { 8138 8134 verbose(env, 8139 8135 "Expected a dynptr of type %s as arg #%d\n", 8140 - dynptr_type_str(arg_to_dynptr_type(arg_type)), regno); 8136 + dynptr_type_str(arg_to_dynptr_type(arg_type)), regno - 1); 8141 8137 return -EINVAL; 8142 8138 } 8143 8139 ··· 8193 8189 const struct btf_type *t; 8194 8190 int spi, err, i, nr_slots, btf_id; 8195 8191 8192 + if (reg->type != PTR_TO_STACK) { 8193 + verbose(env, "arg#%d expected pointer to an iterator on stack\n", regno - 1); 8194 + return -EINVAL; 8195 + } 8196 + 8196 8197 /* For iter_{new,next,destroy} functions, btf_check_iter_kfuncs() 8197 8198 * ensures struct convention, so we wouldn't need to do any BTF 8198 8199 * validation here. But given iter state can be passed as a parameter ··· 8206 8197 */ 8207 8198 btf_id = btf_check_iter_arg(meta->btf, meta->func_proto, regno - 1); 8208 8199 if (btf_id < 0) { 8209 - verbose(env, "expected valid iter pointer as arg #%d\n", regno); 8200 + verbose(env, "expected valid iter pointer as arg #%d\n", regno - 1); 8210 8201 return -EINVAL; 8211 8202 } 8212 8203 t = btf_type_by_id(meta->btf, btf_id); ··· 8216 8207 /* bpf_iter_<type>_new() expects pointer to uninit iter state */ 8217 8208 if (!is_iter_reg_valid_uninit(env, reg, nr_slots)) { 8218 8209 verbose(env, "expected uninitialized iter_%s as arg #%d\n", 8219 - iter_type_str(meta->btf, btf_id), regno); 8210 + iter_type_str(meta->btf, btf_id), regno - 1); 8220 8211 return -EINVAL; 8221 8212 } 8222 8213 ··· 8240 8231 break; 8241 8232 case -EINVAL: 8242 8233 verbose(env, "expected an initialized iter_%s as arg #%d\n", 8243 - iter_type_str(meta->btf, btf_id), regno); 8234 + iter_type_str(meta->btf, btf_id), regno - 1); 8244 8235 return err; 8245 8236 case -EPROTO: 8246 8237 verbose(env, "expected an RCU CS when using %s\n", meta->func_name);
+4 -7
net/ipv4/tcp_bpf.c
··· 441 441 cork = true; 442 442 psock->cork = NULL; 443 443 } 444 - sk_msg_return(sk, msg, tosend); 445 444 release_sock(sk); 446 445 447 446 origsize = msg->sg.size; ··· 452 453 sock_put(sk_redir); 453 454 454 455 lock_sock(sk); 456 + sk_mem_uncharge(sk, sent); 455 457 if (unlikely(ret < 0)) { 456 - int free = sk_msg_free_nocharge(sk, msg); 458 + int free = sk_msg_free(sk, msg); 457 459 458 460 if (!cork) 459 461 *copied -= free; ··· 468 468 break; 469 469 case __SK_DROP: 470 470 default: 471 - sk_msg_free_partial(sk, msg, tosend); 471 + sk_msg_free(sk, msg); 472 472 sk_msg_apply_bytes(psock, tosend); 473 473 *copied -= (tosend + delta); 474 474 return -EACCES; ··· 484 484 } 485 485 if (msg && 486 486 msg->sg.data[msg->sg.start].page_link && 487 - msg->sg.data[msg->sg.start].length) { 488 - if (eval == __SK_REDIRECT) 489 - sk_mem_charge(sk, tosend - sent); 487 + msg->sg.data[msg->sg.start].length) 490 488 goto more_data; 491 - } 492 489 } 493 490 return ret; 494 491 }
+43 -27
net/vmw_vsock/af_vsock.c
··· 117 117 static int __vsock_bind(struct sock *sk, struct sockaddr_vm *addr); 118 118 static void vsock_sk_destruct(struct sock *sk); 119 119 static int vsock_queue_rcv_skb(struct sock *sk, struct sk_buff *skb); 120 + static void vsock_close(struct sock *sk, long timeout); 120 121 121 122 /* Protocol family. */ 122 123 struct proto vsock_proto = { 123 124 .name = "AF_VSOCK", 124 125 .owner = THIS_MODULE, 125 126 .obj_size = sizeof(struct vsock_sock), 127 + .close = vsock_close, 126 128 #ifdef CONFIG_BPF_SYSCALL 127 129 .psock_update_sk_prot = vsock_bpf_update_proto, 128 130 #endif ··· 799 797 800 798 static void __vsock_release(struct sock *sk, int level) 801 799 { 802 - if (sk) { 803 - struct sock *pending; 804 - struct vsock_sock *vsk; 800 + struct vsock_sock *vsk; 801 + struct sock *pending; 805 802 806 - vsk = vsock_sk(sk); 807 - pending = NULL; /* Compiler warning. */ 803 + vsk = vsock_sk(sk); 804 + pending = NULL; /* Compiler warning. */ 808 805 809 - /* When "level" is SINGLE_DEPTH_NESTING, use the nested 810 - * version to avoid the warning "possible recursive locking 811 - * detected". When "level" is 0, lock_sock_nested(sk, level) 812 - * is the same as lock_sock(sk). 813 - */ 814 - lock_sock_nested(sk, level); 806 + /* When "level" is SINGLE_DEPTH_NESTING, use the nested 807 + * version to avoid the warning "possible recursive locking 808 + * detected". When "level" is 0, lock_sock_nested(sk, level) 809 + * is the same as lock_sock(sk). 810 + */ 811 + lock_sock_nested(sk, level); 815 812 816 - if (vsk->transport) 817 - vsk->transport->release(vsk); 818 - else if (sock_type_connectible(sk->sk_type)) 819 - vsock_remove_sock(vsk); 813 + if (vsk->transport) 814 + vsk->transport->release(vsk); 815 + else if (sock_type_connectible(sk->sk_type)) 816 + vsock_remove_sock(vsk); 820 817 821 - sock_orphan(sk); 822 - sk->sk_shutdown = SHUTDOWN_MASK; 818 + sock_orphan(sk); 819 + sk->sk_shutdown = SHUTDOWN_MASK; 823 820 824 - skb_queue_purge(&sk->sk_receive_queue); 821 + skb_queue_purge(&sk->sk_receive_queue); 825 822 826 - /* Clean up any sockets that never were accepted. */ 827 - while ((pending = vsock_dequeue_accept(sk)) != NULL) { 828 - __vsock_release(pending, SINGLE_DEPTH_NESTING); 829 - sock_put(pending); 830 - } 831 - 832 - release_sock(sk); 833 - sock_put(sk); 823 + /* Clean up any sockets that never were accepted. */ 824 + while ((pending = vsock_dequeue_accept(sk)) != NULL) { 825 + __vsock_release(pending, SINGLE_DEPTH_NESTING); 826 + sock_put(pending); 834 827 } 828 + 829 + release_sock(sk); 830 + sock_put(sk); 835 831 } 836 832 837 833 static void vsock_sk_destruct(struct sock *sk) ··· 901 901 } 902 902 EXPORT_SYMBOL_GPL(vsock_data_ready); 903 903 904 + /* Dummy callback required by sockmap. 905 + * See unconditional call of saved_close() in sock_map_close(). 906 + */ 907 + static void vsock_close(struct sock *sk, long timeout) 908 + { 909 + } 910 + 904 911 static int vsock_release(struct socket *sock) 905 912 { 906 - __vsock_release(sock->sk, 0); 913 + struct sock *sk = sock->sk; 914 + 915 + if (!sk) 916 + return 0; 917 + 918 + sk->sk_prot->close(sk, 0); 919 + __vsock_release(sk, 0); 907 920 sock->sk = NULL; 908 921 sock->state = SS_FREE; 909 922 ··· 1066 1053 vsk->peer_shutdown & SEND_SHUTDOWN) { 1067 1054 mask |= EPOLLRDHUP; 1068 1055 } 1056 + 1057 + if (sk_is_readable(sk)) 1058 + mask |= EPOLLIN | EPOLLRDNORM; 1069 1059 1070 1060 if (sock->type == SOCK_DGRAM) { 1071 1061 /* For datagram sockets we can read if there is something in
+2 -3
net/xdp/xsk_buff_pool.c
··· 387 387 return; 388 388 } 389 389 390 - if (!refcount_dec_and_test(&dma_map->users)) 391 - return; 390 + if (refcount_dec_and_test(&dma_map->users)) 391 + __xp_dma_unmap(dma_map, attrs); 392 392 393 - __xp_dma_unmap(dma_map, attrs); 394 393 kvfree(pool->dma_pages); 395 394 pool->dma_pages = NULL; 396 395 pool->dma_pages_cnt = 0;
+1 -1
net/xdp/xskmap.c
··· 224 224 struct xsk_map *m = container_of(map, struct xsk_map, map); 225 225 struct xdp_sock __rcu **map_entry; 226 226 struct xdp_sock *old_xs; 227 - int k = *(u32 *)key; 227 + u32 k = *(u32 *)key; 228 228 229 229 if (k >= map->max_entries) 230 230 return -EINVAL;
+7 -6
samples/bpf/Makefile
··· 146 146 BPF_EXTRA_CFLAGS += -fcf-protection 147 147 endif 148 148 149 - TPROGS_CFLAGS += -Wall -O2 150 - TPROGS_CFLAGS += -Wmissing-prototypes 151 - TPROGS_CFLAGS += -Wstrict-prototypes 152 - TPROGS_CFLAGS += $(call try-run,\ 149 + COMMON_CFLAGS += -Wall -O2 150 + COMMON_CFLAGS += -Wmissing-prototypes 151 + COMMON_CFLAGS += -Wstrict-prototypes 152 + COMMON_CFLAGS += $(call try-run,\ 153 153 printf "int main() { return 0; }" |\ 154 154 $(CC) -Werror -fsanitize=bounds -x c - -o "$$TMP",-fsanitize=bounds,) 155 155 156 + TPROGS_CFLAGS += $(COMMON_CFLAGS) 156 157 TPROGS_CFLAGS += -I$(objtree)/usr/include 157 158 TPROGS_CFLAGS += -I$(srctree)/tools/testing/selftests/bpf/ 158 159 TPROGS_CFLAGS += -I$(LIBBPF_INCLUDE) ··· 163 162 TPROGS_CFLAGS += -DHAVE_ATTR_TEST=0 164 163 165 164 ifdef SYSROOT 166 - TPROGS_CFLAGS += --sysroot=$(SYSROOT) 165 + COMMON_CFLAGS += --sysroot=$(SYSROOT) 167 166 TPROGS_LDFLAGS := -L$(SYSROOT)/usr/lib 168 167 endif 169 168 ··· 230 229 231 230 $(LIBBPF): $(wildcard $(LIBBPF_SRC)/*.[ch] $(LIBBPF_SRC)/Makefile) | $(LIBBPF_OUTPUT) 232 231 # Fix up variables inherited from Kbuild that tools/ build system won't like 233 - $(MAKE) -C $(LIBBPF_SRC) RM='rm -rf' EXTRA_CFLAGS="$(TPROGS_CFLAGS)" \ 232 + $(MAKE) -C $(LIBBPF_SRC) RM='rm -rf' EXTRA_CFLAGS="$(COMMON_CFLAGS)" \ 234 233 LDFLAGS="$(TPROGS_LDFLAGS)" srctree=$(BPF_SAMPLES_PATH)/../../ \ 235 234 O= OUTPUT=$(LIBBPF_OUTPUT)/ DESTDIR=$(LIBBPF_DESTDIR) prefix= \ 236 235 $@ install_headers
+12 -5
tools/bpf/bpftool/prog.c
··· 822 822 printf("%s:\n", sym_name); 823 823 } 824 824 825 - if (disasm_print_insn(img, lens[i], opcodes, 826 - name, disasm_opt, btf, 827 - prog_linfo, ksyms[i], i, 828 - linum)) 829 - goto exit_free; 825 + if (ksyms) { 826 + if (disasm_print_insn(img, lens[i], opcodes, 827 + name, disasm_opt, btf, 828 + prog_linfo, ksyms[i], i, 829 + linum)) 830 + goto exit_free; 831 + } else { 832 + if (disasm_print_insn(img, lens[i], opcodes, 833 + name, disasm_opt, btf, 834 + NULL, 0, 0, false)) 835 + goto exit_free; 836 + } 830 837 831 838 img += lens[i]; 832 839
+2 -2
tools/scripts/Makefile.arch
··· 7 7 -e s/sh[234].*/sh/ -e s/aarch64.*/arm64/ \ 8 8 -e s/riscv.*/riscv/ -e s/loongarch.*/loongarch/) 9 9 10 - ifndef ARCH 11 - ARCH := $(HOSTARCH) 10 + ifeq ($(strip $(ARCH)),) 11 + override ARCH := $(HOSTARCH) 12 12 endif 13 13 14 14 SRCARCH := $(ARCH)
-1
tools/testing/selftests/bpf/.gitignore
··· 5 5 test_verifier 6 6 test_maps 7 7 test_lru_map 8 - test_lpm_map 9 8 test_tag 10 9 FEATURE-DUMP.libbpf 11 10 FEATURE-DUMP.selftests
+1 -1
tools/testing/selftests/bpf/Makefile
··· 83 83 endif 84 84 85 85 # Order correspond to 'make run_tests' order 86 - TEST_GEN_PROGS = test_verifier test_tag test_maps test_lru_map test_lpm_map test_progs \ 86 + TEST_GEN_PROGS = test_verifier test_tag test_maps test_lru_map test_progs \ 87 87 test_sockmap \ 88 88 test_tcpnotify_user test_sysctl \ 89 89 test_progs-no_alu32
+2 -2
tools/testing/selftests/bpf/map_tests/task_storage_map.c
··· 78 78 CHECK(err, "open_and_load", "error %d\n", err); 79 79 80 80 /* Only for a fully preemptible kernel */ 81 - if (!skel->kconfig->CONFIG_PREEMPT) { 82 - printf("%s SKIP (no CONFIG_PREEMPT)\n", __func__); 81 + if (!skel->kconfig->CONFIG_PREEMPTION) { 82 + printf("%s SKIP (no CONFIG_PREEMPTION)\n", __func__); 83 83 read_bpf_task_storage_busy__destroy(skel); 84 84 skips++; 85 85 return;
+77
tools/testing/selftests/bpf/prog_tests/sockmap_basic.c
··· 108 108 close(s); 109 109 } 110 110 111 + static void test_sockmap_vsock_delete_on_close(void) 112 + { 113 + int err, c, p, map; 114 + const int zero = 0; 115 + 116 + err = create_pair(AF_VSOCK, SOCK_STREAM, &c, &p); 117 + if (!ASSERT_OK(err, "create_pair(AF_VSOCK)")) 118 + return; 119 + 120 + map = bpf_map_create(BPF_MAP_TYPE_SOCKMAP, NULL, sizeof(int), 121 + sizeof(int), 1, NULL); 122 + if (!ASSERT_GE(map, 0, "bpf_map_create")) { 123 + close(c); 124 + goto out; 125 + } 126 + 127 + err = bpf_map_update_elem(map, &zero, &c, BPF_NOEXIST); 128 + close(c); 129 + if (!ASSERT_OK(err, "bpf_map_update")) 130 + goto out; 131 + 132 + err = bpf_map_update_elem(map, &zero, &p, BPF_NOEXIST); 133 + ASSERT_OK(err, "after close(), bpf_map_update"); 134 + 135 + out: 136 + close(p); 137 + close(map); 138 + } 139 + 111 140 static void test_skmsg_helpers(enum bpf_map_type map_type) 112 141 { 113 142 struct test_skmsg_load_helpers *skel; ··· 966 937 test_sockmap_pass_prog__destroy(skel); 967 938 } 968 939 940 + static void test_sockmap_skb_verdict_vsock_poll(void) 941 + { 942 + struct test_sockmap_pass_prog *skel; 943 + int err, map, conn, peer; 944 + struct bpf_program *prog; 945 + struct bpf_link *link; 946 + char buf = 'x'; 947 + int zero = 0; 948 + 949 + skel = test_sockmap_pass_prog__open_and_load(); 950 + if (!ASSERT_OK_PTR(skel, "open_and_load")) 951 + return; 952 + 953 + if (create_pair(AF_VSOCK, SOCK_STREAM, &conn, &peer)) 954 + goto destroy; 955 + 956 + prog = skel->progs.prog_skb_verdict; 957 + map = bpf_map__fd(skel->maps.sock_map_rx); 958 + link = bpf_program__attach_sockmap(prog, map); 959 + if (!ASSERT_OK_PTR(link, "bpf_program__attach_sockmap")) 960 + goto close; 961 + 962 + err = bpf_map_update_elem(map, &zero, &conn, BPF_ANY); 963 + if (!ASSERT_OK(err, "bpf_map_update_elem")) 964 + goto detach; 965 + 966 + if (xsend(peer, &buf, 1, 0) != 1) 967 + goto detach; 968 + 969 + err = poll_read(conn, IO_TIMEOUT_SEC); 970 + if (!ASSERT_OK(err, "poll")) 971 + goto detach; 972 + 973 + if (xrecv_nonblock(conn, &buf, 1, 0) != 1) 974 + FAIL("xrecv_nonblock"); 975 + detach: 976 + bpf_link__detach(link); 977 + close: 978 + xclose(conn); 979 + xclose(peer); 980 + destroy: 981 + test_sockmap_pass_prog__destroy(skel); 982 + } 983 + 969 984 void test_sockmap_basic(void) 970 985 { 971 986 if (test__start_subtest("sockmap create_update_free")) 972 987 test_sockmap_create_update_free(BPF_MAP_TYPE_SOCKMAP); 973 988 if (test__start_subtest("sockhash create_update_free")) 974 989 test_sockmap_create_update_free(BPF_MAP_TYPE_SOCKHASH); 990 + if (test__start_subtest("sockmap vsock delete on close")) 991 + test_sockmap_vsock_delete_on_close(); 975 992 if (test__start_subtest("sockmap sk_msg load helpers")) 976 993 test_skmsg_helpers(BPF_MAP_TYPE_SOCKMAP); 977 994 if (test__start_subtest("sockhash sk_msg load helpers")) ··· 1072 997 test_skmsg_helpers_with_link(BPF_MAP_TYPE_SOCKMAP); 1073 998 if (test__start_subtest("sockhash sk_msg attach sockhash helpers with link")) 1074 999 test_skmsg_helpers_with_link(BPF_MAP_TYPE_SOCKHASH); 1000 + if (test__start_subtest("sockmap skb_verdict vsock poll")) 1001 + test_sockmap_skb_verdict_vsock_poll(); 1075 1002 }
+1 -1
tools/testing/selftests/bpf/prog_tests/task_local_storage.c
··· 197 197 /* Unnecessary recursion and deadlock detection are reproducible 198 198 * in the preemptible kernel. 199 199 */ 200 - if (!skel->kconfig->CONFIG_PREEMPT) { 200 + if (!skel->kconfig->CONFIG_PREEMPTION) { 201 201 test__skip(); 202 202 goto done; 203 203 }
+1 -18
tools/testing/selftests/bpf/prog_tests/verifier.c
··· 225 225 void test_verifier_xdp_direct_packet_access(void) { RUN(verifier_xdp_direct_packet_access); } 226 226 void test_verifier_bits_iter(void) { RUN(verifier_bits_iter); } 227 227 void test_verifier_lsm(void) { RUN(verifier_lsm); } 228 - 229 - void test_verifier_mtu(void) 230 - { 231 - __u64 caps = 0; 232 - int ret; 233 - 234 - /* In case CAP_BPF and CAP_PERFMON is not set */ 235 - ret = cap_enable_effective(1ULL << CAP_BPF | 1ULL << CAP_NET_ADMIN, &caps); 236 - if (!ASSERT_OK(ret, "set_cap_bpf_cap_net_admin")) 237 - return; 238 - ret = cap_disable_effective(1ULL << CAP_SYS_ADMIN | 1ULL << CAP_PERFMON, NULL); 239 - if (!ASSERT_OK(ret, "disable_cap_sys_admin")) 240 - goto restore_cap; 241 - RUN(verifier_mtu); 242 - restore_cap: 243 - if (caps) 244 - cap_enable_effective(caps, NULL); 245 - } 228 + void test_verifier_mtu(void) { RUN(verifier_mtu); } 246 229 247 230 static int init_test_val_map(struct bpf_object *obj, char *map_name) 248 231 {
+12
tools/testing/selftests/bpf/progs/bpf_misc.h
··· 5 5 #define XSTR(s) STR(s) 6 6 #define STR(s) #s 7 7 8 + /* Expand a macro and then stringize the expansion */ 9 + #define QUOTE(str) #str 10 + #define EXPAND_QUOTE(str) QUOTE(str) 11 + 8 12 /* This set of attributes controls behavior of the 9 13 * test_loader.c:test_loader__run_subtests(). 10 14 * ··· 110 106 * __arch_* Specify on which architecture the test case should be tested. 111 107 * Several __arch_* annotations could be specified at once. 112 108 * When test case is not run on current arch it is marked as skipped. 109 + * __caps_unpriv Specify the capabilities that should be set when running the test. 113 110 */ 114 111 #define __msg(msg) __attribute__((btf_decl_tag("comment:test_expect_msg=" XSTR(__COUNTER__) "=" msg))) 115 112 #define __xlated(msg) __attribute__((btf_decl_tag("comment:test_expect_xlated=" XSTR(__COUNTER__) "=" msg))) ··· 134 129 #define __arch_x86_64 __arch("X86_64") 135 130 #define __arch_arm64 __arch("ARM64") 136 131 #define __arch_riscv64 __arch("RISCV64") 132 + #define __caps_unpriv(caps) __attribute__((btf_decl_tag("comment:test_caps_unpriv=" EXPAND_QUOTE(caps)))) 133 + 134 + /* Define common capabilities tested using __caps_unpriv */ 135 + #define CAP_NET_ADMIN 12 136 + #define CAP_SYS_ADMIN 21 137 + #define CAP_PERFMON 38 138 + #define CAP_BPF 39 137 139 138 140 /* Convenience macro for use with 'asm volatile' blocks */ 139 141 #define __naked __attribute__((naked))
+11 -11
tools/testing/selftests/bpf/progs/dynptr_fail.c
··· 149 149 150 150 /* A dynptr can't be used after it has been invalidated */ 151 151 SEC("?raw_tp") 152 - __failure __msg("Expected an initialized dynptr as arg #3") 152 + __failure __msg("Expected an initialized dynptr as arg #2") 153 153 int use_after_invalid(void *ctx) 154 154 { 155 155 struct bpf_dynptr ptr; ··· 428 428 429 429 /* A bpf_dynptr is invalidated if it's been written into */ 430 430 SEC("?raw_tp") 431 - __failure __msg("Expected an initialized dynptr as arg #1") 431 + __failure __msg("Expected an initialized dynptr as arg #0") 432 432 int invalid_write1(void *ctx) 433 433 { 434 434 struct bpf_dynptr ptr; ··· 1407 1407 1408 1408 /* bpf_dynptr_adjust can only be called on initialized dynptrs */ 1409 1409 SEC("?raw_tp") 1410 - __failure __msg("Expected an initialized dynptr as arg #1") 1410 + __failure __msg("Expected an initialized dynptr as arg #0") 1411 1411 int dynptr_adjust_invalid(void *ctx) 1412 1412 { 1413 1413 struct bpf_dynptr ptr = {}; ··· 1420 1420 1421 1421 /* bpf_dynptr_is_null can only be called on initialized dynptrs */ 1422 1422 SEC("?raw_tp") 1423 - __failure __msg("Expected an initialized dynptr as arg #1") 1423 + __failure __msg("Expected an initialized dynptr as arg #0") 1424 1424 int dynptr_is_null_invalid(void *ctx) 1425 1425 { 1426 1426 struct bpf_dynptr ptr = {}; ··· 1433 1433 1434 1434 /* bpf_dynptr_is_rdonly can only be called on initialized dynptrs */ 1435 1435 SEC("?raw_tp") 1436 - __failure __msg("Expected an initialized dynptr as arg #1") 1436 + __failure __msg("Expected an initialized dynptr as arg #0") 1437 1437 int dynptr_is_rdonly_invalid(void *ctx) 1438 1438 { 1439 1439 struct bpf_dynptr ptr = {}; ··· 1446 1446 1447 1447 /* bpf_dynptr_size can only be called on initialized dynptrs */ 1448 1448 SEC("?raw_tp") 1449 - __failure __msg("Expected an initialized dynptr as arg #1") 1449 + __failure __msg("Expected an initialized dynptr as arg #0") 1450 1450 int dynptr_size_invalid(void *ctx) 1451 1451 { 1452 1452 struct bpf_dynptr ptr = {}; ··· 1459 1459 1460 1460 /* Only initialized dynptrs can be cloned */ 1461 1461 SEC("?raw_tp") 1462 - __failure __msg("Expected an initialized dynptr as arg #1") 1462 + __failure __msg("Expected an initialized dynptr as arg #0") 1463 1463 int clone_invalid1(void *ctx) 1464 1464 { 1465 1465 struct bpf_dynptr ptr1 = {}; ··· 1493 1493 1494 1494 /* Invalidating a dynptr should invalidate its clones */ 1495 1495 SEC("?raw_tp") 1496 - __failure __msg("Expected an initialized dynptr as arg #3") 1496 + __failure __msg("Expected an initialized dynptr as arg #2") 1497 1497 int clone_invalidate1(void *ctx) 1498 1498 { 1499 1499 struct bpf_dynptr clone; ··· 1514 1514 1515 1515 /* Invalidating a dynptr should invalidate its parent */ 1516 1516 SEC("?raw_tp") 1517 - __failure __msg("Expected an initialized dynptr as arg #3") 1517 + __failure __msg("Expected an initialized dynptr as arg #2") 1518 1518 int clone_invalidate2(void *ctx) 1519 1519 { 1520 1520 struct bpf_dynptr ptr; ··· 1535 1535 1536 1536 /* Invalidating a dynptr should invalidate its siblings */ 1537 1537 SEC("?raw_tp") 1538 - __failure __msg("Expected an initialized dynptr as arg #3") 1538 + __failure __msg("Expected an initialized dynptr as arg #2") 1539 1539 int clone_invalidate3(void *ctx) 1540 1540 { 1541 1541 struct bpf_dynptr ptr; ··· 1723 1723 } 1724 1724 1725 1725 SEC("?raw_tp") 1726 - __failure __msg("arg#1 expected pointer to stack or const struct bpf_dynptr") 1726 + __failure __msg("arg#0 expected pointer to stack or const struct bpf_dynptr") 1727 1727 int test_dynptr_reg_type(void *ctx) 1728 1728 { 1729 1729 struct task_struct *current = NULL;
+26
tools/testing/selftests/bpf/progs/iters.c
··· 1486 1486 return 0; 1487 1487 } 1488 1488 1489 + struct bpf_iter_num global_it; 1490 + 1491 + SEC("raw_tp") 1492 + __failure __msg("arg#0 expected pointer to an iterator on stack") 1493 + int iter_new_bad_arg(const void *ctx) 1494 + { 1495 + bpf_iter_num_new(&global_it, 0, 1); 1496 + return 0; 1497 + } 1498 + 1499 + SEC("raw_tp") 1500 + __failure __msg("arg#0 expected pointer to an iterator on stack") 1501 + int iter_next_bad_arg(const void *ctx) 1502 + { 1503 + bpf_iter_num_next(&global_it); 1504 + return 0; 1505 + } 1506 + 1507 + SEC("raw_tp") 1508 + __failure __msg("arg#0 expected pointer to an iterator on stack") 1509 + int iter_destroy_bad_arg(const void *ctx) 1510 + { 1511 + bpf_iter_num_destroy(&global_it); 1512 + return 0; 1513 + } 1514 + 1489 1515 char _license[] SEC("license") = "GPL";
+7 -7
tools/testing/selftests/bpf/progs/iters_state_safety.c
··· 73 73 } 74 74 75 75 SEC("?raw_tp") 76 - __failure __msg("expected an initialized iter_num as arg #1") 76 + __failure __msg("expected an initialized iter_num as arg #0") 77 77 int destroy_without_creating_fail(void *ctx) 78 78 { 79 79 /* init with zeros to stop verifier complaining about uninit stack */ ··· 91 91 } 92 92 93 93 SEC("?raw_tp") 94 - __failure __msg("expected an initialized iter_num as arg #1") 94 + __failure __msg("expected an initialized iter_num as arg #0") 95 95 int compromise_iter_w_direct_write_fail(void *ctx) 96 96 { 97 97 struct bpf_iter_num iter; ··· 143 143 } 144 144 145 145 SEC("?raw_tp") 146 - __failure __msg("expected an initialized iter_num as arg #1") 146 + __failure __msg("expected an initialized iter_num as arg #0") 147 147 int compromise_iter_w_helper_write_fail(void *ctx) 148 148 { 149 149 struct bpf_iter_num iter; ··· 230 230 } 231 231 232 232 SEC("?raw_tp") 233 - __failure __msg("expected uninitialized iter_num as arg #1") 233 + __failure __msg("expected uninitialized iter_num as arg #0") 234 234 int double_create_fail(void *ctx) 235 235 { 236 236 struct bpf_iter_num iter; ··· 258 258 } 259 259 260 260 SEC("?raw_tp") 261 - __failure __msg("expected an initialized iter_num as arg #1") 261 + __failure __msg("expected an initialized iter_num as arg #0") 262 262 int double_destroy_fail(void *ctx) 263 263 { 264 264 struct bpf_iter_num iter; ··· 284 284 } 285 285 286 286 SEC("?raw_tp") 287 - __failure __msg("expected an initialized iter_num as arg #1") 287 + __failure __msg("expected an initialized iter_num as arg #0") 288 288 int next_without_new_fail(void *ctx) 289 289 { 290 290 struct bpf_iter_num iter; ··· 305 305 } 306 306 307 307 SEC("?raw_tp") 308 - __failure __msg("expected an initialized iter_num as arg #1") 308 + __failure __msg("expected an initialized iter_num as arg #0") 309 309 int next_after_destroy_fail(void *ctx) 310 310 { 311 311 struct bpf_iter_num iter;
+2 -2
tools/testing/selftests/bpf/progs/iters_testmod_seq.c
··· 79 79 80 80 SEC("?raw_tp") 81 81 __failure 82 - __msg("expected an initialized iter_testmod_seq as arg #2") 82 + __msg("expected an initialized iter_testmod_seq as arg #1") 83 83 int testmod_seq_getter_before_bad(const void *ctx) 84 84 { 85 85 struct bpf_iter_testmod_seq it; ··· 89 89 90 90 SEC("?raw_tp") 91 91 __failure 92 - __msg("expected an initialized iter_testmod_seq as arg #2") 92 + __msg("expected an initialized iter_testmod_seq as arg #1") 93 93 int testmod_seq_getter_after_bad(const void *ctx) 94 94 { 95 95 struct bpf_iter_testmod_seq it;
+2 -2
tools/testing/selftests/bpf/progs/read_bpf_task_storage_busy.c
··· 4 4 #include <bpf/bpf_helpers.h> 5 5 #include <bpf/bpf_tracing.h> 6 6 7 - extern bool CONFIG_PREEMPT __kconfig __weak; 7 + extern bool CONFIG_PREEMPTION __kconfig __weak; 8 8 extern const int bpf_task_storage_busy __ksym; 9 9 10 10 char _license[] SEC("license") = "GPL"; ··· 24 24 { 25 25 int *value; 26 26 27 - if (!CONFIG_PREEMPT) 27 + if (!CONFIG_PREEMPTION) 28 28 return 0; 29 29 30 30 if (bpf_get_current_pid_tgid() >> 32 != pid)
+2 -2
tools/testing/selftests/bpf/progs/task_storage_nodeadlock.c
··· 10 10 #define EBUSY 16 11 11 #endif 12 12 13 - extern bool CONFIG_PREEMPT __kconfig __weak; 13 + extern bool CONFIG_PREEMPTION __kconfig __weak; 14 14 int nr_get_errs = 0; 15 15 int nr_del_errs = 0; 16 16 ··· 29 29 int ret, zero = 0; 30 30 int *value; 31 31 32 - if (!CONFIG_PREEMPT) 32 + if (!CONFIG_PREEMPTION) 33 33 return 0; 34 34 35 35 task = bpf_get_current_task_btf();
+1 -1
tools/testing/selftests/bpf/progs/test_kfunc_dynptr_param.c
··· 45 45 } 46 46 47 47 SEC("?lsm.s/bpf") 48 - __failure __msg("arg#1 expected pointer to stack or const struct bpf_dynptr") 48 + __failure __msg("arg#0 expected pointer to stack or const struct bpf_dynptr") 49 49 int BPF_PROG(not_ptr_to_stack, int cmd, union bpf_attr *attr, unsigned int size) 50 50 { 51 51 unsigned long val = 0;
+4 -4
tools/testing/selftests/bpf/progs/verifier_bits_iter.c
··· 32 32 33 33 SEC("iter/cgroup") 34 34 __description("uninitialized iter in ->next()") 35 - __failure __msg("expected an initialized iter_bits as arg #1") 35 + __failure __msg("expected an initialized iter_bits as arg #0") 36 36 int BPF_PROG(next_uninit, struct bpf_iter_meta *meta, struct cgroup *cgrp) 37 37 { 38 - struct bpf_iter_bits *it = NULL; 38 + struct bpf_iter_bits it = {}; 39 39 40 - bpf_iter_bits_next(it); 40 + bpf_iter_bits_next(&it); 41 41 return 0; 42 42 } 43 43 44 44 SEC("iter/cgroup") 45 45 __description("uninitialized iter in ->destroy()") 46 - __failure __msg("expected an initialized iter_bits as arg #1") 46 + __failure __msg("expected an initialized iter_bits as arg #0") 47 47 int BPF_PROG(destroy_uninit, struct bpf_iter_meta *meta, struct cgroup *cgrp) 48 48 { 49 49 struct bpf_iter_bits it = {};
+3 -1
tools/testing/selftests/bpf/progs/verifier_mtu.c
··· 6 6 7 7 SEC("tc/ingress") 8 8 __description("uninit/mtu: write rejected") 9 - __failure __msg("invalid indirect read from stack") 9 + __success 10 + __caps_unpriv(CAP_BPF|CAP_NET_ADMIN) 11 + __failure_unpriv __msg_unpriv("invalid indirect read from stack") 10 12 int tc_uninit_mtu(struct __sk_buff *ctx) 11 13 { 12 14 __u32 mtu;
+35
tools/testing/selftests/bpf/progs/verifier_spill_fill.c
··· 1244 1244 : __clobber_all); 1245 1245 } 1246 1246 1247 + SEC("socket") 1248 + __description("stack_noperfmon: reject read of invalid slots") 1249 + __success 1250 + __caps_unpriv(CAP_BPF) 1251 + __failure_unpriv __msg_unpriv("invalid read from stack off -8+1 size 8") 1252 + __naked void stack_noperfmon_reject_invalid_read(void) 1253 + { 1254 + asm volatile (" \ 1255 + r2 = 1; \ 1256 + r6 = r10; \ 1257 + r6 += -8; \ 1258 + *(u8 *)(r6 + 0) = r2; \ 1259 + r2 = *(u64 *)(r6 + 0); \ 1260 + r0 = 0; \ 1261 + exit; \ 1262 + " ::: __clobber_all); 1263 + } 1264 + 1265 + SEC("socket") 1266 + __description("stack_noperfmon: narrow spill onto 64-bit scalar spilled slots") 1267 + __success 1268 + __caps_unpriv(CAP_BPF) 1269 + __success_unpriv 1270 + __naked void stack_noperfmon_spill_32bit_onto_64bit_slot(void) 1271 + { 1272 + asm volatile(" \ 1273 + r0 = 0; \ 1274 + *(u64 *)(r10 - 8) = r0; \ 1275 + *(u32 *)(r10 - 8) = r0; \ 1276 + exit; \ 1277 + " : 1278 + : 1279 + : __clobber_all); 1280 + } 1281 + 1247 1282 char _license[] SEC("license") = "GPL";
+46
tools/testing/selftests/bpf/test_loader.c
··· 36 36 #define TEST_TAG_ARCH "comment:test_arch=" 37 37 #define TEST_TAG_JITED_PFX "comment:test_jited=" 38 38 #define TEST_TAG_JITED_PFX_UNPRIV "comment:test_jited_unpriv=" 39 + #define TEST_TAG_CAPS_UNPRIV "comment:test_caps_unpriv=" 39 40 40 41 /* Warning: duplicated in bpf_misc.h */ 41 42 #define POINTER_VALUE 0xcafe4all ··· 75 74 struct expected_msgs jited; 76 75 int retval; 77 76 bool execute; 77 + __u64 caps; 78 78 }; 79 79 80 80 struct test_spec { ··· 275 273 return -EINVAL; 276 274 } 277 275 *val = tmp; 276 + return 0; 277 + } 278 + 279 + static int parse_caps(const char *str, __u64 *val, const char *name) 280 + { 281 + int cap_flag = 0; 282 + char *token = NULL, *saveptr = NULL; 283 + 284 + char *str_cpy = strdup(str); 285 + if (str_cpy == NULL) { 286 + PRINT_FAIL("Memory allocation failed\n"); 287 + return -EINVAL; 288 + } 289 + 290 + token = strtok_r(str_cpy, "|", &saveptr); 291 + while (token != NULL) { 292 + errno = 0; 293 + if (!strncmp("CAP_", token, sizeof("CAP_") - 1)) { 294 + PRINT_FAIL("define %s constant in bpf_misc.h, failed to parse caps\n", token); 295 + return -EINVAL; 296 + } 297 + cap_flag = strtol(token, NULL, 10); 298 + if (!cap_flag || errno) { 299 + PRINT_FAIL("failed to parse caps %s\n", name); 300 + return -EINVAL; 301 + } 302 + *val |= (1ULL << cap_flag); 303 + token = strtok_r(NULL, "|", &saveptr); 304 + } 305 + 306 + free(str_cpy); 278 307 return 0; 279 308 } 280 309 ··· 574 541 jit_on_next_line = true; 575 542 } else if (str_has_pfx(s, TEST_BTF_PATH)) { 576 543 spec->btf_custom_path = s + sizeof(TEST_BTF_PATH) - 1; 544 + } else if (str_has_pfx(s, TEST_TAG_CAPS_UNPRIV)) { 545 + val = s + sizeof(TEST_TAG_CAPS_UNPRIV) - 1; 546 + err = parse_caps(val, &spec->unpriv.caps, "test caps"); 547 + if (err) 548 + goto cleanup; 549 + spec->mode_mask |= UNPRIV; 577 550 } 578 551 } 579 552 ··· 955 916 if (drop_capabilities(&caps)) { 956 917 test__end_subtest(); 957 918 return; 919 + } 920 + if (subspec->caps) { 921 + err = cap_enable_effective(subspec->caps, NULL); 922 + if (err) { 923 + PRINT_FAIL("failed to set capabilities: %i, %s\n", err, strerror(err)); 924 + goto subtest_cleanup; 925 + } 958 926 } 959 927 } 960 928
+398 -7
tools/testing/selftests/bpf/test_lpm_map.c tools/testing/selftests/bpf/map_tests/lpm_trie_map_basic_ops.c
··· 20 20 #include <string.h> 21 21 #include <time.h> 22 22 #include <unistd.h> 23 + #include <endian.h> 23 24 #include <arpa/inet.h> 24 25 #include <sys/time.h> 25 26 26 27 #include <bpf/bpf.h> 28 + #include <test_maps.h> 27 29 28 30 #include "bpf_util.h" 29 31 ··· 33 31 struct tlpm_node *next; 34 32 size_t n_bits; 35 33 uint8_t key[]; 34 + }; 35 + 36 + struct lpm_trie_bytes_key { 37 + union { 38 + struct bpf_lpm_trie_key_hdr hdr; 39 + __u32 prefixlen; 40 + }; 41 + unsigned char data[8]; 42 + }; 43 + 44 + struct lpm_trie_int_key { 45 + union { 46 + struct bpf_lpm_trie_key_hdr hdr; 47 + __u32 prefixlen; 48 + }; 49 + unsigned int data; 36 50 }; 37 51 38 52 static struct tlpm_node *tlpm_match(struct tlpm_node *list, ··· 241 223 n_matches = 0; 242 224 n_matches_after_delete = 0; 243 225 n_nodes = 1 << 8; 244 - n_lookups = 1 << 16; 226 + n_lookups = 1 << 9; 245 227 246 228 data = alloca(keysize); 247 229 memset(data, 0, keysize); ··· 788 770 close(map_fd); 789 771 } 790 772 791 - int main(void) 773 + static int lpm_trie_create(unsigned int key_size, unsigned int value_size, unsigned int max_entries) 774 + { 775 + LIBBPF_OPTS(bpf_map_create_opts, opts); 776 + int fd; 777 + 778 + opts.map_flags = BPF_F_NO_PREALLOC; 779 + fd = bpf_map_create(BPF_MAP_TYPE_LPM_TRIE, "lpm_trie", key_size, value_size, max_entries, 780 + &opts); 781 + CHECK(fd < 0, "bpf_map_create", "error %d\n", errno); 782 + 783 + return fd; 784 + } 785 + 786 + static void test_lpm_trie_update_flags(void) 787 + { 788 + struct lpm_trie_int_key key; 789 + unsigned int value, got; 790 + int fd, err; 791 + 792 + fd = lpm_trie_create(sizeof(key), sizeof(value), 3); 793 + 794 + /* invalid flags (Error) */ 795 + key.prefixlen = 32; 796 + key.data = 0; 797 + value = 0; 798 + err = bpf_map_update_elem(fd, &key, &value, BPF_F_LOCK); 799 + CHECK(err != -EINVAL, "invalid update flag", "error %d\n", err); 800 + 801 + /* invalid flags (Error) */ 802 + key.prefixlen = 32; 803 + key.data = 0; 804 + value = 0; 805 + err = bpf_map_update_elem(fd, &key, &value, BPF_NOEXIST | BPF_EXIST); 806 + CHECK(err != -EINVAL, "invalid update flag", "error %d\n", err); 807 + 808 + /* overwrite an empty qp-trie (Error) */ 809 + key.prefixlen = 32; 810 + key.data = 0; 811 + value = 2; 812 + err = bpf_map_update_elem(fd, &key, &value, BPF_EXIST); 813 + CHECK(err != -ENOENT, "overwrite empty qp-trie", "error %d\n", err); 814 + 815 + /* add a new node */ 816 + key.prefixlen = 16; 817 + key.data = 0; 818 + value = 1; 819 + err = bpf_map_update_elem(fd, &key, &value, BPF_NOEXIST); 820 + CHECK(err, "add new elem", "error %d\n", err); 821 + got = 0; 822 + err = bpf_map_lookup_elem(fd, &key, &got); 823 + CHECK(err, "lookup elem", "error %d\n", err); 824 + CHECK(got != value, "check value", "got %d exp %d\n", got, value); 825 + 826 + /* add the same node as new node (Error) */ 827 + err = bpf_map_update_elem(fd, &key, &value, BPF_NOEXIST); 828 + CHECK(err != -EEXIST, "add new elem again", "error %d\n", err); 829 + 830 + /* overwrite the existed node */ 831 + value = 4; 832 + err = bpf_map_update_elem(fd, &key, &value, BPF_EXIST); 833 + CHECK(err, "overwrite elem", "error %d\n", err); 834 + got = 0; 835 + err = bpf_map_lookup_elem(fd, &key, &got); 836 + CHECK(err, "lookup elem", "error %d\n", err); 837 + CHECK(got != value, "check value", "got %d exp %d\n", got, value); 838 + 839 + /* overwrite the node */ 840 + value = 1; 841 + err = bpf_map_update_elem(fd, &key, &value, BPF_ANY); 842 + CHECK(err, "update elem", "error %d\n", err); 843 + got = 0; 844 + err = bpf_map_lookup_elem(fd, &key, &got); 845 + CHECK(err, "lookup elem", "error %d\n", err); 846 + CHECK(got != value, "check value", "got %d exp %d\n", got, value); 847 + 848 + /* overwrite a non-existent node which is the prefix of the first 849 + * node (Error). 850 + */ 851 + key.prefixlen = 8; 852 + key.data = 0; 853 + value = 2; 854 + err = bpf_map_update_elem(fd, &key, &value, BPF_EXIST); 855 + CHECK(err != -ENOENT, "overwrite nonexistent elem", "error %d\n", err); 856 + 857 + /* add a new node which is the prefix of the first node */ 858 + err = bpf_map_update_elem(fd, &key, &value, BPF_NOEXIST); 859 + CHECK(err, "add new elem", "error %d\n", err); 860 + got = 0; 861 + err = bpf_map_lookup_elem(fd, &key, &got); 862 + CHECK(err, "lookup key", "error %d\n", err); 863 + CHECK(got != value, "check value", "got %d exp %d\n", got, value); 864 + 865 + /* add another new node which will be the sibling of the first node */ 866 + key.prefixlen = 9; 867 + key.data = htobe32(1 << 23); 868 + value = 5; 869 + err = bpf_map_update_elem(fd, &key, &value, BPF_NOEXIST); 870 + CHECK(err, "add new elem", "error %d\n", err); 871 + got = 0; 872 + err = bpf_map_lookup_elem(fd, &key, &got); 873 + CHECK(err, "lookup key", "error %d\n", err); 874 + CHECK(got != value, "check value", "got %d exp %d\n", got, value); 875 + 876 + /* overwrite the third node */ 877 + value = 3; 878 + err = bpf_map_update_elem(fd, &key, &value, BPF_ANY); 879 + CHECK(err, "overwrite elem", "error %d\n", err); 880 + got = 0; 881 + err = bpf_map_lookup_elem(fd, &key, &got); 882 + CHECK(err, "lookup key", "error %d\n", err); 883 + CHECK(got != value, "check value", "got %d exp %d\n", got, value); 884 + 885 + /* delete the second node to make it an intermediate node */ 886 + key.prefixlen = 8; 887 + key.data = 0; 888 + err = bpf_map_delete_elem(fd, &key); 889 + CHECK(err, "del elem", "error %d\n", err); 890 + 891 + /* overwrite the intermediate node (Error) */ 892 + value = 2; 893 + err = bpf_map_update_elem(fd, &key, &value, BPF_EXIST); 894 + CHECK(err != -ENOENT, "overwrite nonexistent elem", "error %d\n", err); 895 + 896 + close(fd); 897 + } 898 + 899 + static void test_lpm_trie_update_full_map(void) 900 + { 901 + struct lpm_trie_int_key key; 902 + int value, got; 903 + int fd, err; 904 + 905 + fd = lpm_trie_create(sizeof(key), sizeof(value), 3); 906 + 907 + /* add a new node */ 908 + key.prefixlen = 16; 909 + key.data = 0; 910 + value = 0; 911 + err = bpf_map_update_elem(fd, &key, &value, BPF_NOEXIST); 912 + CHECK(err, "add new elem", "error %d\n", err); 913 + got = 0; 914 + err = bpf_map_lookup_elem(fd, &key, &got); 915 + CHECK(err, "lookup elem", "error %d\n", err); 916 + CHECK(got != value, "check value", "got %d exp %d\n", got, value); 917 + 918 + /* add new node */ 919 + key.prefixlen = 8; 920 + key.data = 0; 921 + value = 1; 922 + err = bpf_map_update_elem(fd, &key, &value, BPF_NOEXIST); 923 + CHECK(err, "add new elem", "error %d\n", err); 924 + got = 0; 925 + err = bpf_map_lookup_elem(fd, &key, &got); 926 + CHECK(err, "lookup elem", "error %d\n", err); 927 + CHECK(got != value, "check value", "got %d exp %d\n", got, value); 928 + 929 + /* add new node */ 930 + key.prefixlen = 9; 931 + key.data = htobe32(1 << 23); 932 + value = 2; 933 + err = bpf_map_update_elem(fd, &key, &value, BPF_NOEXIST); 934 + CHECK(err, "add new elem", "error %d\n", err); 935 + got = 0; 936 + err = bpf_map_lookup_elem(fd, &key, &got); 937 + CHECK(err, "lookup elem", "error %d\n", err); 938 + CHECK(got != value, "check value", "got %d exp %d\n", got, value); 939 + 940 + /* try to add more node (Error) */ 941 + key.prefixlen = 32; 942 + key.data = 0; 943 + value = 3; 944 + err = bpf_map_update_elem(fd, &key, &value, BPF_ANY); 945 + CHECK(err != -ENOSPC, "add to full trie", "error %d\n", err); 946 + 947 + /* update the value of an existed node with BPF_EXIST */ 948 + key.prefixlen = 16; 949 + key.data = 0; 950 + value = 4; 951 + err = bpf_map_update_elem(fd, &key, &value, BPF_EXIST); 952 + CHECK(err, "overwrite elem", "error %d\n", err); 953 + got = 0; 954 + err = bpf_map_lookup_elem(fd, &key, &got); 955 + CHECK(err, "lookup elem", "error %d\n", err); 956 + CHECK(got != value, "check value", "got %d exp %d\n", got, value); 957 + 958 + /* update the value of an existed node with BPF_ANY */ 959 + key.prefixlen = 9; 960 + key.data = htobe32(1 << 23); 961 + value = 5; 962 + err = bpf_map_update_elem(fd, &key, &value, BPF_ANY); 963 + CHECK(err, "overwrite elem", "error %d\n", err); 964 + got = 0; 965 + err = bpf_map_lookup_elem(fd, &key, &got); 966 + CHECK(err, "lookup elem", "error %d\n", err); 967 + CHECK(got != value, "check value", "got %d exp %d\n", got, value); 968 + 969 + close(fd); 970 + } 971 + 972 + static int cmp_str(const void *a, const void *b) 973 + { 974 + const char *str_a = *(const char **)a, *str_b = *(const char **)b; 975 + 976 + return strcmp(str_a, str_b); 977 + } 978 + 979 + /* Save strings in LPM trie. The trailing '\0' for each string will be 980 + * accounted in the prefixlen. The strings returned during the iteration 981 + * should be sorted as expected. 982 + */ 983 + static void test_lpm_trie_iterate_strs(void) 984 + { 985 + static const char * const keys[] = { 986 + "ab", "abO", "abc", "abo", "abS", "abcd", 987 + }; 988 + const char *sorted_keys[ARRAY_SIZE(keys)]; 989 + struct lpm_trie_bytes_key key, next_key; 990 + unsigned int value, got, i, j, len; 991 + struct lpm_trie_bytes_key *cur; 992 + int fd, err; 993 + 994 + fd = lpm_trie_create(sizeof(key), sizeof(value), ARRAY_SIZE(keys)); 995 + 996 + for (i = 0; i < ARRAY_SIZE(keys); i++) { 997 + unsigned int flags; 998 + 999 + /* add i-th element */ 1000 + flags = i % 2 ? BPF_NOEXIST : 0; 1001 + len = strlen(keys[i]); 1002 + /* include the trailing '\0' */ 1003 + key.prefixlen = (len + 1) * 8; 1004 + memset(key.data, 0, sizeof(key.data)); 1005 + memcpy(key.data, keys[i], len); 1006 + value = i + 100; 1007 + err = bpf_map_update_elem(fd, &key, &value, flags); 1008 + CHECK(err, "add elem", "#%u error %d\n", i, err); 1009 + 1010 + err = bpf_map_lookup_elem(fd, &key, &got); 1011 + CHECK(err, "lookup elem", "#%u error %d\n", i, err); 1012 + CHECK(got != value, "lookup elem", "#%u expect %u got %u\n", i, value, got); 1013 + 1014 + /* re-add i-th element (Error) */ 1015 + err = bpf_map_update_elem(fd, &key, &value, BPF_NOEXIST); 1016 + CHECK(err != -EEXIST, "re-add elem", "#%u error %d\n", i, err); 1017 + 1018 + /* Overwrite i-th element */ 1019 + flags = i % 2 ? 0 : BPF_EXIST; 1020 + value = i; 1021 + err = bpf_map_update_elem(fd, &key, &value, flags); 1022 + CHECK(err, "update elem", "error %d\n", err); 1023 + 1024 + /* Lookup #[0~i] elements */ 1025 + for (j = 0; j <= i; j++) { 1026 + len = strlen(keys[j]); 1027 + key.prefixlen = (len + 1) * 8; 1028 + memset(key.data, 0, sizeof(key.data)); 1029 + memcpy(key.data, keys[j], len); 1030 + err = bpf_map_lookup_elem(fd, &key, &got); 1031 + CHECK(err, "lookup elem", "#%u/%u error %d\n", i, j, err); 1032 + CHECK(got != j, "lookup elem", "#%u/%u expect %u got %u\n", 1033 + i, j, value, got); 1034 + } 1035 + } 1036 + 1037 + /* Add element to a full qp-trie (Error) */ 1038 + key.prefixlen = sizeof(key.data) * 8; 1039 + memset(key.data, 0, sizeof(key.data)); 1040 + value = 0; 1041 + err = bpf_map_update_elem(fd, &key, &value, 0); 1042 + CHECK(err != -ENOSPC, "add to full qp-trie", "error %d\n", err); 1043 + 1044 + /* Iterate sorted elements: no deletion */ 1045 + memcpy(sorted_keys, keys, sizeof(keys)); 1046 + qsort(sorted_keys, ARRAY_SIZE(sorted_keys), sizeof(sorted_keys[0]), cmp_str); 1047 + cur = NULL; 1048 + for (i = 0; i < ARRAY_SIZE(sorted_keys); i++) { 1049 + len = strlen(sorted_keys[i]); 1050 + err = bpf_map_get_next_key(fd, cur, &next_key); 1051 + CHECK(err, "iterate", "#%u error %d\n", i, err); 1052 + CHECK(next_key.prefixlen != (len + 1) * 8, "iterate", 1053 + "#%u invalid len %u expect %u\n", 1054 + i, next_key.prefixlen, (len + 1) * 8); 1055 + CHECK(memcmp(sorted_keys[i], next_key.data, len + 1), "iterate", 1056 + "#%u got %.*s exp %.*s\n", i, len, next_key.data, len, sorted_keys[i]); 1057 + 1058 + cur = &next_key; 1059 + } 1060 + err = bpf_map_get_next_key(fd, cur, &next_key); 1061 + CHECK(err != -ENOENT, "more element", "error %d\n", err); 1062 + 1063 + /* Iterate sorted elements: delete the found key after each iteration */ 1064 + cur = NULL; 1065 + for (i = 0; i < ARRAY_SIZE(sorted_keys); i++) { 1066 + len = strlen(sorted_keys[i]); 1067 + err = bpf_map_get_next_key(fd, cur, &next_key); 1068 + CHECK(err, "iterate", "#%u error %d\n", i, err); 1069 + CHECK(next_key.prefixlen != (len + 1) * 8, "iterate", 1070 + "#%u invalid len %u expect %u\n", 1071 + i, next_key.prefixlen, (len + 1) * 8); 1072 + CHECK(memcmp(sorted_keys[i], next_key.data, len + 1), "iterate", 1073 + "#%u got %.*s exp %.*s\n", i, len, next_key.data, len, sorted_keys[i]); 1074 + 1075 + cur = &next_key; 1076 + 1077 + err = bpf_map_delete_elem(fd, cur); 1078 + CHECK(err, "delete", "#%u error %d\n", i, err); 1079 + } 1080 + err = bpf_map_get_next_key(fd, cur, &next_key); 1081 + CHECK(err != -ENOENT, "non-empty qp-trie", "error %d\n", err); 1082 + 1083 + close(fd); 1084 + } 1085 + 1086 + /* Use the fixed prefixlen (32) and save integers in LPM trie. The iteration of 1087 + * LPM trie will return these integers in big-endian order, therefore, convert 1088 + * these integers to big-endian before update. After each iteration, delete the 1089 + * found key (the smallest integer) and expect the next iteration will return 1090 + * the second smallest number. 1091 + */ 1092 + static void test_lpm_trie_iterate_ints(void) 1093 + { 1094 + struct lpm_trie_int_key key, next_key; 1095 + unsigned int i, max_entries; 1096 + struct lpm_trie_int_key *cur; 1097 + unsigned int *data_set; 1098 + int fd, err; 1099 + bool value; 1100 + 1101 + max_entries = 4096; 1102 + data_set = calloc(max_entries, sizeof(*data_set)); 1103 + CHECK(!data_set, "malloc", "no mem\n"); 1104 + for (i = 0; i < max_entries; i++) 1105 + data_set[i] = i; 1106 + 1107 + fd = lpm_trie_create(sizeof(key), sizeof(value), max_entries); 1108 + value = true; 1109 + for (i = 0; i < max_entries; i++) { 1110 + key.prefixlen = 32; 1111 + key.data = htobe32(data_set[i]); 1112 + 1113 + err = bpf_map_update_elem(fd, &key, &value, BPF_NOEXIST); 1114 + CHECK(err, "add elem", "#%u error %d\n", i, err); 1115 + } 1116 + 1117 + cur = NULL; 1118 + for (i = 0; i < max_entries; i++) { 1119 + err = bpf_map_get_next_key(fd, cur, &next_key); 1120 + CHECK(err, "iterate", "#%u error %d\n", i, err); 1121 + CHECK(next_key.prefixlen != 32, "iterate", "#%u invalid len %u\n", 1122 + i, next_key.prefixlen); 1123 + CHECK(be32toh(next_key.data) != data_set[i], "iterate", "#%u got 0x%x exp 0x%x\n", 1124 + i, be32toh(next_key.data), data_set[i]); 1125 + cur = &next_key; 1126 + 1127 + /* 1128 + * Delete the minimal key, the next call of bpf_get_next_key() 1129 + * will return the second minimal key. 1130 + */ 1131 + err = bpf_map_delete_elem(fd, &next_key); 1132 + CHECK(err, "del elem", "#%u elem error %d\n", i, err); 1133 + } 1134 + err = bpf_map_get_next_key(fd, cur, &next_key); 1135 + CHECK(err != -ENOENT, "more element", "error %d\n", err); 1136 + 1137 + err = bpf_map_get_next_key(fd, NULL, &next_key); 1138 + CHECK(err != -ENOENT, "no-empty qp-trie", "error %d\n", err); 1139 + 1140 + free(data_set); 1141 + 1142 + close(fd); 1143 + } 1144 + 1145 + void test_lpm_trie_map_basic_ops(void) 792 1146 { 793 1147 int i; 794 1148 795 1149 /* we want predictable, pseudo random tests */ 796 1150 srand(0xf00ba1); 797 - 798 - /* Use libbpf 1.0 API mode */ 799 - libbpf_set_strict_mode(LIBBPF_STRICT_ALL); 800 1151 801 1152 test_lpm_basic(); 802 1153 test_lpm_order(); ··· 1179 792 test_lpm_get_next_key(); 1180 793 test_lpm_multi_thread(); 1181 794 1182 - printf("test_lpm: OK\n"); 1183 - return 0; 795 + test_lpm_trie_update_flags(); 796 + test_lpm_trie_update_full_map(); 797 + test_lpm_trie_iterate_strs(); 798 + test_lpm_trie_iterate_ints(); 799 + 800 + printf("%s: PASS\n", __func__); 1184 801 }
+5 -1
tools/testing/selftests/bpf/test_sockmap.c
··· 1579 1579 1580 1580 static void test_txmsg_redir_wait_sndmem(int cgrp, struct sockmap_options *opt) 1581 1581 { 1582 - txmsg_redir = 1; 1583 1582 opt->tx_wait_mem = true; 1583 + txmsg_redir = 1; 1584 + test_send_large(opt, cgrp); 1585 + 1586 + txmsg_redir = 1; 1587 + txmsg_apply = 4097; 1584 1588 test_send_large(opt, cgrp); 1585 1589 opt->tx_wait_mem = false; 1586 1590 }