Skip to content

Commit 15ba223

Browse files
committed
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
Pull networking fixes from David Miller: 1) Null termination fix in dns_resolver got the pointer dereferncing wrong, fix from Ben Hutchings. 2) ip_options_compile() has a benign but real buffer overflow when parsing options. From Eric Dumazet. 3) Table updates can crash in netfilter's nftables if none of the state flags indicate an actual change, from Pablo Neira Ayuso. 4) Fix race in nf_tables dumping, also from Pablo. 5) GRE-GRO support broke the forwarding path because the segmentation state was not fully initialized in these paths, from Jerry Chu. 6) sunvnet driver leaks objects and potentially crashes on module unload, from Sowmini Varadhan. 7) We can accidently generate the same handle for several u32 classifier filters, fix from Cong Wang. 8) Several edge case bug fixes in fragment handling in xen-netback, from Zoltan Kiss. * git://git.kernel.org/pub/scm/linux/kernel/git/davem/net: (21 commits) ipv4: fix buffer overflow in ip_options_compile() batman-adv: fix TT VLAN inconsistency on VLAN re-add batman-adv: drop QinQ claim frames in bridge loop avoidance dns_resolver: Null-terminate the right string xen-netback: Fix pointer incrementation to avoid incorrect logging xen-netback: Fix releasing header slot on error path xen-netback: Fix releasing frag_list skbs in error path xen-netback: Fix handling frag_list on grant op error path net_sched: avoid generating same handle for u32 filters net: huawei_cdc_ncm: add "subclass 3" devices net: qmi_wwan: add two Sierra Wireless/Netgear devices wan/x25_asy: integer overflow in x25_asy_change_mtu() net: ppp: fix creating PPP pass and active filters net/mlx4_en: cq->irq_desc wasn't set in legacy EQ's sunvnet: clean up objects created in vnet_new() on vnet_exit() r8169: Enable RX_MULTI_EN for RTL_GIGA_MAC_VER_40 net-gre-gro: Fix a bug that breaks the forwarding path netfilter: nf_tables: 64bit stats need some extra synchronization netfilter: nf_tables: set NLM_F_DUMP_INTR if netlink dumping is stale netfilter: nf_tables: safe RCU iteration on list when dumping ...
2 parents 89faa06 + 850717e commit 15ba223

File tree

25 files changed

+367
-128
lines changed

25 files changed

+367
-128
lines changed

drivers/isdn/i4l/isdn_ppp.c

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -638,9 +638,15 @@ isdn_ppp_ioctl(int min, struct file *file, unsigned int cmd, unsigned long arg)
638638
fprog.len = len;
639639
fprog.filter = code;
640640

641-
if (is->pass_filter)
641+
if (is->pass_filter) {
642642
sk_unattached_filter_destroy(is->pass_filter);
643-
err = sk_unattached_filter_create(&is->pass_filter, &fprog);
643+
is->pass_filter = NULL;
644+
}
645+
if (fprog.filter != NULL)
646+
err = sk_unattached_filter_create(&is->pass_filter,
647+
&fprog);
648+
else
649+
err = 0;
644650
kfree(code);
645651

646652
return err;
@@ -657,9 +663,15 @@ isdn_ppp_ioctl(int min, struct file *file, unsigned int cmd, unsigned long arg)
657663
fprog.len = len;
658664
fprog.filter = code;
659665

660-
if (is->active_filter)
666+
if (is->active_filter) {
661667
sk_unattached_filter_destroy(is->active_filter);
662-
err = sk_unattached_filter_create(&is->active_filter, &fprog);
668+
is->active_filter = NULL;
669+
}
670+
if (fprog.filter != NULL)
671+
err = sk_unattached_filter_create(&is->active_filter,
672+
&fprog);
673+
else
674+
err = 0;
663675
kfree(code);
664676

665677
return err;

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

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -129,14 +129,15 @@ int mlx4_en_activate_cq(struct mlx4_en_priv *priv, struct mlx4_en_cq *cq,
129129
name);
130130
}
131131

