Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 057a650b authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull networking fixes from David Miller:

 1) Don't race in IPSEC dumps, from Yuejie Shi.

 2) Verify lengths properly in IPSEC reqeusts, from Herbert Xu.

 3) Fix out of bounds access in ipv6 segment routing code, from David
    Lebrun.

 4) Don't write into the header of cloned SKBs in smsc95xx driver, from
    James Hughes.

 5) Several other drivers have this bug too, fix them. From Eric
    Dumazet.

 6) Fix access to uninitialized data in TC action cookie code, from
    Wolfgang Bumiller.

 7) Fix double free in IPV6 segment routing, again from David Lebrun.

 8) Don't let userspace set the RTF_PCPU flag, oops. From David Ahern.

 9) Fix use after free in qrtr code, from Dan Carpenter.

10) Don't double-destroy devices in ip6mr code, from Nikolay
    Aleksandrov.

11) Don't pass out-of-range TX queue indices into drivers, from Tushar
    Dave.

* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net: (30 commits)
  netpoll: Check for skb->queue_mapping
  ip6mr: fix notification device destruction
  bpf, doc: update bpf maintainers entry
  net: qrtr: potential use after free in qrtr_sendmsg()
  bpf: Fix values type used in test_maps
  net: ipv6: RTF_PCPU should not be settable from userspace
  gso: Validate assumption of frag_list segementation
  kaweth: use skb_cow_head() to deal with cloned skbs
  ch9200: use skb_cow_head() to deal with cloned skbs
  lan78xx: use skb_cow_head() to deal with cloned skbs
  sr9700: use skb_cow_head() to deal with cloned skbs
  cx82310_eth: use skb_cow_head() to deal with cloned skbs
  smsc75xx: use skb_cow_head() to deal with cloned skbs
  ipv6: sr: fix double free of skb after handling invalid SRH
  MAINTAINERS: Add "B:" field for networking.
  net sched actions: allocate act cookie early
  qed: Fix issue in populating the PFC config paramters.
  qed: Fix possible system hang in the dcbnl-getdcbx() path.
  qed: Fix sending an invalid PFC error mask to MFW.
  qed: Fix possible error in populating max_tc field.
  ...
parents 92b4fc75 c70b17b7
Loading
Loading
Loading
Loading
+16 −2
Original line number Diff line number Diff line
@@ -2585,12 +2585,26 @@ F: include/uapi/linux/if_bonding.h

BPF (Safe dynamic programs and tools)
M:	Alexei Starovoitov <ast@kernel.org>
M:	Daniel Borkmann <daniel@iogearbox.net>
L:	netdev@vger.kernel.org
L:	linux-kernel@vger.kernel.org
S:	Supported
F:	arch/x86/net/bpf_jit*
F:	Documentation/networking/filter.txt
F:	include/linux/bpf*
F:	include/linux/filter.h
F:	include/uapi/linux/bpf*
F:	include/uapi/linux/filter.h
F:	kernel/bpf/
F:	tools/testing/selftests/bpf/
F:	kernel/trace/bpf_trace.c
F:	lib/test_bpf.c
F:	net/bpf/
F:	net/core/filter.c
F:	net/sched/act_bpf.c
F:	net/sched/cls_bpf.c
F:	samples/bpf/
F:	tools/net/bpf*
F:	tools/testing/selftests/bpf/

BROADCOM B44 10/100 ETHERNET DRIVER
M:	Michael Chan <michael.chan@broadcom.com>
@@ -8761,6 +8775,7 @@ W: http://www.linuxfoundation.org/en/Net
Q:	http://patchwork.ozlabs.org/project/netdev/list/
T:	git git://git.kernel.org/pub/scm/linux/kernel/git/davem/net.git
T:	git git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next.git
B:	mailto:netdev@vger.kernel.org
S:	Maintained
F:	net/
F:	include/net/
@@ -12464,7 +12479,6 @@ F: drivers/clk/ti/
F:	include/linux/clk/ti.h

TI ETHERNET SWITCH DRIVER (CPSW)
M:	Mugunthan V N <mugunthanvnm@ti.com>
R:	Grygorii Strashko <grygorii.strashko@ti.com>
L:	linux-omap@vger.kernel.org
L:	netdev@vger.kernel.org
+12 −1
Original line number Diff line number Diff line
@@ -583,6 +583,13 @@ qed_dcbx_get_ets_data(struct qed_hwfn *p_hwfn,
		   p_params->ets_cbs,
		   p_ets->pri_tc_tbl[0], p_params->max_ets_tc);

	if (p_params->ets_enabled && !p_params->max_ets_tc) {
		p_params->max_ets_tc = QED_MAX_PFC_PRIORITIES;
		DP_VERBOSE(p_hwfn, QED_MSG_DCB,
			   "ETS params: max_ets_tc is forced to %d\n",
		p_params->max_ets_tc);
	}

	/* 8 bit tsa and bw data corresponding to each of the 8 TC's are
	 * encoded in a type u32 array of size 2.
	 */
