Skip to content

Commit

Permalink
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
Browse files Browse the repository at this point in the history
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
  ...
  • Loading branch information
Linus Torvalds committed Jul 22, 2014
2 parents 89faa06 + 850717e commit 15ba223
Show file tree
Hide file tree
Showing 25 changed files with 367 additions and 128 deletions.
20 changes: 16 additions & 4 deletions drivers/isdn/i4l/isdn_ppp.c
Original file line number Diff line number Diff line change
Expand Up @@ -638,9 +638,15 @@ isdn_ppp_ioctl(int min, struct file *file, unsigned int cmd, unsigned long arg)
fprog.len = len;
fprog.filter = code;

if (is->pass_filter)
if (is->pass_filter) {
sk_unattached_filter_destroy(is->pass_filter);
err = sk_unattached_filter_create(&is->pass_filter, &fprog);
is->pass_filter = NULL;
}
if (fprog.filter != NULL)
err = sk_unattached_filter_create(&is->pass_filter,
&fprog);
else
err = 0;
kfree(code);

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

if (is->active_filter)
if (is->active_filter) {
sk_unattached_filter_destroy(is->active_filter);
err = sk_unattached_filter_create(&is->active_filter, &fprog);
is->active_filter = NULL;
}
if (fprog.filter != NULL)
err = sk_unattached_filter_create(&is->active_filter,
&fprog);
else
err = 0;
kfree(code);

return err;
Expand Down
7 changes: 4 additions & 3 deletions drivers/net/ethernet/mellanox/mlx4/en_cq.c
Original file line number Diff line number Diff line change
Expand Up @@ -129,14 +129,15 @@ int mlx4_en_activate_cq(struct mlx4_en_priv *priv, struct mlx4_en_cq *cq,
name);
}

cq->irq_desc =
irq_to_desc(mlx4_eq_get_irq(mdev->dev,
cq->vector));
}
} else {
cq->vector = (cq->ring + 1 + priv->port) %
mdev->dev->caps.num_comp_vectors;
}

cq->irq_desc =
irq_to_desc(mlx4_eq_get_irq(mdev->dev,
cq->vector));
} else {
/* For TX we use the same irq per
ring we assigned for the RX */
Expand Down
2 changes: 2 additions & 0 deletions drivers/net/ethernet/realtek/r8169.c
Original file line number Diff line number Diff line change
Expand Up @@ -4240,6 +4240,8 @@ static void rtl_init_rxcfg(struct rtl8169_private *tp)
RTL_W32(RxConfig, RX128_INT_EN | RX_MULTI_EN | RX_DMA_BURST);
break;
case RTL_GIGA_MAC_VER_40:
RTL_W32(RxConfig, RX128_INT_EN | RX_MULTI_EN | RX_DMA_BURST | RX_EARLY_OFF);
break;
case RTL_GIGA_MAC_VER_41:
case RTL_GIGA_MAC_VER_42:
case RTL_GIGA_MAC_VER_43:
Expand Down
20 changes: 19 additions & 1 deletion drivers/net/ethernet/sun/sunvnet.c
Original file line number Diff line number Diff line change
Expand Up @@ -1083,6 +1083,24 @@ static struct vnet *vnet_find_or_create(const u64 *local_mac)
return vp;
}

static void vnet_cleanup(void)
{
struct vnet *vp;
struct net_device *dev;

mutex_lock(&vnet_list_mutex);
while (!list_empty(&vnet_list)) {
vp = list_first_entry(&vnet_list, struct vnet, list);
list_del(&vp->list);
dev = vp->dev;
/* vio_unregister_driver() should have cleaned up port_list */
BUG_ON(!list_empty(&vp->port_list));
unregister_netdev(dev);
free_netdev(dev);
}
mutex_unlock(&vnet_list_mutex);
}

static const char *local_mac_prop = "local-mac-address";

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

kfree(port);

unregister_netdev(vp->dev);
}
return 0;
}
Expand Down Expand Up @@ -1268,6 +1285,7 @@ static int __init vnet_init(void)
static void __exit vnet_exit(void)
{
vio_unregister_driver(&vnet_port_driver);
vnet_cleanup();
}

module_init(vnet_init);
Expand Down
22 changes: 16 additions & 6 deletions drivers/net/ppp/ppp_generic.c
Original file line number Diff line number Diff line change
Expand Up @@ -757,10 +757,15 @@ static long ppp_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
};

ppp_lock(ppp);
if (ppp->pass_filter)
if (ppp->pass_filter) {
sk_unattached_filter_destroy(ppp->pass_filter);
err = sk_unattached_filter_create(&ppp->pass_filter,
&fprog);
ppp->pass_filter = NULL;
}
if (fprog.filter != NULL)
err = sk_unattached_filter_create(&ppp->pass_filter,
&fprog);
else
err = 0;
kfree(code);
ppp_unlock(ppp);
}
Expand All @@ -778,10 +783,15 @@ static long ppp_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
};

