Skip to content

Commit 926af62

Browse files
committed
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
Pull networking fixes from David Miller: 1) Load correct firmware in rtl8192ce wireless driver, from Jurij Smakov. 2) Fix leak of tx_ring and tx_cq due to overwriting in mlx4 driver, from Martin KaFai Lau. 3) Need to reference count PHY driver module when it is attached, from Mao Wenan. 4) Don't do zero length vzalloc() in ethtool register dump, from Stanislaw Gruszka. 5) Defer net_disable_timestamp() to a workqueue to get out of locking issues, from Eric Dumazet. 6) We cannot drop the SKB dst when IP options refer to them, fix also from Eric Dumazet. 7) Incorrect packet header offset calculations in ip6_gre, again from Eric Dumazet. 8) Missing tcp_v6_restore_cb() causes use-after-free, from Eric too. 9) tcp_splice_read() can get into an infinite loop with URG, and hey it's from Eric once more. 10) vnet_hdr_sz can change asynchronously, so read it once during decision making in macvtap and tun, from Willem de Bruijn. 11) Can't use kernel stack for DMA transfers in USB networking drivers, from Ben Hutchings. 12) Handle csum errors properly in UDP by calling the proper destructor, from Eric Dumazet. 13) For non-deterministic softirq run when scheduling NAPI from a workqueue in mlx4, from Benjamin Poirier. * git://git.kernel.org/pub/scm/linux/kernel/git/davem/net: (28 commits) sctp: check af before verify address in sctp_addr_id2transport sctp: avoid BUG_ON on sctp_wait_for_sndbuf mlx4: Invoke softirqs after napi_reschedule udp: properly cope with csum errors catc: Use heap buffer for memory size test catc: Combine failure cleanup code in catc_probe() rtl8150: Use heap buffers for all register access pegasus: Use heap buffers for all register access macvtap: read vnet_hdr_size once tun: read vnet_hdr_sz once tcp: avoid infinite loop in tcp_splice_read() hns: avoid stack overflow with CONFIG_KASAN ipv6: Fix IPv6 packet loss in scenarios involving roaming + snooping switches ipv6: tcp: add a missing tcp_v6_restore_cb() nl80211: Fix mesh HT operation check mac80211: Fix adding of mesh vendor IEs mac80211: Allocate a sync skcipher explicitly for FILS AEAD mac80211: Fix FILS AEAD protection in Association Request frame ip6_gre: fix ip6gre_err() invalid reads netlabel: out of bound access in cipso_v4_validate() ...
2 parents b678912 + 912964e commit 926af62

File tree

32 files changed

+255
-164
lines changed

32 files changed

+255
-164
lines changed

drivers/net/ethernet/hisilicon/hns/hns_dsaf_reg.h

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1014,19 +1014,15 @@
10141014

10151015
static inline void dsaf_write_reg(void __iomem *base, u32 reg, u32 value)
10161016
{
1017-
u8 __iomem *reg_addr = ACCESS_ONCE(base);
1018-
1019-
writel(value, reg_addr + reg);
1017+
writel(value, base + reg);
10201018
}
10211019

10221020
#define dsaf_write_dev(a, reg, value) \
10231021
dsaf_write_reg((a)->io_base, (reg), (value))
10241022

10251023
static inline u32 dsaf_read_reg(u8 __iomem *base, u32 reg)
10261024
{
1027-
u8 __iomem *reg_addr = ACCESS_ONCE(base);
1028-
1029-
return readl(reg_addr + reg);
1025+
return readl(base + reg);
10301026
}
10311027

10321028
static inline void dsaf_write_syscon(struct regmap *base, u32 reg, u32 value)

