Skip to content

Commit 9d94769

Browse files
committed
Daniel Borkmann says: ==================== bpf 2023-04-19 We've added 3 non-merge commits during the last 6 day(s) which contain a total of 3 files changed, 34 insertions(+), 9 deletions(-). The main changes are: 1) Fix a crash on s390's bpf_arch_text_poke() under a NULL new_addr, from Ilya Leoshkevich. 2) Fix a bug in BPF verifier's precision tracker, from Daniel Borkmann and Andrii Nakryiko. 3) Fix a regression in veth's xdp_features which led to a broken BPF CI selftest, from Lorenzo Bianconi. * tag 'for-netdev' of https://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf: bpf: Fix incorrect verifier pruning due to missing register precision taints veth: take into account peer device for NETDEV_XDP_ACT_NDO_XMIT xdp_features flag s390/bpf: Fix bpf_arch_text_poke() with new_addr == NULL ==================== Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Jakub Kicinski <[email protected]>
2 parents 52b37ae + 71b547f commit 9d94769

File tree

3 files changed

+34
-9
lines changed

3 files changed

+34
-9
lines changed

arch/s390/net/bpf_jit_comp.c

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -539,7 +539,7 @@ static void bpf_jit_plt(void *plt, void *ret, void *target)
539539
{
540540
memcpy(plt, bpf_plt, BPF_PLT_SIZE);
541541
*(void **)((char *)plt + (bpf_plt_ret - bpf_plt)) = ret;
542-
*(void **)((char *)plt + (bpf_plt_target - bpf_plt)) = target;
542+
*(void **)((char *)plt + (bpf_plt_target - bpf_plt)) = target ?: ret;
543543
}
544544

545545
/*
@@ -2010,7 +2010,9 @@ int bpf_arch_text_poke(void *ip, enum bpf_text_poke_type t,
20102010
} __packed insn;
20112011
char expected_plt[BPF_PLT_SIZE];
20122012
char current_plt[BPF_PLT_SIZE];
2013+
char new_plt[BPF_PLT_SIZE];
20132014
char *plt;
2015+
char *ret;
20142016
int err;
20152017

20162018
/* Verify the branch to be patched. */
@@ -2032,12 +2034,15 @@ int bpf_arch_text_poke(void *ip, enum bpf_text_poke_type t,
20322034
err = copy_from_kernel_nofault(current_plt, plt, BPF_PLT_SIZE);
20332035
if (err < 0)
20342036
return err;
2035-
bpf_jit_plt(expected_plt, (char *)ip + 6, old_addr);
2037+
ret = (char *)ip + 6;
2038+
bpf_jit_plt(expected_plt, ret, old_addr);
20362039
if (memcmp(current_plt, expected_plt, BPF_PLT_SIZE))
20372040
return -EINVAL;
20382041
/* Adjust the call address. */
2042+
bpf_jit_plt(new_plt, ret, new_addr);
20392043
s390_kernel_write(plt + (bpf_plt_target - bpf_plt),
2040-
&new_addr, sizeof(void *));
2044+
new_plt + (bpf_plt_target - bpf_plt),
2045+
sizeof(void *));
20412046
}
20422047

20432048
/* Adjust the mask of the branch. */

drivers/net/veth.c

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1262,11 +1262,12 @@ static void veth_set_xdp_features(struct net_device *dev)
12621262

12631263
peer = rtnl_dereference(priv->peer);
12641264
if (peer && peer->real_num_tx_queues <= dev->real_num_rx_queues) {
1265+
struct veth_priv *priv_peer = netdev_priv(peer);
12651266
xdp_features_t val = NETDEV_XDP_ACT_BASIC |
12661267
NETDEV_XDP_ACT_REDIRECT |
12671268
NETDEV_XDP_ACT_RX_SG;
12681269

1269-
if (priv->_xdp_prog || veth_gro_requested(dev))
1270+
if (priv_peer->_xdp_prog || veth_gro_requested(peer))
12701271
val |= NETDEV_XDP_ACT_NDO_XMIT |
12711272
NETDEV_XDP_ACT_NDO_XMIT_SG;
12721273
xdp_set_features_flag(dev, val);
@@ -1504,19 +1505,23 @@ static int veth_set_features(struct net_device *dev,
15041505
{
15051506
netdev_features_t changed = features ^ dev->features;
15061507
struct veth_priv *priv = netdev_priv(dev);
1508+
struct net_device *peer;
15071509
int err;
15081510

15091511
if (!(changed & NETIF_F_GRO) || !(dev->flags & IFF_UP) || priv->_xdp_prog)
15101512
return 0;
15111513

1514+
peer = rtnl_dereference(priv->peer);
15121515
if (features & NETIF_F_GRO) {
15131516
err = veth_napi_enable(dev);
15141517
if (err)
15151518
return err;
15161519

1517-
xdp_features_set_redirect_target(dev, true);
1520+
if (peer)
1521+
xdp_features_set_redirect_target(peer, true);
15181522
} else {
1519-
xdp_features_clear_redirect_target(dev);
1523+
if (peer)
1524+
xdp_features_clear_redirect_target(peer);
15201525
veth_napi_del(dev);
15211526
}
15221527
return 0;
@@ -1598,13 +1603,13 @@ static int veth_xdp_set(struct net_device *dev, struct bpf_prog *prog,
15981603
peer->max_mtu = max_mtu;
15991604
}
16001605

1601-
xdp_features_set_redirect_target(dev, true);
1606+
xdp_features_set_redirect_target(peer, true);
16021607
}
16031608

16041609
if (old_prog) {
16051610
if (!prog) {
1606-
if (!veth_gro_requested(dev))
1607-
xdp_features_clear_redirect_target(dev);
1611+
if (peer && !veth_gro_requested(dev))
1612+
xdp_features_clear_redirect_target(peer);
16081613

16091614
if (dev->flags & IFF_UP)
16101615
veth_disable_xdp(dev);

kernel/bpf/verifier.c

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2967,6 +2967,21 @@ static int backtrack_insn(struct bpf_verifier_env *env, int idx,
29672967
}
29682968
} else if (opcode == BPF_EXIT) {
29692969
return -ENOTSUPP;
2970+
} else if (BPF_SRC(insn->code) == BPF_X) {
2971+
if (!(*reg_mask & (dreg | sreg)))
2972+
return 0;
2973+
/* dreg <cond> sreg
2974+
* Both dreg and sreg need precision before
2975+
* this insn. If only sreg was marked precise
2976+
* before it would be equally necessary to
2977+
* propagate it to dreg.
2978+
*/
2979+
*reg_mask |= (sreg | dreg);
2980+
/* else dreg <cond> K
2981+
* Only dreg still needs precision before
2982+
* this insn, so for the K-based conditional
2983+
* there is nothing new to be marked.
2984+
*/
29702985
}
29712986
} else if (class == BPF_LD) {
29722987
if (!(*reg_mask & dreg))

0 commit comments

Comments
 (0)