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

Merge git://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf

Daniel Borkmann says:

====================
pull-request: bpf 2019-12-19

The following pull-request contains BPF updates for your *net* tree.

We've added 10 non-merge commits during the last 8 day(s) which contain
a total of 21 files changed, 269 insertions(+), 108 deletions(-).

The main changes are:

1) Fix lack of synchronization between xsk wakeup and destroying resources
used by xsk wakeup, from Maxim Mikityanskiy.

2) Fix pruning with tail call patching, untrack programs in case of verifier
error and fix a cgroup local storage tracking bug, from Daniel Borkmann.

3) Fix clearing skb->tstamp in bpf_redirect() when going from ingress to
egress which otherwise cause issues e.g. on fq qdisc, from Lorenz Bauer.

4) Fix compile warning of unused proc_dointvec_minmax_bpf_restricted() when
only cBPF is present, from Alexander Lobakin.
====================

Signed-off-by: David S. Miller <davem@davemloft.net>

+276 -115
+1 -1
drivers/net/ethernet/intel/i40e/i40e.h
··· 1152 1152 1153 1153 static inline bool i40e_enabled_xdp_vsi(struct i40e_vsi *vsi) 1154 1154 { 1155 - return !!vsi->xdp_prog; 1155 + return !!READ_ONCE(vsi->xdp_prog); 1156 1156 } 1157 1157 1158 1158 int i40e_create_queue_channel(struct i40e_vsi *vsi, struct i40e_channel *ch);
+7 -3
drivers/net/ethernet/intel/i40e/i40e_main.c
··· 6823 6823 for (i = 0; i < vsi->num_queue_pairs; i++) { 6824 6824 i40e_clean_tx_ring(vsi->tx_rings[i]); 6825 6825 if (i40e_enabled_xdp_vsi(vsi)) { 6826 - /* Make sure that in-progress ndo_xdp_xmit 6827 - * calls are completed. 6826 + /* Make sure that in-progress ndo_xdp_xmit and 6827 + * ndo_xsk_wakeup calls are completed. 6828 6828 */ 6829 6829 synchronize_rcu(); 6830 6830 i40e_clean_tx_ring(vsi->xdp_rings[i]); ··· 12546 12546 12547 12547 old_prog = xchg(&vsi->xdp_prog, prog); 12548 12548 12549 - if (need_reset) 12549 + if (need_reset) { 12550 + if (!prog) 12551 + /* Wait until ndo_xsk_wakeup completes. */ 12552 + synchronize_rcu(); 12550 12553 i40e_reset_and_rebuild(pf, true, true); 12554 + } 12551 12555 12552 12556 for (i = 0; i < vsi->num_queue_pairs; i++) 12553 12557 WRITE_ONCE(vsi->rx_rings[i]->xdp_prog, vsi->xdp_prog);
+4
drivers/net/ethernet/intel/i40e/i40e_xsk.c
··· 787 787 { 788 788 struct i40e_netdev_priv *np = netdev_priv(dev); 789 789 struct i40e_vsi *vsi = np->vsi; 790 + struct i40e_pf *pf = vsi->back; 790 791 struct i40e_ring *ring; 792 + 793 + if (test_bit(__I40E_CONFIG_BUSY, pf->state)) 794 + return -ENETDOWN; 791 795 792 796 if (test_bit(__I40E_VSI_DOWN, vsi->state)) 793 797 return -ENETDOWN;
+6 -1
drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
··· 10261 10261 10262 10262 /* If transitioning XDP modes reconfigure rings */ 10263 10263 if (need_reset) { 10264 - int err = ixgbe_setup_tc(dev, adapter->hw_tcs); 10264 + int err; 10265 + 10266 + if (!prog) 10267 + /* Wait until ndo_xsk_wakeup completes. */ 10268 + synchronize_rcu(); 10269 + err = ixgbe_setup_tc(dev, adapter->hw_tcs); 10265 10270 10266 10271 if (err) { 10267 10272 rcu_assign_pointer(adapter->xdp_prog, old_prog);
+6 -2
drivers/net/ethernet/intel/ixgbe/ixgbe_xsk.c
··· 709 709 if (qid >= adapter->num_xdp_queues) 710 710 return -ENXIO; 711 711 712 - if (!adapter->xdp_ring[qid]->xsk_umem) 712 + ring = adapter->xdp_ring[qid]; 713 + 714 + if (test_bit(__IXGBE_TX_DISABLED, &ring->state)) 715 + return -ENETDOWN; 716 + 717 + if (!ring->xsk_umem) 713 718 return -ENXIO; 714 719 715 - ring = adapter->xdp_ring[qid]; 716 720 if (!napi_if_scheduled_mark_missed(&ring->q_vector->napi)) { 717 721 u64 eics = BIT_ULL(ring->q_vector->v_idx); 718 722
+1 -1
drivers/net/ethernet/mellanox/mlx5/core/en.h
··· 760 760 MLX5E_STATE_OPENED, 761 761 MLX5E_STATE_DESTROYING, 762 762 MLX5E_STATE_XDP_TX_ENABLED, 763 - MLX5E_STATE_XDP_OPEN, 763 + MLX5E_STATE_XDP_ACTIVE, 764 764 }; 765 765 766 766 struct mlx5e_rqt {
+9 -13
drivers/net/ethernet/mellanox/mlx5/core/en/xdp.h
··· 75 75 static inline void mlx5e_xdp_tx_enable(struct mlx5e_priv *priv) 76 76 { 77 77 set_bit(MLX5E_STATE_XDP_TX_ENABLED, &priv->state); 78 + 79 + if (priv->channels.params.xdp_prog) 80 + set_bit(MLX5E_STATE_XDP_ACTIVE, &priv->state); 78 81 } 79 82 80 83 static inline void mlx5e_xdp_tx_disable(struct mlx5e_priv *priv) 81 84 { 85 + if (priv->channels.params.xdp_prog) 86 + clear_bit(MLX5E_STATE_XDP_ACTIVE, &priv->state); 87 + 82 88 clear_bit(MLX5E_STATE_XDP_TX_ENABLED, &priv->state); 83 - /* let other device's napi(s) see our new state */ 89 + /* Let other device's napi(s) and XSK wakeups see our new state. */ 84 90 synchronize_rcu(); 85 91 } 86 92 ··· 95 89 return test_bit(MLX5E_STATE_XDP_TX_ENABLED, &priv->state); 96 90 } 97 91 98 - static inline void mlx5e_xdp_set_open(struct mlx5e_priv *priv) 92 + static inline bool mlx5e_xdp_is_active(struct mlx5e_priv *priv) 99 93 { 100 - set_bit(MLX5E_STATE_XDP_OPEN, &priv->state); 101 - } 102 - 103 - static inline void mlx5e_xdp_set_closed(struct mlx5e_priv *priv) 104 - { 105 - clear_bit(MLX5E_STATE_XDP_OPEN, &priv->state); 106 - } 107 - 108 - static inline bool mlx5e_xdp_is_open(struct mlx5e_priv *priv) 109 - { 110 - return test_bit(MLX5E_STATE_XDP_OPEN, &priv->state); 94 + return test_bit(MLX5E_STATE_XDP_ACTIVE, &priv->state); 111 95 } 112 96 113 97 static inline void mlx5e_xmit_xdp_doorbell(struct mlx5e_xdpsq *sq)
+1
drivers/net/ethernet/mellanox/mlx5/core/en/xsk/setup.c
··· 144 144 { 145 145 clear_bit(MLX5E_CHANNEL_STATE_XSK, c->state); 146 146 napi_synchronize(&c->napi); 147 + synchronize_rcu(); /* Sync with the XSK wakeup. */ 147 148 148 149 mlx5e_close_rq(&c->xskrq); 149 150 mlx5e_close_cq(&c->xskrq.cq);
+1 -1
drivers/net/ethernet/mellanox/mlx5/core/en/xsk/tx.c
··· 14 14 struct mlx5e_channel *c; 15 15 u16 ix; 16 16 17 - if (unlikely(!mlx5e_xdp_is_open(priv))) 17 + if (unlikely(!mlx5e_xdp_is_active(priv))) 18 18 return -ENETDOWN; 19 19 20 20 if (unlikely(!mlx5e_qid_get_ch_if_in_group(params, qid, MLX5E_RQ_GROUP_XSK, &ix)))
+1 -18
drivers/net/ethernet/mellanox/mlx5/core/en_main.c
··· 3000 3000 int mlx5e_open_locked(struct net_device *netdev) 3001 3001 { 3002 3002 struct mlx5e_priv *priv = netdev_priv(netdev); 3003 - bool is_xdp = priv->channels.params.xdp_prog; 3004 3003 int err; 3005 3004 3006 3005 set_bit(MLX5E_STATE_OPENED, &priv->state); 3007 - if (is_xdp) 3008 - mlx5e_xdp_set_open(priv); 3009 3006 3010 3007 err = mlx5e_open_channels(priv, &priv->channels); 3011 3008 if (err) ··· 3017 3020 return 0; 3018 3021 3019 3022 err_clear_state_opened_flag: 3020 - if (is_xdp) 3021 - mlx5e_xdp_set_closed(priv); 3022 3023 clear_bit(MLX5E_STATE_OPENED, &priv->state); 3023 3024 return err; 3024 3025 } ··· 3048 3053 if (!test_bit(MLX5E_STATE_OPENED, &priv->state)) 3049 3054 return 0; 3050 3055 3051 - if (priv->channels.params.xdp_prog) 3052 - mlx5e_xdp_set_closed(priv); 3053 3056 clear_bit(MLX5E_STATE_OPENED, &priv->state); 3054 3057 3055 3058 netif_carrier_off(priv->netdev); ··· 4364 4371 return 0; 4365 4372 } 4366 4373 4367 - static int mlx5e_xdp_update_state(struct mlx5e_priv *priv) 4368 - { 4369 - if (priv->channels.params.xdp_prog) 4370 - mlx5e_xdp_set_open(priv); 4371 - else 4372 - mlx5e_xdp_set_closed(priv); 4373 - 4374 - return 0; 4375 - } 4376 - 4377 4374 static int mlx5e_xdp_set(struct net_device *netdev, struct bpf_prog *prog) 4378 4375 { 4379 4376 struct mlx5e_priv *priv = netdev_priv(netdev); ··· 4398 4415 mlx5e_set_rq_type(priv->mdev, &new_channels.params); 4399 4416 old_prog = priv->channels.params.xdp_prog; 4400 4417 4401 - err = mlx5e_safe_switch_channels(priv, &new_channels, mlx5e_xdp_update_state); 4418 + err = mlx5e_safe_switch_channels(priv, &new_channels, NULL); 4402 4419 if (err) 4403 4420 goto unlock; 4404 4421 } else {
+4 -4
include/linux/bpf-cgroup.h
··· 157 157 struct cgroup *cgroup, 158 158 enum bpf_attach_type type); 159 159 void bpf_cgroup_storage_unlink(struct bpf_cgroup_storage *storage); 160 - int bpf_cgroup_storage_assign(struct bpf_prog *prog, struct bpf_map *map); 161 - void bpf_cgroup_storage_release(struct bpf_prog *prog, struct bpf_map *map); 160 + int bpf_cgroup_storage_assign(struct bpf_prog_aux *aux, struct bpf_map *map); 161 + void bpf_cgroup_storage_release(struct bpf_prog_aux *aux, struct bpf_map *map); 162 162 163 163 int bpf_percpu_cgroup_storage_copy(struct bpf_map *map, void *key, void *value); 164 164 int bpf_percpu_cgroup_storage_update(struct bpf_map *map, void *key, ··· 360 360 361 361 static inline void bpf_cgroup_storage_set( 362 362 struct bpf_cgroup_storage *storage[MAX_BPF_CGROUP_STORAGE_TYPE]) {} 363 - static inline int bpf_cgroup_storage_assign(struct bpf_prog *prog, 363 + static inline int bpf_cgroup_storage_assign(struct bpf_prog_aux *aux, 364 364 struct bpf_map *map) { return 0; } 365 - static inline void bpf_cgroup_storage_release(struct bpf_prog *prog, 365 + static inline void bpf_cgroup_storage_release(struct bpf_prog_aux *aux, 366 366 struct bpf_map *map) {} 367 367 static inline struct bpf_cgroup_storage *bpf_cgroup_storage_alloc( 368 368 struct bpf_prog *prog, enum bpf_cgroup_storage_type stype) { return NULL; }
+2
include/linux/bpf.h
··· 818 818 void bpf_prog_put(struct bpf_prog *prog); 819 819 int __bpf_prog_charge(struct user_struct *user, u32 pages); 820 820 void __bpf_prog_uncharge(struct user_struct *user, u32 pages); 821 + void __bpf_free_used_maps(struct bpf_prog_aux *aux, 822 + struct bpf_map **used_maps, u32 len); 821 823 822 824 void bpf_prog_free_id(struct bpf_prog *prog, bool do_idr_lock); 823 825 void bpf_map_free_id(struct bpf_map *map, bool do_idr_lock);
+17 -12
kernel/bpf/core.c
··· 2043 2043 for_each_cgroup_storage_type(stype) { 2044 2044 if (!aux->cgroup_storage[stype]) 2045 2045 continue; 2046 - bpf_cgroup_storage_release(aux->prog, 2047 - aux->cgroup_storage[stype]); 2046 + bpf_cgroup_storage_release(aux, aux->cgroup_storage[stype]); 2047 + } 2048 + } 2049 + 2050 + void __bpf_free_used_maps(struct bpf_prog_aux *aux, 2051 + struct bpf_map **used_maps, u32 len) 2052 + { 2053 + struct bpf_map *map; 2054 + u32 i; 2055 + 2056 + bpf_free_cgroup_storage(aux); 2057 + for (i = 0; i < len; i++) { 2058 + map = used_maps[i]; 2059 + if (map->ops->map_poke_untrack) 2060 + map->ops->map_poke_untrack(map, aux); 2061 + bpf_map_put(map); 2048 2062 } 2049 2063 } 2050 2064 2051 2065 static void bpf_free_used_maps(struct bpf_prog_aux *aux) 2052 2066 { 2053 - struct bpf_map *map; 2054 - int i; 2055 - 2056 - bpf_free_cgroup_storage(aux); 2057 - for (i = 0; i < aux->used_map_cnt; i++) { 2058 - map = aux->used_maps[i]; 2059 - if (map->ops->map_poke_untrack) 2060 - map->ops->map_poke_untrack(map, aux); 2061 - bpf_map_put(map); 2062 - } 2067 + __bpf_free_used_maps(aux, aux->used_maps, aux->used_map_cnt); 2063 2068 kfree(aux->used_maps); 2064 2069 } 2065 2070
+12 -12
kernel/bpf/local_storage.c
··· 20 20 struct bpf_map map; 21 21 22 22 spinlock_t lock; 23 - struct bpf_prog *prog; 23 + struct bpf_prog_aux *aux; 24 24 struct rb_root root; 25 25 struct list_head list; 26 26 }; ··· 420 420 .map_seq_show_elem = cgroup_storage_seq_show_elem, 421 421 }; 422 422 423 - int bpf_cgroup_storage_assign(struct bpf_prog *prog, struct bpf_map *_map) 423 + int bpf_cgroup_storage_assign(struct bpf_prog_aux *aux, struct bpf_map *_map) 424 424 { 425 425 enum bpf_cgroup_storage_type stype = cgroup_storage_type(_map); 426 426 struct bpf_cgroup_storage_map *map = map_to_storage(_map); ··· 428 428 429 429 spin_lock_bh(&map->lock); 430 430 431 - if (map->prog && map->prog != prog) 431 + if (map->aux && map->aux != aux) 432 432 goto unlock; 433 - if (prog->aux->cgroup_storage[stype] && 434 - prog->aux->cgroup_storage[stype] != _map) 433 + if (aux->cgroup_storage[stype] && 434 + aux->cgroup_storage[stype] != _map) 435 435 goto unlock; 436 436 437 - map->prog = prog; 438 - prog->aux->cgroup_storage[stype] = _map; 437 + map->aux = aux; 438 + aux->cgroup_storage[stype] = _map; 439 439 ret = 0; 440 440 unlock: 441 441 spin_unlock_bh(&map->lock); ··· 443 443 return ret; 444 444 } 445 445 446 - void bpf_cgroup_storage_release(struct bpf_prog *prog, struct bpf_map *_map) 446 + void bpf_cgroup_storage_release(struct bpf_prog_aux *aux, struct bpf_map *_map) 447 447 { 448 448 enum bpf_cgroup_storage_type stype = cgroup_storage_type(_map); 449 449 struct bpf_cgroup_storage_map *map = map_to_storage(_map); 450 450 451 451 spin_lock_bh(&map->lock); 452 - if (map->prog == prog) { 453 - WARN_ON(prog->aux->cgroup_storage[stype] != _map); 454 - map->prog = NULL; 455 - prog->aux->cgroup_storage[stype] = NULL; 452 + if (map->aux == aux) { 453 + WARN_ON(aux->cgroup_storage[stype] != _map); 454 + map->aux = NULL; 455 + aux->cgroup_storage[stype] = NULL; 456 456 } 457 457 spin_unlock_bh(&map->lock); 458 458 }
+10 -14
kernel/bpf/verifier.c
··· 4134 4134 struct bpf_map *map = meta->map_ptr; 4135 4135 struct tnum range; 4136 4136 u64 val; 4137 + int err; 4137 4138 4138 4139 if (func_id != BPF_FUNC_tail_call) 4139 4140 return 0; ··· 4150 4149 bpf_map_key_store(aux, BPF_MAP_KEY_POISON); 4151 4150 return 0; 4152 4151 } 4152 + 4153 + err = mark_chain_precision(env, BPF_REG_3); 4154 + if (err) 4155 + return err; 4153 4156 4154 4157 val = reg->var_off.value; 4155 4158 if (bpf_map_key_unseen(aux)) ··· 8273 8268 env->used_maps[env->used_map_cnt++] = map; 8274 8269 8275 8270 if (bpf_map_is_cgroup_storage(map) && 8276 - bpf_cgroup_storage_assign(env->prog, map)) { 8271 + bpf_cgroup_storage_assign(env->prog->aux, map)) { 8277 8272 verbose(env, "only one cgroup storage of each type is allowed\n"); 8278 8273 fdput(f); 8279 8274 return -EBUSY; ··· 8303 8298 /* drop refcnt of maps used by the rejected program */ 8304 8299 static void release_maps(struct bpf_verifier_env *env) 8305 8300 { 8306 - enum bpf_cgroup_storage_type stype; 8307 - int i; 8308 - 8309 - for_each_cgroup_storage_type(stype) { 8310 - if (!env->prog->aux->cgroup_storage[stype]) 8311 - continue; 8312 - bpf_cgroup_storage_release(env->prog, 8313 - env->prog->aux->cgroup_storage[stype]); 8314 - } 8315 - 8316 - for (i = 0; i < env->used_map_cnt; i++) 8317 - bpf_map_put(env->used_maps[i]); 8301 + __bpf_free_used_maps(env->prog->aux, env->used_maps, 8302 + env->used_map_cnt); 8318 8303 } 8319 8304 8320 8305 /* convert pseudo BPF_LD_IMM64 into generic BPF_LD_IMM64 */ ··· 9277 9282 insn->code = BPF_JMP | BPF_TAIL_CALL; 9278 9283 9279 9284 aux = &env->insn_aux_data[i + delta]; 9280 - if (prog->jit_requested && !expect_blinding && 9285 + if (env->allow_ptr_leaks && !expect_blinding && 9286 + prog->jit_requested && 9281 9287 !bpf_map_key_poisoned(aux) && 9282 9288 !bpf_map_ptr_poisoned(aux) && 9283 9289 !bpf_map_ptr_unpriv(aux)) {
+1
net/core/filter.c
··· 2055 2055 } 2056 2056 2057 2057 skb->dev = dev; 2058 + skb->tstamp = 0; 2058 2059 2059 2060 dev_xmit_recursion_inc(); 2060 2061 ret = dev_queue_xmit(skb);
+2
net/core/sysctl_net_core.c
··· 288 288 return ret; 289 289 } 290 290 291 + # ifdef CONFIG_HAVE_EBPF_JIT 291 292 static int 292 293 proc_dointvec_minmax_bpf_restricted(struct ctl_table *table, int write, 293 294 void __user *buffer, size_t *lenp, ··· 299 298 300 299 return proc_dointvec_minmax(table, write, buffer, lenp, ppos); 301 300 } 301 + # endif /* CONFIG_HAVE_EBPF_JIT */ 302 302 303 303 static int 304 304 proc_dolongvec_minmax_bpf_restricted(struct ctl_table *table, int write,
+14 -8
net/xdp/xsk.c
··· 334 334 } 335 335 EXPORT_SYMBOL(xsk_umem_consume_tx); 336 336 337 - static int xsk_zc_xmit(struct xdp_sock *xs) 337 + static int xsk_wakeup(struct xdp_sock *xs, u8 flags) 338 338 { 339 339 struct net_device *dev = xs->dev; 340 + int err; 340 341 341 - return dev->netdev_ops->ndo_xsk_wakeup(dev, xs->queue_id, 342 - XDP_WAKEUP_TX); 342 + rcu_read_lock(); 343 + err = dev->netdev_ops->ndo_xsk_wakeup(dev, xs->queue_id, flags); 344 + rcu_read_unlock(); 345 + 346 + return err; 347 + } 348 + 349 + static int xsk_zc_xmit(struct xdp_sock *xs) 350 + { 351 + return xsk_wakeup(xs, XDP_WAKEUP_TX); 343 352 } 344 353 345 354 static void xsk_destruct_skb(struct sk_buff *skb) ··· 462 453 __poll_t mask = datagram_poll(file, sock, wait); 463 454 struct sock *sk = sock->sk; 464 455 struct xdp_sock *xs = xdp_sk(sk); 465 - struct net_device *dev; 466 456 struct xdp_umem *umem; 467 457 468 458 if (unlikely(!xsk_is_bound(xs))) 469 459 return mask; 470 460 471 - dev = xs->dev; 472 461 umem = xs->umem; 473 462 474 463 if (umem->need_wakeup) { 475 - if (dev->netdev_ops->ndo_xsk_wakeup) 476 - dev->netdev_ops->ndo_xsk_wakeup(dev, xs->queue_id, 477 - umem->need_wakeup); 464 + if (xs->zc) 465 + xsk_wakeup(xs, umem->need_wakeup); 478 466 else 479 467 /* Poll needs to drive Tx also in copy mode */ 480 468 __xsk_sendmsg(sk);
+22 -21
tools/testing/selftests/bpf/test_verifier.c
··· 408 408 assert(!bpf_map_update_elem(fd, &index, &value, 0)); 409 409 } 410 410 411 - static int create_prog_dummy1(enum bpf_prog_type prog_type) 411 + static int create_prog_dummy_simple(enum bpf_prog_type prog_type, int ret) 412 412 { 413 413 struct bpf_insn prog[] = { 414 - BPF_MOV64_IMM(BPF_REG_0, 42), 414 + BPF_MOV64_IMM(BPF_REG_0, ret), 415 415 BPF_EXIT_INSN(), 416 416 }; 417 417 ··· 419 419 ARRAY_SIZE(prog), "GPL", 0, NULL, 0); 420 420 } 421 421 422 - static int create_prog_dummy2(enum bpf_prog_type prog_type, int mfd, int idx) 422 + static int create_prog_dummy_loop(enum bpf_prog_type prog_type, int mfd, 423 + int idx, int ret) 423 424 { 424 425 struct bpf_insn prog[] = { 425 426 BPF_MOV64_IMM(BPF_REG_3, idx), 426 427 BPF_LD_MAP_FD(BPF_REG_2, mfd), 427 428 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, 428 429 BPF_FUNC_tail_call), 429 - BPF_MOV64_IMM(BPF_REG_0, 41), 430 + BPF_MOV64_IMM(BPF_REG_0, ret), 430 431 BPF_EXIT_INSN(), 431 432 }; 432 433 ··· 436 435 } 437 436 438 437 static int create_prog_array(enum bpf_prog_type prog_type, uint32_t max_elem, 439 - int p1key) 438 + int p1key, int p2key, int p3key) 440 439 { 441 - int p2key = 1; 442 - int mfd, p1fd, p2fd; 440 + int mfd, p1fd, p2fd, p3fd; 443 441 444 442 mfd = bpf_create_map(BPF_MAP_TYPE_PROG_ARRAY, sizeof(int), 445 443 sizeof(int), max_elem, 0); ··· 449 449 return -1; 450 450 } 451 451 452 - p1fd = create_prog_dummy1(prog_type); 453 - p2fd = create_prog_dummy2(prog_type, mfd, p2key); 454 - if (p1fd < 0 || p2fd < 0) 455 - goto out; 452 + p1fd = create_prog_dummy_simple(prog_type, 42); 453 + p2fd = create_prog_dummy_loop(prog_type, mfd, p2key, 41); 454 + p3fd = create_prog_dummy_simple(prog_type, 24); 455 + if (p1fd < 0 || p2fd < 0 || p3fd < 0) 456 + goto err; 456 457 if (bpf_map_update_elem(mfd, &p1key, &p1fd, BPF_ANY) < 0) 457 - goto out; 458 + goto err; 458 459 if (bpf_map_update_elem(mfd, &p2key, &p2fd, BPF_ANY) < 0) 459 - goto out; 460 + goto err; 461 + if (bpf_map_update_elem(mfd, &p3key, &p3fd, BPF_ANY) < 0) { 462 + err: 463 + close(mfd); 464 + mfd = -1; 465 + } 466 + close(p3fd); 460 467 close(p2fd); 461 468 close(p1fd); 462 - 463 469 return mfd; 464 - out: 465 - close(p2fd); 466 - close(p1fd); 467 - close(mfd); 468 - return -1; 469 470 } 470 471 471 472 static int create_map_in_map(void) ··· 685 684 } 686 685 687 686 if (*fixup_prog1) { 688 - map_fds[4] = create_prog_array(prog_type, 4, 0); 687 + map_fds[4] = create_prog_array(prog_type, 4, 0, 1, 2); 689 688 do { 690 689 prog[*fixup_prog1].imm = map_fds[4]; 691 690 fixup_prog1++; ··· 693 692 } 694 693 695 694 if (*fixup_prog2) { 696 - map_fds[5] = create_prog_array(prog_type, 8, 7); 695 + map_fds[5] = create_prog_array(prog_type, 8, 7, 1, 2); 697 696 do { 698 697 prog[*fixup_prog2].imm = map_fds[5]; 699 698 fixup_prog2++;
+3 -3
tools/testing/selftests/bpf/verifier/ref_tracking.c
··· 455 455 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0), 456 456 BPF_JMP_IMM(BPF_JNE, BPF_REG_1, 0, 7), 457 457 /* bpf_tail_call() */ 458 - BPF_MOV64_IMM(BPF_REG_3, 2), 458 + BPF_MOV64_IMM(BPF_REG_3, 3), 459 459 BPF_LD_MAP_FD(BPF_REG_2, 0), 460 460 BPF_MOV64_REG(BPF_REG_1, BPF_REG_7), 461 461 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_tail_call), ··· 478 478 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 1), 479 479 BPF_EMIT_CALL(BPF_FUNC_sk_release), 480 480 /* bpf_tail_call() */ 481 - BPF_MOV64_IMM(BPF_REG_3, 2), 481 + BPF_MOV64_IMM(BPF_REG_3, 3), 482 482 BPF_LD_MAP_FD(BPF_REG_2, 0), 483 483 BPF_MOV64_REG(BPF_REG_1, BPF_REG_7), 484 484 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_tail_call), ··· 497 497 BPF_SK_LOOKUP(sk_lookup_tcp), 498 498 /* bpf_tail_call() */ 499 499 BPF_MOV64_REG(BPF_REG_6, BPF_REG_0), 500 - BPF_MOV64_IMM(BPF_REG_3, 2), 500 + BPF_MOV64_IMM(BPF_REG_3, 3), 501 501 BPF_LD_MAP_FD(BPF_REG_2, 0), 502 502 BPF_MOV64_REG(BPF_REG_1, BPF_REG_7), 503 503 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_tail_call),
+152 -1
tools/testing/selftests/bpf/verifier/runtime_jit.c
··· 27 27 { 28 28 "runtime/jit: tail_call within bounds, no prog", 29 29 .insns = { 30 - BPF_MOV64_IMM(BPF_REG_3, 2), 30 + BPF_MOV64_IMM(BPF_REG_3, 3), 31 31 BPF_LD_MAP_FD(BPF_REG_2, 0), 32 32 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_tail_call), 33 33 BPF_MOV64_IMM(BPF_REG_0, 1), ··· 36 36 .fixup_prog1 = { 1 }, 37 37 .result = ACCEPT, 38 38 .retval = 1, 39 + }, 40 + { 41 + "runtime/jit: tail_call within bounds, key 2", 42 + .insns = { 43 + BPF_MOV64_IMM(BPF_REG_3, 2), 44 + BPF_LD_MAP_FD(BPF_REG_2, 0), 45 + BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_tail_call), 46 + BPF_MOV64_IMM(BPF_REG_0, 1), 47 + BPF_EXIT_INSN(), 48 + }, 49 + .fixup_prog1 = { 1 }, 50 + .result = ACCEPT, 51 + .retval = 24, 52 + }, 53 + { 54 + "runtime/jit: tail_call within bounds, key 2 / key 2, first branch", 55 + .insns = { 56 + BPF_MOV64_IMM(BPF_REG_0, 13), 57 + BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0, 58 + offsetof(struct __sk_buff, cb[0])), 59 + BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1, 60 + offsetof(struct __sk_buff, cb[0])), 61 + BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 13, 4), 62 + BPF_MOV64_IMM(BPF_REG_3, 2), 63 + BPF_LD_MAP_FD(BPF_REG_2, 0), 64 + BPF_JMP_IMM(BPF_JA, 0, 0, 3), 65 + BPF_MOV64_IMM(BPF_REG_3, 2), 66 + BPF_LD_MAP_FD(BPF_REG_2, 0), 67 + BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_tail_call), 68 + BPF_MOV64_IMM(BPF_REG_0, 1), 69 + BPF_EXIT_INSN(), 70 + }, 71 + .fixup_prog1 = { 5, 9 }, 72 + .result = ACCEPT, 73 + .retval = 24, 74 + }, 75 + { 76 + "runtime/jit: tail_call within bounds, key 2 / key 2, second branch", 77 + .insns = { 78 + BPF_MOV64_IMM(BPF_REG_0, 14), 79 + BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0, 80 + offsetof(struct __sk_buff, cb[0])), 81 + BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1, 82 + offsetof(struct __sk_buff, cb[0])), 83 + BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 13, 4), 84 + BPF_MOV64_IMM(BPF_REG_3, 2), 85 + BPF_LD_MAP_FD(BPF_REG_2, 0), 86 + BPF_JMP_IMM(BPF_JA, 0, 0, 3), 87 + BPF_MOV64_IMM(BPF_REG_3, 2), 88 + BPF_LD_MAP_FD(BPF_REG_2, 0), 89 + BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_tail_call), 90 + BPF_MOV64_IMM(BPF_REG_0, 1), 91 + BPF_EXIT_INSN(), 92 + }, 93 + .fixup_prog1 = { 5, 9 }, 94 + .result = ACCEPT, 95 + .retval = 24, 96 + }, 97 + { 98 + "runtime/jit: tail_call within bounds, key 0 / key 2, first branch", 99 + .insns = { 100 + BPF_MOV64_IMM(BPF_REG_0, 13), 101 + BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0, 102 + offsetof(struct __sk_buff, cb[0])), 103 + BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1, 104 + offsetof(struct __sk_buff, cb[0])), 105 + BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 13, 4), 106 + BPF_MOV64_IMM(BPF_REG_3, 0), 107 + BPF_LD_MAP_FD(BPF_REG_2, 0), 108 + BPF_JMP_IMM(BPF_JA, 0, 0, 3), 109 + BPF_MOV64_IMM(BPF_REG_3, 2), 110 + BPF_LD_MAP_FD(BPF_REG_2, 0), 111 + BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_tail_call), 112 + BPF_MOV64_IMM(BPF_REG_0, 1), 113 + BPF_EXIT_INSN(), 114 + }, 115 + .fixup_prog1 = { 5, 9 }, 116 + .result = ACCEPT, 117 + .retval = 24, 118 + }, 119 + { 120 + "runtime/jit: tail_call within bounds, key 0 / key 2, second branch", 121 + .insns = { 122 + BPF_MOV64_IMM(BPF_REG_0, 14), 123 + BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0, 124 + offsetof(struct __sk_buff, cb[0])), 125 + BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1, 126 + offsetof(struct __sk_buff, cb[0])), 127 + BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 13, 4), 128 + BPF_MOV64_IMM(BPF_REG_3, 0), 129 + BPF_LD_MAP_FD(BPF_REG_2, 0), 130 + BPF_JMP_IMM(BPF_JA, 0, 0, 3), 131 + BPF_MOV64_IMM(BPF_REG_3, 2), 132 + BPF_LD_MAP_FD(BPF_REG_2, 0), 133 + BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_tail_call), 134 + BPF_MOV64_IMM(BPF_REG_0, 1), 135 + BPF_EXIT_INSN(), 136 + }, 137 + .fixup_prog1 = { 5, 9 }, 138 + .result = ACCEPT, 139 + .retval = 42, 140 + }, 141 + { 142 + "runtime/jit: tail_call within bounds, different maps, first branch", 143 + .insns = { 144 + BPF_MOV64_IMM(BPF_REG_0, 13), 145 + BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0, 146 + offsetof(struct __sk_buff, cb[0])), 147 + BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1, 148 + offsetof(struct __sk_buff, cb[0])), 149 + BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 13, 4), 150 + BPF_MOV64_IMM(BPF_REG_3, 0), 151 + BPF_LD_MAP_FD(BPF_REG_2, 0), 152 + BPF_JMP_IMM(BPF_JA, 0, 0, 3), 153 + BPF_MOV64_IMM(BPF_REG_3, 0), 154 + BPF_LD_MAP_FD(BPF_REG_2, 0), 155 + BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_tail_call), 156 + BPF_MOV64_IMM(BPF_REG_0, 1), 157 + BPF_EXIT_INSN(), 158 + }, 159 + .fixup_prog1 = { 5 }, 160 + .fixup_prog2 = { 9 }, 161 + .result_unpriv = REJECT, 162 + .errstr_unpriv = "tail_call abusing map_ptr", 163 + .result = ACCEPT, 164 + .retval = 1, 165 + }, 166 + { 167 + "runtime/jit: tail_call within bounds, different maps, second branch", 168 + .insns = { 169 + BPF_MOV64_IMM(BPF_REG_0, 14), 170 + BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0, 171 + offsetof(struct __sk_buff, cb[0])), 172 + BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1, 173 + offsetof(struct __sk_buff, cb[0])), 174 + BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 13, 4), 175 + BPF_MOV64_IMM(BPF_REG_3, 0), 176 + BPF_LD_MAP_FD(BPF_REG_2, 0), 177 + BPF_JMP_IMM(BPF_JA, 0, 0, 3), 178 + BPF_MOV64_IMM(BPF_REG_3, 0), 179 + BPF_LD_MAP_FD(BPF_REG_2, 0), 180 + BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_tail_call), 181 + BPF_MOV64_IMM(BPF_REG_0, 1), 182 + BPF_EXIT_INSN(), 183 + }, 184 + .fixup_prog1 = { 5 }, 185 + .fixup_prog2 = { 9 }, 186 + .result_unpriv = REJECT, 187 + .errstr_unpriv = "tail_call abusing map_ptr", 188 + .result = ACCEPT, 189 + .retval = 42, 39 190 }, 40 191 { 41 192 "runtime/jit: tail_call out of bounds",