drivers/net/ethernet/mellanox/mlx4/en_ethtool.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1099,7 +1099,7 @@ static int mlx4_en_set_ringparam(struct net_device *dev,
10991099
memcpy(&new_prof, priv->prof, sizeof(struct mlx4_en_port_profile));
11001100
new_prof.tx_ring_size = tx_size;
11011101
new_prof.rx_ring_size = rx_size;
1102-
err = mlx4_en_try_alloc_resources(priv, tmp, &new_prof);
1102+
err = mlx4_en_try_alloc_resources(priv, tmp, &new_prof, true);
11031103
if (err)
11041104
goto out;
11051105

@@ -1774,7 +1774,7 @@ static int mlx4_en_set_channels(struct net_device *dev,
17741774
new_prof.tx_ring_num[TX_XDP] = xdp_count;
17751775
new_prof.rx_ring_num = channel->rx_count;
17761776

1777-
err = mlx4_en_try_alloc_resources(priv, tmp, &new_prof);
1777+
err = mlx4_en_try_alloc_resources(priv, tmp, &new_prof, true);
17781778
if (err)
17791779
goto out;
17801780

drivers/net/ethernet/mellanox/mlx4/en_netdev.c

Lines changed: 25 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2042,6 +2042,8 @@ static void mlx4_en_free_resources(struct mlx4_en_priv *priv)
20422042
if (priv->tx_cq[t] && priv->tx_cq[t][i])
20432043
mlx4_en_destroy_cq(priv, &priv->tx_cq[t][i]);
20442044
}
2045+
kfree(priv->tx_ring[t]);
2046+
kfree(priv->tx_cq[t]);
20452047
}
20462048

20472049
for (i = 0; i < priv->rx_ring_num; i++) {
@@ -2184,9 +2186,11 @@ static void mlx4_en_update_priv(struct mlx4_en_priv *dst,
21842186

21852187
int mlx4_en_try_alloc_resources(struct mlx4_en_priv *priv,
21862188
struct mlx4_en_priv *tmp,
2187-
struct mlx4_en_port_profile *prof)
2189+
struct mlx4_en_port_profile *prof,
2190+
bool carry_xdp_prog)
21882191
{
2189-
int t;
2192+
struct bpf_prog *xdp_prog;
2193+
int i, t;
21902194

21912195
mlx4_en_copy_priv(tmp, priv, prof);
21922196

@@ -2200,6 +2204,23 @@ int mlx4_en_try_alloc_resources(struct mlx4_en_priv *priv,
22002204
}
22012205
return -ENOMEM;
22022206
}
2207+
2208+
/* All rx_rings has the same xdp_prog. Pick the first one. */
2209+
xdp_prog = rcu_dereference_protected(
2210+
priv->rx_ring[0]->xdp_prog,
2211+
lockdep_is_held(&priv->mdev->state_lock));
2212+
2213+
if (xdp_prog && carry_xdp_prog) {
2214+
xdp_prog = bpf_prog_add(xdp_prog, tmp->rx_ring_num);
2215+
if (IS_ERR(xdp_prog)) {
2216+
mlx4_en_free_resources(tmp);
2217+
return PTR_ERR(xdp_prog);
2218+
}
2219+
for (i = 0; i < tmp->rx_ring_num; i++)
2220+
rcu_assign_pointer(tmp->rx_ring[i]->xdp_prog,
2221+
xdp_prog);
2222+
}
2223+
22032224
return 0;
22042225
}
22052226

@@ -2214,7 +2235,6 @@ void mlx4_en_destroy_netdev(struct net_device *dev)
22142235
{
22152236
struct mlx4_en_priv *priv = netdev_priv(dev);
22162237
struct mlx4_en_dev *mdev = priv->mdev;
2217-
int t;
22182238

22192239
en_dbg(DRV, priv, "Destroying netdev on port:%d\n", priv->port);
22202240

@@ -2248,11 +2268,6 @@ void mlx4_en_destroy_netdev(struct net_device *dev)
22482268
mlx4_en_free_resources(priv);
22492269
mutex_unlock(&mdev->state_lock);
22502270

2251-
for (t = 0; t < MLX4_EN_NUM_TX_TYPES; t++) {
2252-
kfree(priv->tx_ring[t]);
2253-
kfree(priv->tx_cq[t]);
2254-
}
2255-
22562271
free_netdev(dev);
22572272
}
22582273

@@ -2755,7 +2770,7 @@ static int mlx4_xdp_set(struct net_device *dev, struct bpf_prog *prog)
27552770
en_warn(priv, "Reducing the number of TX rings, to not exceed the max total rings number.\n");
27562771
}
27572772