132-
cq->irq_desc =
133-
irq_to_desc(mlx4_eq_get_irq(mdev->dev,
134-
cq->vector));
135132
}
136133
} else {
137134
cq->vector = (cq->ring + 1 + priv->port) %
138135
mdev->dev->caps.num_comp_vectors;
139136
}
137+
138+
cq->irq_desc =
139+
irq_to_desc(mlx4_eq_get_irq(mdev->dev,
140+
cq->vector));
140141
} else {
141142
/* For TX we use the same irq per
142143
ring we assigned for the RX */

drivers/net/ethernet/realtek/r8169.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4240,6 +4240,8 @@ static void rtl_init_rxcfg(struct rtl8169_private *tp)
42404240
RTL_W32(RxConfig, RX128_INT_EN | RX_MULTI_EN | RX_DMA_BURST);
42414241
break;
42424242
case RTL_GIGA_MAC_VER_40:
4243+
RTL_W32(RxConfig, RX128_INT_EN | RX_MULTI_EN | RX_DMA_BURST | RX_EARLY_OFF);
4244+
break;
42434245
case RTL_GIGA_MAC_VER_41:
42444246
case RTL_GIGA_MAC_VER_42:
42454247
case RTL_GIGA_MAC_VER_43:

drivers/net/ethernet/sun/sunvnet.c

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1083,6 +1083,24 @@ static struct vnet *vnet_find_or_create(const u64 *local_mac)
10831083
return vp;
10841084
}
10851085

1086+
static void vnet_cleanup(void)
1087+
{
1088+
struct vnet *vp;
1089+
struct net_device *dev;
1090+
1091+
mutex_lock(&vnet_list_mutex);
1092+
while (!list_empty(&vnet_list)) {
1093+
vp = list_first_entry(&vnet_list, struct vnet, list);
1094+
list_del(&vp->list);
1095+
dev = vp->dev;
1096+
/* vio_unregister_driver() should have cleaned up port_list */
1097+
BUG_ON(!list_empty(&vp->port_list));
1098+
unregister_netdev(dev);
1099+
free_netdev(dev);
1100+
}
1101+
mutex_unlock(&vnet_list_mutex);
1102+
}
1103+
10861104
static const char *local_mac_prop = "local-mac-address";
10871105

10881106
static struct vnet *vnet_find_parent(struct mdesc_handle *hp,
@@ -1240,7 +1258,6 @@ static int vnet_port_remove(struct vio_dev *vdev)
12401258

12411259
kfree(port);
12421260

1243-
unregister_netdev(vp->dev);
12441261
}
12451262
return 0;
12461263
}
@@ -1268,6 +1285,7 @@ static int __init vnet_init(void)
12681285
static void __exit vnet_exit(void)
12691286
{
12701287
vio_unregister_driver(&vnet_port_driver);
1288+
vnet_cleanup();
12711289
}
12721290

12731291
module_init(vnet_init);

drivers/net/ppp/ppp_generic.c

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -757,10 +757,15 @@ static long ppp_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
757757
};
758758

759759
ppp_lock(ppp);
760-
if (ppp->pass_filter)
760+
if (ppp->pass_filter) {
761761
sk_unattached_filter_destroy(ppp->pass_filter);
762-
err = sk_unattached_filter_create(&ppp->pass_filter,
763-
&fprog);
762+
ppp->pass_filter = NULL;
763+
}
764+
if (fprog.filter != NULL)
765+
err = sk_unattached_filter_create(&ppp->pass_filter,
766+
&fprog);
767+
else
768+
err = 0;
764769
kfree(code);
765770
ppp_unlock(ppp);
766771
}
@@ -778,10 +783,15 @@ static long ppp_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
778783
};
779784

