Commit 825464e7 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull networking fixes from Paolo Abeni:
 "Including fixes from bpf and netfilter.

  Current release - regressions:

   - eth: amt: fix possible null-ptr-deref in amt_rcv()

  Previous releases - regressions:

   - tcp: use alloc_large_system_hash() to allocate table_perturb

   - af_unix: fix a data-race in unix_dgram_peer_wake_me()

   - nfc: st21nfca: fix memory leaks in EVT_TRANSACTION handling

   - eth: ixgbe: fix unexpected VLAN rx in promisc mode on VF

  Previous releases - always broken:

   - ipv6: fix signed integer overflow in __ip6_append_data

   - netfilter:
       - nat: really support inet nat without l3 address
       - nf_tables: memleak flow rule from commit path

   - bpf: fix calling global functions from BPF_PROG_TYPE_EXT programs

   - openvswitch: fix misuse of the cached connection on tuple changes

   - nfc: nfcmrvl: fix memory leak in nfcmrvl_play_deferred

   - eth: altera: fix refcount leak in altera_tse_mdio_create

  Misc:

   - add Quentin Monnet to bpftool maintainers"

* tag 'net-5.19-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net: (45 commits)
  net: amd-xgbe: fix clang -Wformat warning
  tcp: use alloc_large_system_hash() to allocate table_perturb
  net: dsa: realtek: rtl8365mb: fix GMII caps for ports with internal PHY
  net: dsa: mv88e6xxx: correctly report serdes link failure
  net: dsa: mv88e6xxx: fix BMSR error to be consistent with others
  net: dsa: mv88e6xxx: use BMSR_ANEGCOMPLETE bit for filling an_complete
  net: altera: Fix refcount leak in altera_tse_mdio_create
  net: openvswitch: fix misuse of the cached connection on tuple changes
  net: ethernet: mtk_eth_soc: fix misuse of mem alloc interface netdev[napi]_alloc_frag
  ip_gre: test csum_start instead of transport header
  au1000_eth: stop using virt_to_bus()
  ipv6: Fix signed integer overflow in l2tp_ip6_sendmsg
  ipv6: Fix signed integer overflow in __ip6_append_data
  nfc: nfcmrvl: Fix memory leak in nfcmrvl_play_deferred
  nfc: st21nfca: fix incorrect sizing calculations in EVT_TRANSACTION
  nfc: st21nfca: fix memory leaks in EVT_TRANSACTION handling
  nfc: st21nfca: fix incorrect validating logic in EVT_TRANSACTION
  net: ipv6: unexport __init-annotated seg6_hmac_init()
  net: xfrm: unexport __init-annotated xfrm4_protocol_init()
  net: mdio: unexport __init-annotated mdio_bus_init()
  ...
parents 507160f4 647df0d4
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -3757,6 +3757,13 @@ F: include/linux/bpf_lsm.h
F:	kernel/bpf/bpf_lsm.c
F:	security/bpf/
BPFTOOL
M:	Quentin Monnet <quentin@isovalent.com>
L:	bpf@vger.kernel.org
S:	Maintained
F:	kernel/bpf/disasm.*
F:	tools/bpf/bpftool/
BROADCOM B44 10/100 ETHERNET DRIVER
M:	Michael Chan <michael.chan@broadcom.com>
L:	netdev@vger.kernel.org
+1 −0
Original line number Diff line number Diff line
@@ -1478,6 +1478,7 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog)
			bpf_jit_binary_free(header);
			prog->bpf_func = NULL;
			prog->jited = 0;
			prog->jited_len = 0;
			goto out_off;
		}
		bpf_jit_binary_lock_ro(header);
+40 −19
Original line number Diff line number Diff line
@@ -51,6 +51,7 @@ static char *status_str[] = {
};