2758-
err = mlx4_en_try_alloc_resources(priv, tmp, &new_prof);
2773+
err = mlx4_en_try_alloc_resources(priv, tmp, &new_prof, false);
27592774
if (err) {
27602775
if (prog)
27612776
bpf_prog_sub(prog, priv->rx_ring_num - 1);
@@ -3499,7 +3514,7 @@ int mlx4_en_reset_config(struct net_device *dev,
34993514
memcpy(&new_prof, priv->prof, sizeof(struct mlx4_en_port_profile));
35003515
memcpy(&new_prof.hwtstamp_config, &ts_config, sizeof(ts_config));
35013516

3502-
err = mlx4_en_try_alloc_resources(priv, tmp, &new_prof);
3517+
err = mlx4_en_try_alloc_resources(priv, tmp, &new_prof, true);
35033518
if (err)
35043519
goto out;
35053520

drivers/net/ethernet/mellanox/mlx4/en_rx.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -514,8 +514,11 @@ void mlx4_en_recover_from_oom(struct mlx4_en_priv *priv)
514514
return;
515515

516516
for (ring = 0; ring < priv->rx_ring_num; ring++) {
517-
if (mlx4_en_is_ring_empty(priv->rx_ring[ring]))
517+
if (mlx4_en_is_ring_empty(priv->rx_ring[ring])) {
518+
local_bh_disable();
518519
napi_reschedule(&priv->rx_cq[ring]->napi);
520+
local_bh_enable();
521+
}
519522
}
520523
}
521524

drivers/net/ethernet/mellanox/mlx4/mlx4_en.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -679,7 +679,8 @@ void mlx4_en_set_stats_bitmap(struct mlx4_dev *dev,
679679

680680
int mlx4_en_try_alloc_resources(struct mlx4_en_priv *priv,
681681
struct mlx4_en_priv *tmp,
682-
struct mlx4_en_port_profile *prof);
682+
struct mlx4_en_port_profile *prof,
683+
bool carry_xdp_prog);
683684
void mlx4_en_safe_replace_resources(struct mlx4_en_priv *priv,
684685
struct mlx4_en_priv *tmp);
685686

drivers/net/macvtap.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -681,7 +681,7 @@ static ssize_t macvtap_get_user(struct macvtap_queue *q, struct msghdr *m,
681681
size_t linear;
682682

683683
if (q->flags & IFF_VNET_HDR) {
684-
vnet_hdr_len = q->vnet_hdr_sz;
684+
vnet_hdr_len = READ_ONCE(q->vnet_hdr_sz);
685685

686686
err = -EINVAL;
687687
if (len < vnet_hdr_len)
@@ -820,7 +820,7 @@ static ssize_t macvtap_put_user(struct macvtap_queue *q,
820820

821821
if (q->flags & IFF_VNET_HDR) {
822822
struct virtio_net_hdr vnet_hdr;
823-
vnet_hdr_len = q->vnet_hdr_sz;
823+
vnet_hdr_len = READ_ONCE(q->vnet_hdr_sz);
824824
if (iov_iter_count(iter) < vnet_hdr_len)
825825
return -EINVAL;
826826

drivers/net/phy/phy_device.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -920,6 +920,11 @@ int phy_attach_direct(struct net_device *dev, struct phy_device *phydev,
920920
return -EIO;
921921
}
922922

923+
if (!try_module_get(d->driver->owner)) {
924+
dev_err(&dev->dev, "failed to get the device driver module\n");
925+
return -EIO;
926+
}
927+
923928
get_device(d);
924929

925930
/* Assume that if there is no driver, that it doesn't
@@ -977,6 +982,7 @@ int phy_attach_direct(struct net_device *dev, struct phy_device *phydev,
977982
error:
978983
phy_detach(phydev);
979984
put_device(d);
985+
module_put(d->driver->owner);
980986
if (ndev_owner != bus->owner)
981987
module_put(bus->owner);
982988
return err;
@@ -1059,6 +1065,7 @@ void phy_detach(struct phy_device *phydev)
10591065
bus = phydev->mdio.bus;
10601066

10611067
put_device(&phydev->mdio.dev);
1068+
module_put(phydev->mdio.dev.driver->owner);
10621069
if (ndev_owner != bus->owner)
10631070
module_put(bus->owner);
10641071
}

drivers/net/tun.c

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1170,9 +1170,11 @@ static ssize_t tun_get_user(struct tun_struct *tun, struct tun_file *tfile,
11701170
}
11711171

11721172
if (tun->flags & IFF_VNET_HDR) {
1173-
if (len < tun->vnet_hdr_sz)
1173+
int vnet_hdr_sz = READ_ONCE(tun->vnet_hdr_sz);
1174+
1175+
if (len < vnet_hdr_sz)
11741176
return -EINVAL;
1175-
len -= tun->vnet_hdr_sz;
1177+
len -= vnet_hdr_sz;
11761178

11771179
if (!copy_from_iter_full(&gso, sizeof(gso), from))
11781180
return -EFAULT;
@@ -1183,7 +1185,7 @@ static ssize_t tun_get_user(struct tun_struct *tun, struct tun_file *tfile,
11831185

11841186
if (tun16_to_cpu(tun, gso.hdr_len) > len)
11851187
return -EINVAL;
1186-
iov_iter_advance(from, tun->vnet_hdr_sz - sizeof(gso));
1188+
iov_iter_advance(from, vnet_hdr_sz - sizeof(gso));
11871189
}
11881190

11891191
if ((tun->flags & TUN_TYPE_MASK) == IFF_TAP) {
@@ -1335,7 +1337,7 @@ static ssize_t tun_put_user(struct tun_struct *tun,
13351337
vlan_hlen = VLAN_HLEN;
13361338

13371339
if (tun->flags & IFF_VNET_HDR)
1338-
vnet_hdr_sz = tun->vnet_hdr_sz;
1340+
vnet_hdr_sz = READ_ONCE(tun->vnet_hdr_sz);
13391341

13401342
total = skb->len + vlan_hlen + vnet_hdr_sz;
13411343

drivers/net/usb/catc.c

Lines changed: 34 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -776,7 +776,7 @@ static int catc_probe(struct usb_interface *intf, const struct usb_device_id *id
776776
struct net_device *netdev;
777777
struct catc *catc;
778778
u8 broadcast[ETH_ALEN];
779-
int i, pktsz;
779+
int pktsz, ret;
780780

781781
if (usb_set_interface(usbdev,
782782
intf->altsetting->desc.bInterfaceNumber, 1)) {
@@ -811,12 +811,8 @@ static int catc_probe(struct usb_interface *intf, const struct usb_device_id *id
811811
if ((!catc->ctrl_urb) || (!catc->tx_urb) ||
812812
(!catc->rx_urb) || (!catc->irq_urb)) {
813813
dev_err(&intf->dev, "No free urbs available.\n");
814-
usb_free_urb(catc->ctrl_urb);
815-
usb_free_urb(catc->tx_urb);
816-
usb_free_urb(catc->rx_urb);
817-
usb_free_urb(catc->irq_urb);
818-
free_netdev(netdev);
819-
return -ENOMEM;
814+
ret = -ENOMEM;
815+
goto fail_free;
820816
}
821817

822818
/* The F5U011 has the same vendor/product as the netmate but a device version of 0x130 */
@@ -844,15 +840,24 @@ static int catc_probe(struct usb_interface *intf, const struct usb_device_id *id
844840
catc->irq_buf, 2, catc_irq_done, catc, 1);
845841

846842
if (!catc->is_f5u011) {
843+
u32 *buf;
844+
int i;
845+
847846
dev_dbg(dev, "Checking memory size\n");
848847

849-
i = 0x12345678;
850-
catc_write_mem(catc, 0x7a80, &i, 4);
851-
i = 0x87654321;
852-
catc_write_mem(catc, 0xfa80, &i, 4);
853-
catc_read_mem(catc, 0x7a80, &i, 4);
848+
buf = kmalloc(4, GFP_KERNEL);
849+
if (!buf) {
850+
ret = -ENOMEM;
851+
goto fail_free;
852+
}
853+
854+
*buf = 0x12345678;
855+
catc_write_mem(catc, 0x7a80, buf, 4);
856+
*buf = 0x87654321;
857+
catc_write_mem(catc, 0xfa80, buf, 4);
858+
catc_read_mem(catc, 0x7a80, buf, 4);
854859

855-
switch (i) {
860+
switch (*buf) {
856861
case 0x12345678:
857862
catc_set_reg(catc, TxBufCount, 8);
858863
catc_set_reg(catc, RxBufCount, 32);
@@ -867,6 +872,8 @@ static int catc_probe(struct usb_interface *intf, const struct usb_device_id *id
867872
dev_dbg(dev, "32k Memory\n");
868873
break;
869874
}
875+
876+
kfree(buf);
870877

871878
dev_dbg(dev, "Getting MAC from SEEROM.\n");
872879

@@ -913,16 +920,21 @@ static int catc_probe(struct usb_interface *intf, const struct usb_device_id *id
913920
usb_set_intfdata(intf, catc);
914921

915922
SET_NETDEV_DEV(netdev, &intf->dev);
916-
if (register_netdev(netdev) != 0) {
917-
usb_set_intfdata(intf, NULL);
918-
usb_free_urb(catc->ctrl_urb);
919-
usb_free_urb(catc->tx_urb);
920-
usb_free_urb(catc->rx_urb);
921-
usb_free_urb(catc->irq_urb);
922-
free_netdev(netdev);
923-
return -EIO;
924-
}
923+
ret = register_netdev(netdev);
924+
if (ret)
925+
goto fail_clear_intfdata;
926+
925927
return 0;
928+
929+
fail_clear_intfdata:
930+
usb_set_intfdata(intf, NULL);
931+
fail_free:
932+
usb_free_urb(catc->ctrl_urb);
933+
usb_free_urb(catc->tx_urb);
934+
usb_free_urb(catc->rx_urb);
935+
usb_free_urb(catc->irq_urb);
936+
free_netdev(netdev);
937+
return ret;
926938
}
927939

928940
static void catc_disconnect(struct usb_interface *intf)

drivers/net/usb/pegasus.c

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -126,40 +126,61 @@ static void async_ctrl_callback(struct urb *urb)
126126

127127
static int get_registers(pegasus_t *pegasus, __u16 indx, __u16 size, void *data)
128128
{
129+
u8 *buf;
129130
int ret;
130131

132+
buf = kmalloc(size, GFP_NOIO);
133+
if (!buf)
134+
return -ENOMEM;
135+
131136
ret = usb_control_msg(pegasus->usb, usb_rcvctrlpipe(pegasus->usb, 0),
132137
PEGASUS_REQ_GET_REGS, PEGASUS_REQT_READ, 0,
133-
indx, data, size, 1000);
138+
indx, buf, size, 1000);
134139
if (ret < 0)
135140
netif_dbg(pegasus, drv, pegasus->net,
136141
"%s returned %d\n", __func__, ret);
142+
else if (ret <= size)
143+
memcpy(data, buf, ret);
144+
kfree(buf);
137145
return ret;
138146
}
139147

140-
static int set_registers(pegasus_t *pegasus, __u16 indx, __u16 size, void *data)
148+
static int set_registers(pegasus_t *pegasus, __u16 indx, __u16 size,
149+
const void *data)
141150
{
151+
u8 *buf;
142152
int ret;
143153

154+
buf = kmemdup(data, size, GFP_NOIO);
155+
if (!buf)
156+
return -ENOMEM;
157+
144158
ret = usb_control_msg(pegasus->usb, usb_sndctrlpipe(pegasus->usb, 0),
145159
PEGASUS_REQ_SET_REGS, PEGASUS_REQT_WRITE, 0,
146-
indx, data, size, 100);
160+
indx, buf, size, 100);
147161
if (ret < 0)
148162
netif_dbg(pegasus, drv, pegasus->net,
149163
"%s returned %d\n", __func__, ret);
164+
kfree(buf);
150165
return ret;
151166
}
152167

153168
static int set_register(pegasus_t *pegasus, __u16 indx, __u8 data)
154169
{
170+
u8 *buf;
155171
int ret;
156172

173+
buf = kmemdup(&data, 1, GFP_NOIO);
174+
if (!buf)
175+
return -ENOMEM;
176+
157177
ret = usb_control_msg(pegasus->usb, usb_sndctrlpipe(pegasus->usb, 0),
158178
PEGASUS_REQ_SET_REG, PEGASUS_REQT_WRITE, data,
159-
indx, &data, 1, 1000);
179+
indx, buf, 1, 1000);
160180
if (ret < 0)
161181
netif_dbg(pegasus, drv, pegasus->net,
162182
"%s returned %d\n", __func__, ret);
183+
kfree(buf);
163184
return ret;
164185
}
165186

0 commit comments

Comments
 (0)