Commit 2786ae33 authored by Jakub Kicinski's avatar Jakub Kicinski
Browse files
Daniel Borkmann says:

====================
pull-request: bpf 2024-05-27

We've added 15 non-merge commits during the last 7 day(s) which contain
a total of 18 files changed, 583 insertions(+), 55 deletions(-).

The main changes are:

1) Fix broken BPF multi-uprobe PID filtering logic which filtered by thread
   while the promise was to filter by process, from Andrii Nakryiko.

2) Fix the recent influx of syzkaller reports to sockmap which triggered
   a locking rule violation by performing a map_delete, from Jakub Sitnicki.

3) Fixes to netkit driver in particular on skb->pkt_type override upon pass
   verdict, from Daniel Borkmann.

4) Fix an integer overflow in resolve_btfids which can wrongly trigger build
   failures, from Friedrich Vock.

5) Follow-up fixes for ARC JIT reported by static analyzers,
   from Shahab Vahedi.

* tag 'for-netdev' of https://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf:
  selftests/bpf: Cover verifier checks for mutating sockmap/sockhash
  Revert "bpf, sockmap: Prevent lock inversion deadlock in map delete elem"
  bpf: Allow delete from sockmap/sockhash only if update is allowed
  selftests/bpf: Add netkit test for pkt_type
  selftests/bpf: Add netkit tests for mac address
  netkit: Fix pkt_type override upon netkit pass verdict
  netkit: Fix setting mac address in l2 mode
  ARC, bpf: Fix issues reported by the static analyzers
  selftests/bpf: extend multi-uprobe tests with USDTs
  selftests/bpf: extend multi-uprobe tests with child thread case
  libbpf: detect broken PID filtering logic for multi-uprobe
  bpf: remove unnecessary rcu_read_{lock,unlock}() in multi-uprobe attach logic
  bpf: fix multi-uprobe PID filtering logic
  bpf: Fix potential integer overflow in resolve_btfids
  MAINTAINERS: Add myself as reviewer of ARM64 BPF JIT
====================

Link: https://lore.kernel.org/r/20240527203551.29712-1-daniel@iogearbox.net


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parents 52a2f060 a63bf556
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -3855,6 +3855,7 @@ BPF JIT for ARM64
M:	Daniel Borkmann <daniel@iogearbox.net>
M:	Alexei Starovoitov <ast@kernel.org>
M:	Puranjay Mohan <puranjay@kernel.org>
R:	Xu Kuohai <xukuohai@huaweicloud.com>
L:	bpf@vger.kernel.org
S:	Supported
F:	arch/arm64/net/
+1 −1
Original line number Diff line number Diff line
@@ -39,7 +39,7 @@