@@ -1001,6 +1008,8 @@ qed_dcbx_set_pfc_data(struct qed_hwfn *p_hwfn,
	u8 pfc_map = 0;
	int i;

	*pfc &= ~DCBX_PFC_ERROR_MASK;

	if (p_params->pfc.willing)
		*pfc |= DCBX_PFC_WILLING_MASK;
	else
@@ -1255,7 +1264,7 @@ static struct qed_dcbx_get *qed_dcbnl_get_dcbx(struct qed_hwfn *hwfn,
{
	struct qed_dcbx_get *dcbx_info;

	dcbx_info = kzalloc(sizeof(*dcbx_info), GFP_KERNEL);
	dcbx_info = kmalloc(sizeof(*dcbx_info), GFP_ATOMIC);
	if (!dcbx_info)
		return NULL;

@@ -2073,6 +2082,8 @@ static int qed_dcbnl_ieee_setpfc(struct qed_dev *cdev, struct ieee_pfc *pfc)
	for (i = 0; i < QED_MAX_PFC_PRIORITIES; i++)
		dcbx_set.config.params.pfc.prio[i] = !!(pfc->pfc_en & BIT(i));

	dcbx_set.config.params.pfc.max_tc = pfc->pfc_cap;

	ptt = qed_ptt_acquire(hwfn);
	if (!ptt)
		return -EINVAL;
+67 −55
Original line number Diff line number Diff line
@@ -1127,41 +1127,90 @@ static struct mdiobb_ops bb_ops = {
	.get_mdio_data = sh_get_mdio,
};

/* free skb and descriptor buffer */
static void sh_eth_ring_free(struct net_device *ndev)
/* free Tx skb function */
static int sh_eth_tx_free(struct net_device *ndev, bool sent_only)
{
	struct sh_eth_private *mdp = netdev_priv(ndev);
	int ringsize, i;
	struct sh_eth_txdesc *txdesc;
	int free_num = 0;
	int entry;
	bool sent;

	/* Free Rx skb ringbuffer */
	if (mdp->rx_skbuff) {
		for (i = 0; i < mdp->num_rx_ring; i++)
			dev_kfree_skb(mdp->rx_skbuff[i]);
	for (; mdp->cur_tx - mdp->dirty_tx > 0; mdp->dirty_tx++) {
		entry = mdp->dirty_tx % mdp->num_tx_ring;
		txdesc = &mdp->tx_ring[entry];
		sent = !(txdesc->status & cpu_to_le32(TD_TACT));
		if (sent_only && !sent)
			break;
		/* TACT bit must be checked before all the following reads */
		dma_rmb();
		netif_info(mdp, tx_done, ndev,
			   "tx entry %d status 0x%08x\n",
			   entry, le32_to_cpu(txdesc->status));
		/* Free the original skb. */
		if (mdp->tx_skbuff[entry]) {
			dma_unmap_single(&ndev->dev, le32_to_cpu(txdesc->addr),
					 le32_to_cpu(txdesc->len) >> 16,
					 DMA_TO_DEVICE);
			dev_kfree_skb_irq(mdp->tx_skbuff[entry]);
			mdp->tx_skbuff[entry] = NULL;
			free_num++;
		}
	kfree(mdp->rx_skbuff);
	mdp->rx_skbuff = NULL;
		txdesc->status = cpu_to_le32(TD_TFP);
		if (entry >= mdp->num_tx_ring - 1)
			txdesc->status |= cpu_to_le32(TD_TDLE);

	/* Free Tx skb ringbuffer */
	if (mdp->tx_skbuff) {
		for (i = 0; i < mdp->num_tx_ring; i++)
			dev_kfree_skb(mdp->tx_skbuff[i]);
		if (sent) {
			ndev->stats.tx_packets++;
			ndev->stats.tx_bytes += le32_to_cpu(txdesc->len) >> 16;
		}
	}
	return free_num;
}
	kfree(mdp->tx_skbuff);
	mdp->tx_skbuff = NULL;

/* free skb and descriptor buffer */
static void sh_eth_ring_free(struct net_device *ndev)
{
	struct sh_eth_private *mdp = netdev_priv(ndev);
	int ringsize, i;

	if (mdp->rx_ring) {
		for (i = 0; i < mdp->num_rx_ring; i++) {
			if (mdp->rx_skbuff[i]) {
				struct sh_eth_rxdesc *rxdesc = &mdp->rx_ring[i];

				dma_unmap_single(&ndev->dev,
						 le32_to_cpu(rxdesc->addr),
						 ALIGN(mdp->rx_buf_sz, 32),
						 DMA_FROM_DEVICE);
			}
		}
		ringsize = sizeof(struct sh_eth_rxdesc) * mdp->num_rx_ring;
		dma_free_coherent(NULL, ringsize, mdp->rx_ring,
				  mdp->rx_desc_dma);
		mdp->rx_ring = NULL;
	}

	/* Free Rx skb ringbuffer */
	if (mdp->rx_skbuff) {
		for (i = 0; i < mdp->num_rx_ring; i++)
			dev_kfree_skb(mdp->rx_skbuff[i]);
	}
	kfree(mdp->rx_skbuff);
	mdp->rx_skbuff = NULL;

	if (mdp->tx_ring) {
		sh_eth_tx_free(ndev, false);

		ringsize = sizeof(struct sh_eth_txdesc) * mdp->num_tx_ring;
		dma_free_coherent(NULL, ringsize, mdp->tx_ring,
				  mdp->tx_desc_dma);
		mdp->tx_ring = NULL;
	}

	/* Free Tx skb ringbuffer */
	kfree(mdp->tx_skbuff);
	mdp->tx_skbuff = NULL;
}

/* format skb and descriptor buffer */
@@ -1409,43 +1458,6 @@ static void sh_eth_dev_exit(struct net_device *ndev)
	update_mac_address(ndev);
}

/* free Tx skb function */
static int sh_eth_txfree(struct net_device *ndev)
{
	struct sh_eth_private *mdp = netdev_priv(ndev);
	struct sh_eth_txdesc *txdesc;
	int free_num = 0;
	int entry;

	for (; mdp->cur_tx - mdp->dirty_tx > 0; mdp->dirty_tx++) {
		entry = mdp->dirty_tx % mdp->num_tx_ring;
		txdesc = &mdp->tx_ring[entry];
		if (txdesc->status & cpu_to_le32(TD_TACT))
			break;
		/* TACT bit must be checked before all the following reads */
		dma_rmb();
		netif_info(mdp, tx_done, ndev,
			   "tx entry %d status 0x%08x\n",
			   entry, le32_to_cpu(txdesc->status));
		/* Free the original skb. */
		if (mdp->tx_skbuff[entry]) {
			dma_unmap_single(&ndev->dev, le32_to_cpu(txdesc->addr),
					 le32_to_cpu(txdesc->len) >> 16,
					 DMA_TO_DEVICE);
			dev_kfree_skb_irq(mdp->tx_skbuff[entry]);
			mdp->tx_skbuff[entry] = NULL;
			free_num++;
		}
		txdesc->status = cpu_to_le32(TD_TFP);
		if (entry >= mdp->num_tx_ring - 1)
			txdesc->status |= cpu_to_le32(TD_TDLE);

		ndev->stats.tx_packets++;
		ndev->stats.tx_bytes += le32_to_cpu(txdesc->len) >> 16;
	}
	return free_num;
}

/* Packet receive function */
static int sh_eth_rx(struct net_device *ndev, u32 intr_status, int *quota)
{
@@ -1690,7 +1702,7 @@ static void sh_eth_error(struct net_device *ndev, u32 intr_status)
			   intr_status, mdp->cur_tx, mdp->dirty_tx,
			   (u32)ndev->state, edtrr);
		/* dirty buffer free */
		sh_eth_txfree(ndev);
		sh_eth_tx_free(ndev, true);

		/* SH7712 BUG */
		if (edtrr ^ sh_eth_get_edtrr_trns(mdp)) {
@@ -1751,7 +1763,7 @@ static irqreturn_t sh_eth_interrupt(int irq, void *netdev)
		/* Clear Tx interrupts */
		sh_eth_write(ndev, intr_status & cd->tx_check, EESR);

		sh_eth_txfree(ndev);
		sh_eth_tx_free(ndev, true);
		netif_wake_queue(ndev);
	}

@@ -2412,7 +2424,7 @@ static int sh_eth_start_xmit(struct sk_buff *skb, struct net_device *ndev)

	spin_lock_irqsave(&mdp->lock, flags);
	if ((mdp->cur_tx - mdp->dirty_tx) >= (mdp->num_tx_ring - 4)) {
		if (!sh_eth_txfree(ndev)) {
		if (!sh_eth_tx_free(ndev, true)) {
			netif_warn(mdp, tx_queued, ndev, "TxFD exhausted.\n");
			netif_stop_queue(ndev);
			spin_unlock_irqrestore(&mdp->lock, flags);
+0 −2
Original line number Diff line number Diff line
@@ -1438,8 +1438,6 @@ static bool dp83640_rxtstamp(struct phy_device *phydev,
		skb_info->tmo = jiffies + SKB_TIMESTAMP_TIMEOUT;
		skb_queue_tail(&dp83640->rx_queue, skb);
		schedule_delayed_work(&dp83640->ts_work, SKB_TIMESTAMP_TIMEOUT);
	} else {
		netif_rx_ni(skb);
	}

	return true;
+2 −7
Original line number Diff line number Diff line
@@ -254,13 +254,8 @@ static struct sk_buff *ch9200_tx_fixup(struct usbnet *dev, struct sk_buff *skb,
	tx_overhead = 0x40;

	len = skb->len;
	if (skb_headroom(skb) < tx_overhead) {
		struct sk_buff *skb2;

		skb2 = skb_copy_expand(skb, tx_overhead, 0, flags);
	if (skb_cow_head(skb, tx_overhead)) {
		dev_kfree_skb_any(skb);
		skb = skb2;
		if (!skb)
		return NULL;
	}

Loading