static char *type_str[] = {
	"", /* Type 0 is not defined */
	"AMT_MSG_DISCOVERY",
	"AMT_MSG_ADVERTISEMENT",
	"AMT_MSG_REQUEST",
@@ -2220,8 +2221,7 @@ static bool amt_advertisement_handler(struct amt_dev *amt, struct sk_buff *skb)
	struct amt_header_advertisement *amta;
	int hdr_size;

	hdr_size = sizeof(*amta) - sizeof(struct amt_header);

	hdr_size = sizeof(*amta) + sizeof(struct udphdr);
	if (!pskb_may_pull(skb, hdr_size))
		return true;

@@ -2251,19 +2251,27 @@ static bool amt_multicast_data_handler(struct amt_dev *amt, struct sk_buff *skb)
	struct ethhdr *eth;
	struct iphdr *iph;

	hdr_size = sizeof(*amtmd) + sizeof(struct udphdr);
	if (!pskb_may_pull(skb, hdr_size))
		return true;

	amtmd = (struct amt_header_mcast_data *)(udp_hdr(skb) + 1);
	if (amtmd->reserved || amtmd->version)
		return true;

	hdr_size = sizeof(*amtmd) + sizeof(struct udphdr);
	if (iptunnel_pull_header(skb, hdr_size, htons(ETH_P_IP), false))
		return true;

	skb_reset_network_header(skb);
	skb_push(skb, sizeof(*eth));
	skb_reset_mac_header(skb);
	skb_pull(skb, sizeof(*eth));
	eth = eth_hdr(skb);

	if (!pskb_may_pull(skb, sizeof(*iph)))
		return true;
	iph = ip_hdr(skb);

	if (iph->version == 4) {
		if (!ipv4_is_multicast(iph->daddr))
			return true;
@@ -2274,6 +2282,9 @@ static bool amt_multicast_data_handler(struct amt_dev *amt, struct sk_buff *skb)
	} else if (iph->version == 6) {
		struct ipv6hdr *ip6h;

		if (!pskb_may_pull(skb, sizeof(*ip6h)))
			return true;

		ip6h = ipv6_hdr(skb);
		if (!ipv6_addr_is_multicast(&ip6h->daddr))
			return true;
@@ -2306,8 +2317,7 @@ static bool amt_membership_query_handler(struct amt_dev *amt,
	struct iphdr *iph;
	int hdr_size, len;

	hdr_size = sizeof(*amtmq) - sizeof(struct amt_header);

	hdr_size = sizeof(*amtmq) + sizeof(struct udphdr);
	if (!pskb_may_pull(skb, hdr_size))
		return true;

@@ -2315,22 +2325,27 @@ static bool amt_membership_query_handler(struct amt_dev *amt,
	if (amtmq->reserved || amtmq->version)
		return true;

	hdr_size = sizeof(*amtmq) + sizeof(struct udphdr) - sizeof(*eth);
	hdr_size -= sizeof(*eth);
	if (iptunnel_pull_header(skb, hdr_size, htons(ETH_P_TEB), false))
		return true;

	oeth = eth_hdr(skb);
	skb_reset_mac_header(skb);
	skb_pull(skb, sizeof(*eth));
	skb_reset_network_header(skb);
	eth = eth_hdr(skb);
	if (!pskb_may_pull(skb, sizeof(*iph)))
		return true;

	iph = ip_hdr(skb);
	if (iph->version == 4) {
		if (!ipv4_is_multicast(iph->daddr))
			return true;
		if (!pskb_may_pull(skb, sizeof(*iph) + AMT_IPHDR_OPTS +
				   sizeof(*ihv3)))
			return true;

		if (!ipv4_is_multicast(iph->daddr))
			return true;

		ihv3 = skb_pull(skb, sizeof(*iph) + AMT_IPHDR_OPTS);
		skb_reset_transport_header(skb);
		skb_push(skb, sizeof(*iph) + AMT_IPHDR_OPTS);
@@ -2345,15 +2360,17 @@ static bool amt_membership_query_handler(struct amt_dev *amt,
		ip_eth_mc_map(iph->daddr, eth->h_dest);
#if IS_ENABLED(CONFIG_IPV6)
	} else if (iph->version == 6) {
		struct ipv6hdr *ip6h = ipv6_hdr(skb);
		struct mld2_query *mld2q;
		struct ipv6hdr *ip6h;

		if (!ipv6_addr_is_multicast(&ip6h->daddr))
			return true;
		if (!pskb_may_pull(skb, sizeof(*ip6h) + AMT_IP6HDR_OPTS +
				   sizeof(*mld2q)))
			return true;

		ip6h = ipv6_hdr(skb);
		if (!ipv6_addr_is_multicast(&ip6h->daddr))
			return true;

		mld2q = skb_pull(skb, sizeof(*ip6h) + AMT_IP6HDR_OPTS);
		skb_reset_transport_header(skb);
		skb_push(skb, sizeof(*ip6h) + AMT_IP6HDR_OPTS);
@@ -2389,23 +2406,23 @@ static bool amt_update_handler(struct amt_dev *amt, struct sk_buff *skb)
{
	struct amt_header_membership_update *amtmu;
	struct amt_tunnel_list *tunnel;
	struct udphdr *udph;
	struct ethhdr *eth;
	struct iphdr *iph;
	int len;
	int len, hdr_size;

	iph = ip_hdr(skb);
	udph = udp_hdr(skb);

	if (__iptunnel_pull_header(skb, sizeof(*udph), skb->protocol,
				   false, false))
	hdr_size = sizeof(*amtmu) + sizeof(struct udphdr);
	if (!pskb_may_pull(skb, hdr_size))
		return true;

	amtmu = (struct amt_header_membership_update *)skb->data;
	amtmu = (struct amt_header_membership_update *)(udp_hdr(skb) + 1);
	if (amtmu->reserved || amtmu->version)
		return true;

	skb_pull(skb, sizeof(*amtmu));
	if (iptunnel_pull_header(skb, hdr_size, skb->protocol, false))
		return true;

	skb_reset_network_header(skb);

	list_for_each_entry_rcu(tunnel, &amt->tunnel_list, list) {
@@ -2426,6 +2443,9 @@ static bool amt_update_handler(struct amt_dev *amt, struct sk_buff *skb)
	return true;

report:
	if (!pskb_may_pull(skb, sizeof(*iph)))
		return true;

	iph = ip_hdr(skb);
	if (iph->version == 4) {
		if (ip_mc_check_igmp(skb)) {
@@ -2679,7 +2699,8 @@ static int amt_rcv(struct sock *sk, struct sk_buff *skb)
	amt = rcu_dereference_sk_user_data(sk);
	if (!amt) {
		err = true;
		goto drop;
		kfree_skb(skb);
		goto out;
	}

	skb->dev = amt->dev;
+3 −1
Original line number Diff line number Diff line
@@ -2070,8 +2070,10 @@ static int gswip_gphy_fw_list(struct gswip_priv *priv,
	for_each_available_child_of_node(gphy_fw_list_np, gphy_fw_np) {
		err = gswip_gphy_fw_probe(priv, &priv->gphy_fw[i],
					  gphy_fw_np, i);
		if (err)
		if (err) {
			of_node_put(gphy_fw_np);
			goto remove_gphy;
		}
		i++;
	}

+19 −16
Original line number Diff line number Diff line
@@ -50,22 +50,25 @@ static int mv88e6390_serdes_write(struct mv88e6xxx_chip *chip,
}

static int mv88e6xxx_serdes_pcs_get_state(struct mv88e6xxx_chip *chip,
					  u16 ctrl, u16 status, u16 lpa,
					  u16 bmsr, u16 lpa, u16 status,
					  struct phylink_link_state *state)
{
	state->link = false;

	/* If the BMSR reports that the link had failed, report this to
	 * phylink.
	 */
	if (!(bmsr & BMSR_LSTATUS))
		return 0;

	state->link = !!(status & MV88E6390_SGMII_PHY_STATUS_LINK);
	state->an_complete = !!(bmsr & BMSR_ANEGCOMPLETE);

	if (status & MV88E6390_SGMII_PHY_STATUS_SPD_DPL_VALID) {
		/* The Spped and Duplex Resolved register is 1 if AN is enabled
		 * and complete, or if AN is disabled. So with disabled AN we
		 * still get here on link up. But we want to set an_complete
		 * only if AN was enabled, thus we look at BMCR_ANENABLE.
		 * (According to 802.3-2008 section 22.2.4.2.10, we should be
		 *  able to get this same value from BMSR_ANEGCAPABLE, but tests
		 *  show that these Marvell PHYs don't conform to this part of
		 *  the specificaion - BMSR_ANEGCAPABLE is simply always 1.)
		 * still get here on link up.
		 */
		state->an_complete = !!(ctrl & BMCR_ANENABLE);
		state->duplex = status &
				MV88E6390_SGMII_PHY_STATUS_DUPLEX_FULL ?
			                         DUPLEX_FULL : DUPLEX_HALF;
@@ -191,12 +194,12 @@ int mv88e6352_serdes_pcs_config(struct mv88e6xxx_chip *chip, int port,
int mv88e6352_serdes_pcs_get_state(struct mv88e6xxx_chip *chip, int port,
				   int lane, struct phylink_link_state *state)
{
	u16 lpa, status, ctrl;
	u16 bmsr, lpa, status;
	int err;

	err = mv88e6352_serdes_read(chip, MII_BMCR, &ctrl);
	err = mv88e6352_serdes_read(chip, MII_BMSR, &bmsr);
	if (err) {
		dev_err(chip->dev, "can't read Serdes PHY control: %d\n", err);
		dev_err(chip->dev, "can't read Serdes PHY BMSR: %d\n", err);
		return err;
	}

@@ -212,7 +215,7 @@ int mv88e6352_serdes_pcs_get_state(struct mv88e6xxx_chip *chip, int port,
		return err;
	}

	return mv88e6xxx_serdes_pcs_get_state(chip, ctrl, status, lpa, state);
	return mv88e6xxx_serdes_pcs_get_state(chip, bmsr, lpa, status, state);
}

int mv88e6352_serdes_pcs_an_restart(struct mv88e6xxx_chip *chip, int port,
@@ -918,13 +921,13 @@ int mv88e6390_serdes_pcs_config(struct mv88e6xxx_chip *chip, int port,
static int mv88e6390_serdes_pcs_get_state_sgmii(struct mv88e6xxx_chip *chip,
	int port, int lane, struct phylink_link_state *state)
{
	u16 lpa, status, ctrl;
	u16 bmsr, lpa, status;
	int err;

	err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
				    MV88E6390_SGMII_BMCR, &ctrl);
				    MV88E6390_SGMII_BMSR, &bmsr);
	if (err) {
		dev_err(chip->dev, "can't read Serdes PHY control: %d\n", err);
		dev_err(chip->dev, "can't read Serdes PHY BMSR: %d\n", err);
		return err;
	}

@@ -942,7 +945,7 @@ static int mv88e6390_serdes_pcs_get_state_sgmii(struct mv88e6xxx_chip *chip,
		return err;
	}

	return mv88e6xxx_serdes_pcs_get_state(chip, ctrl, status, lpa, state);
	return mv88e6xxx_serdes_pcs_get_state(chip, bmsr, lpa, status, state);
}

static int mv88e6390_serdes_pcs_get_state_10g(struct mv88e6xxx_chip *chip,
Loading