/************** Functions that the back-end must provide **************/
/* Extension for 32-bit operations. */
inline u8 zext(u8 *buf, u8 rd);
u8 zext(u8 *buf, u8 rd);
/***** Moves *****/
u8 mov_r32(u8 *buf, u8 rd, u8 rs, u8 sign_ext);
u8 mov_r32_i32(u8 *buf, u8 reg, s32 imm);
+6 −4
Original line number Diff line number Diff line
@@ -62,7 +62,7 @@ enum {
 *   If/when we decide to add ARCv2 instructions that do use register pairs,
 *   the mapping, hopefully, doesn't need to be revisited.
 */
const u8 bpf2arc[][2] = {
static const u8 bpf2arc[][2] = {
	/* Return value from in-kernel function, and exit value from eBPF */
	[BPF_REG_0] = {ARC_R_8, ARC_R_9},
	/* Arguments from eBPF program to in-kernel function */
@@ -1302,7 +1302,7 @@ static u8 arc_b(u8 *buf, s32 offset)

/************* Packers (Deal with BPF_REGs) **************/

inline u8 zext(u8 *buf, u8 rd)
u8 zext(u8 *buf, u8 rd)
{
	if (rd != BPF_REG_FP)
		return arc_movi_r(buf, REG_HI(rd), 0);
@@ -2235,6 +2235,7 @@ u8 gen_swap(u8 *buf, u8 rd, u8 size, u8 endian, bool force, bool do_zext)
			break;
		default:
			/* The caller must have handled this. */
			break;
		}
	} else {
		/*
@@ -2253,6 +2254,7 @@ u8 gen_swap(u8 *buf, u8 rd, u8 size, u8 endian, bool force, bool do_zext)
			break;
		default:
			/* The caller must have handled this. */
			break;
		}
	}

@@ -2517,7 +2519,7 @@ u8 arc_epilogue(u8 *buf, u32 usage, u16 frame_size)
#define JCC64_NR_OF_JMPS 3	/* Number of jumps in jcc64 template. */
#define JCC64_INSNS_TO_END 3	/* Number of insn. inclusive the 2nd jmp to end. */
#define JCC64_SKIP_JMP 1	/* Index of the "skip" jump to "end". */
const struct {
static const struct {
	/*
	 * "jit_off" is common between all "jmp[]" and is coupled with
	 * "cond" of each "jmp[]" instance. e.g.:
@@ -2883,7 +2885,7 @@ u8 gen_jmp_64(u8 *buf, u8 rd, u8 rs, u8 cond, u32 curr_off, u32 targ_off)
 * The "ARC_CC_SET" becomes "CC_unequal" because of the "tst"
 * instruction that precedes the conditional branch.
 */
const u8 arcv2_32_jmps[ARC_CC_LAST] = {
static const u8 arcv2_32_jmps[ARC_CC_LAST] = {
	[ARC_CC_UGT] = CC_great_u,
	[ARC_CC_UGE] = CC_great_eq_u,
	[ARC_CC_ULT] = CC_less_u,
+11 −11
Original line number Diff line number Diff line
@@ -159,7 +159,7 @@ static void jit_dump(const struct jit_context *ctx)
/* Initialise the context so there's no garbage. */
static int jit_ctx_init(struct jit_context *ctx, struct bpf_prog *prog)
{
	memset(ctx, 0, sizeof(ctx));
	memset(ctx, 0, sizeof(*ctx));

	ctx->orig_prog = prog;

@@ -167,7 +167,7 @@ static int jit_ctx_init(struct jit_context *ctx, struct bpf_prog *prog)
	ctx->prog = bpf_jit_blind_constants(prog);
	if (IS_ERR(ctx->prog))
		return PTR_ERR(ctx->prog);
	ctx->blinded = (ctx->prog == ctx->orig_prog ? false : true);
	ctx->blinded = (ctx->prog != ctx->orig_prog);

	/* If the verifier doesn't zero-extend, then we have to do it. */
	ctx->do_zext = !ctx->prog->aux->verifier_zext;
@@ -1182,12 +1182,12 @@ static int jit_prepare(struct jit_context *ctx)
}

/*
 * All the "handle_*()" functions have been called before by the
 * "jit_prepare()". If there was an error, we would know by now.
 * Therefore, no extra error checking at this point, other than
 * a sanity check at the end that expects the calculated length
 * (jit.len) to be equal to the length of generated instructions
 * (jit.index).
 * jit_compile() is the real compilation phase. jit_prepare() is
 * invoked before jit_compile() as a dry-run to make sure everything
 * will go OK and allocate the necessary memory.
 *
 * In the end, jit_compile() checks if it has produced the same number
 * of instructions as jit_prepare() would.
 */
static int jit_compile(struct jit_context *ctx)
{
@@ -1407,9 +1407,9 @@ static struct bpf_prog *do_extra_pass(struct bpf_prog *prog)

/*
 * This function may be invoked twice for the same stream of BPF
 * instructions. The "extra pass" happens, when there are "call"s
 * involved that their addresses are not known during the first
 * invocation.
 * instructions. The "extra pass" happens, when there are
 * (re)locations involved that their addresses are not known
 * during the first run.
 */
struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog)
{
+24 −6
Original line number Diff line number Diff line
@@ -55,6 +55,7 @@ static void netkit_prep_forward(struct sk_buff *skb, bool xnet)
	skb_scrub_packet(skb, xnet);
	skb->priority = 0;
	nf_skip_egress(skb, true);
	skb_reset_mac_header(skb);
}

static struct netkit *netkit_priv(const struct net_device *dev)
@@ -78,6 +79,7 @@ static netdev_tx_t netkit_xmit(struct sk_buff *skb, struct net_device *dev)
		     skb_orphan_frags(skb, GFP_ATOMIC)))
		goto drop;
	netkit_prep_forward(skb, !net_eq(dev_net(dev), dev_net(peer)));
	eth_skb_pkt_type(skb, peer);
	skb->dev = peer;
	entry = rcu_dereference(nk->active);
	if (entry)
@@ -85,7 +87,7 @@ static netdev_tx_t netkit_xmit(struct sk_buff *skb, struct net_device *dev)
	switch (ret) {
	case NETKIT_NEXT:
	case NETKIT_PASS:
		skb->protocol = eth_type_trans(skb, skb->dev);
		eth_skb_pull_mac(skb);
		skb_postpull_rcsum(skb, eth_hdr(skb), ETH_HLEN);
		if (likely(__netif_rx(skb) == NET_RX_SUCCESS)) {
			dev_sw_netstats_tx_add(dev, 1, len);
@@ -155,6 +157,16 @@ static void netkit_set_multicast(struct net_device *dev)
	/* Nothing to do, we receive whatever gets pushed to us! */
}

static int netkit_set_macaddr(struct net_device *dev, void *sa)
{
	struct netkit *nk = netkit_priv(dev);

	if (nk->mode != NETKIT_L2)
		return -EOPNOTSUPP;

	return eth_mac_addr(dev, sa);
}

static void netkit_set_headroom(struct net_device *dev, int headroom)
{
	struct netkit *nk = netkit_priv(dev), *nk2;
@@ -198,6 +210,7 @@ static const struct net_device_ops netkit_netdev_ops = {
	.ndo_start_xmit		= netkit_xmit,
	.ndo_set_rx_mode	= netkit_set_multicast,
	.ndo_set_rx_headroom	= netkit_set_headroom,
	.ndo_set_mac_address	= netkit_set_macaddr,
	.ndo_get_iflink		= netkit_get_iflink,
	.ndo_get_peer_dev	= netkit_peer_dev,
	.ndo_get_stats64	= netkit_get_stats,
@@ -300,9 +313,11 @@ static int netkit_validate(struct nlattr *tb[], struct nlattr *data[],

	if (!attr)
		return 0;
	NL_SET_ERR_MSG_ATTR(extack, attr,
			    "Setting Ethernet address is not supported");
	return -EOPNOTSUPP;
	if (nla_len(attr) != ETH_ALEN)
		return -EINVAL;
	if (!is_valid_ether_addr(nla_data(attr)))
		return -EADDRNOTAVAIL;
	return 0;
}

static struct rtnl_link_ops netkit_link_ops;
@@ -365,6 +380,9 @@ static int netkit_new_link(struct net *src_net, struct net_device *dev,
		strscpy(ifname, "nk%d", IFNAMSIZ);
		ifname_assign_type = NET_NAME_ENUM;
	}
	if (mode != NETKIT_L2 &&
	    (tb[IFLA_ADDRESS] || tbp[IFLA_ADDRESS]))
		return -EOPNOTSUPP;

	net = rtnl_link_get_net(src_net, tbp);
	if (IS_ERR(net))
@@ -379,7 +397,7 @@ static int netkit_new_link(struct net *src_net, struct net_device *dev,

	netif_inherit_tso_max(peer, dev);

	if (mode == NETKIT_L2)
	if (mode == NETKIT_L2 && !(ifmp && tbp[IFLA_ADDRESS]))
		eth_hw_addr_random(peer);
	if (ifmp && dev->ifindex)
		peer->ifindex = ifmp->ifi_index;
@@ -402,7 +420,7 @@ static int netkit_new_link(struct net *src_net, struct net_device *dev,
	if (err < 0)
		goto err_configure_peer;

	if (mode == NETKIT_L2)
	if (mode == NETKIT_L2 && !tb[IFLA_ADDRESS])
		eth_hw_addr_random(dev);
	if (tb[IFLA_IFNAME])
		nla_strscpy(dev->name, tb[IFLA_IFNAME], IFNAMSIZ);
Loading