ppp_lock(ppp);
if (ppp->active_filter)
if (ppp->active_filter) {
sk_unattached_filter_destroy(ppp->active_filter);
err = sk_unattached_filter_create(&ppp->active_filter,
&fprog);
ppp->active_filter = NULL;
}
if (fprog.filter != NULL)
err = sk_unattached_filter_create(&ppp->active_filter,
&fprog);
else
err = 0;
kfree(code);
ppp_unlock(ppp);
}
Expand Down
3 changes: 3 additions & 0 deletions drivers/net/usb/huawei_cdc_ncm.c
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,9 @@ static const struct usb_device_id huawei_cdc_ncm_devs[] = {
{ USB_VENDOR_AND_INTERFACE_INFO(0x12d1, 0xff, 0x02, 0x76),
.driver_info = (unsigned long)&huawei_cdc_ncm_info,
},
{ USB_VENDOR_AND_INTERFACE_INFO(0x12d1, 0xff, 0x03, 0x16),
.driver_info = (unsigned long)&huawei_cdc_ncm_info,
},

/* Terminating entry */
{
Expand Down
2 changes: 2 additions & 0 deletions drivers/net/usb/qmi_wwan.c
Original file line number Diff line number Diff line change
Expand Up @@ -667,6 +667,7 @@ static const struct usb_device_id products[] = {
{QMI_FIXED_INTF(0x05c6, 0x9084, 4)},
{QMI_FIXED_INTF(0x05c6, 0x920d, 0)},
{QMI_FIXED_INTF(0x05c6, 0x920d, 5)},
{QMI_FIXED_INTF(0x0846, 0x68a2, 8)},
{QMI_FIXED_INTF(0x12d1, 0x140c, 1)}, /* Huawei E173 */
{QMI_FIXED_INTF(0x12d1, 0x14ac, 1)}, /* Huawei E1820 */
{QMI_FIXED_INTF(0x16d8, 0x6003, 0)}, /* CMOTech 6003 */
Expand Down Expand Up @@ -757,6 +758,7 @@ static const struct usb_device_id products[] = {
{QMI_FIXED_INTF(0x1199, 0x9054, 8)}, /* Sierra Wireless Modem */
{QMI_FIXED_INTF(0x1199, 0x9055, 8)}, /* Netgear AirCard 341U */
{QMI_FIXED_INTF(0x1199, 0x9056, 8)}, /* Sierra Wireless Modem */
{QMI_FIXED_INTF(0x1199, 0x9057, 8)},
{QMI_FIXED_INTF(0x1199, 0x9061, 8)}, /* Sierra Wireless Modem */
{QMI_FIXED_INTF(0x1bbb, 0x011e, 4)}, /* Telekom Speedstick LTE II (Alcatel One Touch L100V LTE) */
{QMI_FIXED_INTF(0x1bbb, 0x0203, 2)}, /* Alcatel L800MA */
Expand Down
6 changes: 5 additions & 1 deletion drivers/net/wan/x25_asy.c
Original file line number Diff line number Diff line change
Expand Up @@ -122,8 +122,12 @@ static int x25_asy_change_mtu(struct net_device *dev, int newmtu)
{
struct x25_asy *sl = netdev_priv(dev);
unsigned char *xbuff, *rbuff;
int len = 2 * newmtu;
int len;

if (newmtu > 65534)
return -EINVAL;

len = 2 * newmtu;
xbuff = kmalloc(len + 4, GFP_ATOMIC);
rbuff = kmalloc(len + 4, GFP_ATOMIC);

Expand Down
86 changes: 63 additions & 23 deletions drivers/net/xen-netback/netback.c
Original file line number Diff line number Diff line change
Expand Up @@ -1030,23 +1030,34 @@ static int xenvif_tx_check_gop(struct xenvif_queue *queue,
{
struct gnttab_map_grant_ref *gop_map = *gopp_map;
u16 pending_idx = XENVIF_TX_CB(skb)->pending_idx;
/* This always points to the shinfo of the skb being checked, which
* could be either the first or the one on the frag_list
*/
struct skb_shared_info *shinfo = skb_shinfo(skb);
/* If this is non-NULL, we are currently checking the frag_list skb, and
* this points to the shinfo of the first one
*/
struct skb_shared_info *first_shinfo = NULL;
int nr_frags = shinfo->nr_frags;
const bool sharedslot = nr_frags &&
frag_get_pending_idx(&shinfo->frags[0]) == pending_idx;
int i, err;
struct sk_buff *first_skb = NULL;

/* Check status of header. */
err = (*gopp_copy)->status;
(*gopp_copy)++;
if (unlikely(err)) {
if (net_ratelimit())
netdev_dbg(queue->vif->dev,
"Grant copy of header failed! status: %d pending_idx: %u ref: %u\n",
(*gopp_copy)->status,
pending_idx,
(*gopp_copy)->source.u.ref);
xenvif_idx_release(queue, pending_idx, XEN_NETIF_RSP_ERROR);
/* The first frag might still have this slot mapped */
if (!sharedslot)
xenvif_idx_release(queue, pending_idx,
XEN_NETIF_RSP_ERROR);
}
(*gopp_copy)++;

check_frags:
for (i = 0; i < nr_frags; i++, gop_map++) {
Expand All @@ -1062,8 +1073,19 @@ static int xenvif_tx_check_gop(struct xenvif_queue *queue,
pending_idx,
gop_map->handle);
/* Had a previous error? Invalidate this fragment. */
if (unlikely(err))
if (unlikely(err)) {
xenvif_idx_unmap(queue, pending_idx);
/* If the mapping of the first frag was OK, but
* the header's copy failed, and they are
* sharing a slot, send an error
*/
if (i == 0 && sharedslot)
xenvif_idx_release(queue, pending_idx,
XEN_NETIF_RSP_ERROR);
else
xenvif_idx_release(queue, pending_idx,
XEN_NETIF_RSP_OKAY);
}
continue;
}

Expand All @@ -1075,42 +1097,53 @@ static int xenvif_tx_check_gop(struct xenvif_queue *queue,
gop_map->status,
pending_idx,
gop_map->ref);

xenvif_idx_release(queue, pending_idx, XEN_NETIF_RSP_ERROR);

/* Not the first error? Preceding frags already invalidated. */
if (err)
continue;
/* First error: invalidate preceding fragments. */

/* First error: if the header haven't shared a slot with the
* first frag, release it as well.
*/
if (!sharedslot)
xenvif_idx_release(queue,
XENVIF_TX_CB(skb)->pending_idx,
XEN_NETIF_RSP_OKAY);

/* Invalidate preceding fragments of this skb. */
for (j = 0; j < i; j++) {
pending_idx = frag_get_pending_idx(&shinfo->frags[j]);
xenvif_idx_unmap(queue, pending_idx);
xenvif_idx_release(queue, pending_idx,
XEN_NETIF_RSP_OKAY);
}

/* And if we found the error while checking the frag_list, unmap
* the first skb's frags
*/
if (first_shinfo) {
for (j = 0; j < first_shinfo->nr_frags; j++) {
pending_idx = frag_get_pending_idx(&first_shinfo->frags[j]);
xenvif_idx_unmap(queue, pending_idx);
xenvif_idx_release(queue, pending_idx,
XEN_NETIF_RSP_OKAY);
}
}

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

if (skb_has_frag_list(skb)) {
first_skb = skb;
skb = shinfo->frag_list;
shinfo = skb_shinfo(skb);
if (skb_has_frag_list(skb) && !first_shinfo) {
first_shinfo = skb_shinfo(skb);
shinfo = skb_shinfo(skb_shinfo(skb)->frag_list);
nr_frags = shinfo->nr_frags;

goto check_frags;
}

/* There was a mapping error in the frag_list skb. We have to unmap
* the first skb's frags
*/
if (first_skb && err) {
int j;
shinfo = skb_shinfo(first_skb);
for (j = 0; j < shinfo->nr_frags; j++) {
pending_idx = frag_get_pending_idx(&shinfo->frags[j]);
xenvif_idx_unmap(queue, pending_idx);
}
}

*gopp_map = gop_map;
return err;
}
Expand Down Expand Up @@ -1518,7 +1551,16 @@ static int xenvif_tx_submit(struct xenvif_queue *queue)

/* Check the remap error code. */
if (unlikely(xenvif_tx_check_gop(queue, skb, &gop_map, &gop_copy))) {
/* If there was an error, xenvif_tx_check_gop is
* expected to release all the frags which were mapped,
* so kfree_skb shouldn't do it again
*/
skb_shinfo(skb)->nr_frags = 0;
if (skb_has_frag_list(skb)) {
struct sk_buff *nskb =
skb_shinfo(skb)->frag_list;
skb_shinfo(nskb)->nr_frags = 0;
}
kfree_skb(skb);
continue;
}
Expand Down Expand Up @@ -1822,8 +1864,6 @@ void xenvif_idx_unmap(struct xenvif_queue *queue, u16 pending_idx)
tx_unmap_op.status);
BUG();
}

xenvif_idx_release(queue, pending_idx, XEN_NETIF_RSP_OKAY);
}

static inline int rx_work_todo(struct xenvif_queue *queue)
Expand Down
6 changes: 4 additions & 2 deletions include/net/netfilter/nf_tables.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include <linux/netfilter/nfnetlink.h>
#include <linux/netfilter/x_tables.h>
#include <linux/netfilter/nf_tables.h>
#include <linux/u64_stats_sync.h>
#include <net/netlink.h>

#define NFT_JUMP_STACK_SIZE 16
Expand Down Expand Up @@ -528,8 +529,9 @@ enum nft_chain_type {
};

struct nft_stats {
u64 bytes;
u64 pkts;
u64 bytes;
u64 pkts;
struct u64_stats_sync syncp;
};

#define NFT_HOOK_OPS_MAX 2
Expand Down
2 changes: 1 addition & 1 deletion include/net/netns/nftables.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ struct netns_nftables {
struct nft_af_info *inet;
struct nft_af_info *arp;
struct nft_af_info *bridge;
unsigned int base_seq;
u8 gencursor;
u8 genctr;
};

#endif
Loading

0 comments on commit 15ba223

Please sign in to comment.