780785
ppp_lock(ppp);
781-
if (ppp->active_filter)
786+
if (ppp->active_filter) {
782787
sk_unattached_filter_destroy(ppp->active_filter);
783-
err = sk_unattached_filter_create(&ppp->active_filter,
784-
&fprog);
788+
ppp->active_filter = NULL;
789+
}
790+
if (fprog.filter != NULL)
791+
err = sk_unattached_filter_create(&ppp->active_filter,
792+
&fprog);
793+
else
794+
err = 0;
785795
kfree(code);
786796
ppp_unlock(ppp);
787797
}

drivers/net/usb/huawei_cdc_ncm.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,9 @@ static const struct usb_device_id huawei_cdc_ncm_devs[] = {
194194
{ USB_VENDOR_AND_INTERFACE_INFO(0x12d1, 0xff, 0x02, 0x76),
195195
.driver_info = (unsigned long)&huawei_cdc_ncm_info,
196196
},
197+
{ USB_VENDOR_AND_INTERFACE_INFO(0x12d1, 0xff, 0x03, 0x16),
198+
.driver_info = (unsigned long)&huawei_cdc_ncm_info,
199+
},
197200

198201
/* Terminating entry */
199202
{

drivers/net/usb/qmi_wwan.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -667,6 +667,7 @@ static const struct usb_device_id products[] = {
667667
{QMI_FIXED_INTF(0x05c6, 0x9084, 4)},
668668
{QMI_FIXED_INTF(0x05c6, 0x920d, 0)},
669669
{QMI_FIXED_INTF(0x05c6, 0x920d, 5)},
670+
{QMI_FIXED_INTF(0x0846, 0x68a2, 8)},
670671
{QMI_FIXED_INTF(0x12d1, 0x140c, 1)}, /* Huawei E173 */
671672
{QMI_FIXED_INTF(0x12d1, 0x14ac, 1)}, /* Huawei E1820 */
672673
{QMI_FIXED_INTF(0x16d8, 0x6003, 0)}, /* CMOTech 6003 */
@@ -757,6 +758,7 @@ static const struct usb_device_id products[] = {
757758
{QMI_FIXED_INTF(0x1199, 0x9054, 8)}, /* Sierra Wireless Modem */
758759
{QMI_FIXED_INTF(0x1199, 0x9055, 8)}, /* Netgear AirCard 341U */
759760
{QMI_FIXED_INTF(0x1199, 0x9056, 8)}, /* Sierra Wireless Modem */
761+
{QMI_FIXED_INTF(0x1199, 0x9057, 8)},
760762
{QMI_FIXED_INTF(0x1199, 0x9061, 8)}, /* Sierra Wireless Modem */
761763
{QMI_FIXED_INTF(0x1bbb, 0x011e, 4)}, /* Telekom Speedstick LTE II (Alcatel One Touch L100V LTE) */
762764
{QMI_FIXED_INTF(0x1bbb, 0x0203, 2)}, /* Alcatel L800MA */

drivers/net/wan/x25_asy.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,8 +122,12 @@ static int x25_asy_change_mtu(struct net_device *dev, int newmtu)
122122
{
123123
struct x25_asy *sl = netdev_priv(dev);
124124
unsigned char *xbuff, *rbuff;
125-
int len = 2 * newmtu;
125+
int len;
126126

127+
if (newmtu > 65534)
128+
return -EINVAL;
129+
130+
len = 2 * newmtu;
127131
xbuff = kmalloc(len + 4, GFP_ATOMIC);
128132
rbuff = kmalloc(len + 4, GFP_ATOMIC);
129133

drivers/net/xen-netback/netback.c

Lines changed: 63 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1030,23 +1030,34 @@ static int xenvif_tx_check_gop(struct xenvif_queue *queue,
10301030
{
10311031
struct gnttab_map_grant_ref *gop_map = *gopp_map;
10321032
u16 pending_idx = XENVIF_TX_CB(skb)->pending_idx;
1033+
/* This always points to the shinfo of the skb being checked, which
1034+
* could be either the first or the one on the frag_list
1035+
*/
10331036
struct skb_shared_info *shinfo = skb_shinfo(skb);
1037+
/* If this is non-NULL, we are currently checking the frag_list skb, and
1038+
* this points to the shinfo of the first one
1039+
*/
1040+
struct skb_shared_info *first_shinfo = NULL;
10341041
int nr_frags = shinfo->nr_frags;
1042+
const bool sharedslot = nr_frags &&
1043+
frag_get_pending_idx(&shinfo->frags[0]) == pending_idx;
10351044
int i, err;
1036-
struct sk_buff *first_skb = NULL;
10371045

10381046
/* Check status of header. */
10391047
err = (*gopp_copy)->status;
1040-
(*gopp_copy)++;
10411048
if (unlikely(err)) {
10421049
if (net_ratelimit())
10431050
netdev_dbg(queue->vif->dev,
10441051
"Grant copy of header failed! status: %d pending_idx: %u ref: %u\n",
10451052
(*gopp_copy)->status,
10461053
pending_idx,
10471054
(*gopp_copy)->source.u.ref);
1048-
xenvif_idx_release(queue, pending_idx, XEN_NETIF_RSP_ERROR);
1055+
/* The first frag might still have this slot mapped */
1056+
if (!sharedslot)
1057+
xenvif_idx_release(queue, pending_idx,
1058+
XEN_NETIF_RSP_ERROR);
10491059
}
1060+
(*gopp_copy)++;
10501061

10511062
check_frags:
10521063
for (i = 0; i < nr_frags; i++, gop_map++) {
@@ -1062,8 +1073,19 @@ static int xenvif_tx_check_gop(struct xenvif_queue *queue,
10621073
pending_idx,
10631074
gop_map->handle);
10641075
/* Had a previous error? Invalidate this fragment. */
1065-
if (unlikely(err))
1076+
if (unlikely(err)) {
10661077
xenvif_idx_unmap(queue, pending_idx);
1078+
/* If the mapping of the first frag was OK, but
1079+
* the header's copy failed, and they are
1080+
* sharing a slot, send an error
1081+
*/
1082+
if (i == 0 && sharedslot)
1083+
xenvif_idx_release(queue, pending_idx,
1084+
XEN_NETIF_RSP_ERROR);
1085+
else
1086+
xenvif_idx_release(queue, pending_idx,
1087+
XEN_NETIF_RSP_OKAY);
1088+
}
10671089
continue;
10681090
}
10691091

@@ -1075,42 +1097,53 @@ static int xenvif_tx_check_gop(struct xenvif_queue *queue,
10751097
gop_map->status,
10761098
pending_idx,
10771099
gop_map->ref);
1100+
10781101
xenvif_idx_release(queue, pending_idx, XEN_NETIF_RSP_ERROR);
10791102

10801103
/* Not the first error? Preceding frags already invalidated. */
10811104
if (err)
10821105
continue;
1083-
/* First error: invalidate preceding fragments. */
1106+
1107+
/* First error: if the header haven't shared a slot with the
1108+
* first frag, release it as well.
1109+
*/
1110+
if (!sharedslot)
1111+
xenvif_idx_release(queue,
1112+
XENVIF_TX_CB(skb)->pending_idx,
1113+
XEN_NETIF_RSP_OKAY);
1114+
1115+
/* Invalidate preceding fragments of this skb. */
10841116
for (j = 0; j < i; j++) {
10851117
pending_idx = frag_get_pending_idx(&shinfo->frags[j]);
10861118
xenvif_idx_unmap(queue, pending_idx);
1119+
xenvif_idx_release(queue, pending_idx,
1120+
XEN_NETIF_RSP_OKAY);
1121+
}
1122+
1123+
/* And if we found the error while checking the frag_list, unmap
1124+
* the first skb's frags
1125+
*/
1126+
if (first_shinfo) {
1127+
for (j = 0; j < first_shinfo->nr_frags; j++) {
1128+
pending_idx = frag_get_pending_idx(&first_shinfo->frags[j]);
1129+
xenvif_idx_unmap(queue, pending_idx);
1130+
xenvif_idx_release(queue, pending_idx,
1131+
XEN_NETIF_RSP_OKAY);
1132+
}
10871133
}
10881134

10891135
/* Remember the error: invalidate all subsequent fragments. */
10901136
err = newerr;
10911137
}
10921138

1093-
if (skb_has_frag_list(skb)) {
1094-
first_skb = skb;
1095-
skb = shinfo->frag_list;
1096-
shinfo = skb_shinfo(skb);
1139+
if (skb_has_frag_list(skb) && !first_shinfo) {
1140+
first_shinfo = skb_shinfo(skb);
1141+
shinfo = skb_shinfo(skb_shinfo(skb)->frag_list);
10971142
nr_frags = shinfo->nr_frags;
10981143

10991144
goto check_frags;
11001145
}
11011146

1102-
/* There was a mapping error in the frag_list skb. We have to unmap
1103-
* the first skb's frags
1104-
*/
1105-
if (first_skb && err) {
1106-
int j;
1107-
shinfo = skb_shinfo(first_skb);
1108-
for (j = 0; j < shinfo->nr_frags; j++) {
1109-
pending_idx = frag_get_pending_idx(&shinfo->frags[j]);
1110-
xenvif_idx_unmap(queue, pending_idx);
1111-
}
1112-
}
1113-
11141147
*gopp_map = gop_map;
11151148
return err;
11161149
}
@@ -1518,7 +1551,16 @@ static int xenvif_tx_submit(struct xenvif_queue *queue)
15181551

15191552
/* Check the remap error code. */
15201553
if (unlikely(xenvif_tx_check_gop(queue, skb, &gop_map, &gop_copy))) {
1554+
/* If there was an error, xenvif_tx_check_gop is
1555+
* expected to release all the frags which were mapped,
1556+
* so kfree_skb shouldn't do it again
1557+
*/
15211558
skb_shinfo(skb)->nr_frags = 0;
1559+
if (skb_has_frag_list(skb)) {
1560+
struct sk_buff *nskb =
1561+
skb_shinfo(skb)->frag_list;
1562+
skb_shinfo(nskb)->nr_frags = 0;
1563+
}
15221564
kfree_skb(skb);
15231565
continue;
15241566
}
@@ -1822,8 +1864,6 @@ void xenvif_idx_unmap(struct xenvif_queue *queue, u16 pending_idx)
18221864
tx_unmap_op.status);
18231865
BUG();
18241866
}
1825-
1826-
xenvif_idx_release(queue, pending_idx, XEN_NETIF_RSP_OKAY);
18271867
}
18281868

18291869
static inline int rx_work_todo(struct xenvif_queue *queue)

include/net/netfilter/nf_tables.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#include <linux/netfilter/nfnetlink.h>
77
#include <linux/netfilter/x_tables.h>
88
#include <linux/netfilter/nf_tables.h>
9+
#include <linux/u64_stats_sync.h>
910
#include <net/netlink.h>
1011

1112
#define NFT_JUMP_STACK_SIZE 16
@@ -528,8 +529,9 @@ enum nft_chain_type {
528529
};
529530

530531
struct nft_stats {
531-
u64 bytes;
532-
u64 pkts;
532+
u64 bytes;
533+
u64 pkts;
534+
struct u64_stats_sync syncp;
533535
};
534536

535537
#define NFT_HOOK_OPS_MAX 2

include/net/netns/nftables.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@ struct netns_nftables {
1313
struct nft_af_info *inet;
1414
struct nft_af_info *arp;
1515
struct nft_af_info *bridge;
16+
unsigned int base_seq;
1617
u8 gencursor;
17-
u8 genctr;
1818
};
1919

2020
#endif

0 commit comments

Comments
 (0)