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) Fix use-after-free in IPSEC input parsing, desintation address
    pointer was loaded before pskb_may_pull() which can change the SKB
    data pointers. From Florian Westphal.

 2) Stack out-of-bounds read in xfrm_state_find(), from Steffen
    Klassert.

 3) IPVS state of SKB is not properly reset when moving between
    namespaces, from Ye Yin.

 4) Fix crash in asix driver suspend and resume, from Andrey Konovalov.

 5) Don't deliver ipv6 l2tp tunnel packets to ipv4 l2tp tunnels, and
    vice versa, from Guillaume Nault.

 6) Fix DSACK undo on non-dup ACKs, from Priyaranjan Jha.

 7) Fix regression in bond_xmit_hash()'s behavior after the TCP port
    selection changes back in 4.2, from Hangbin Liu.

 8) Two divide by zero bugs in USB networking drivers when parsing
    descriptors, from Bjorn Mork.

 9) Fix bonding slaves being stuck in BOND_LINK_FAIL state, from Jay
    Vosburgh.

10) Missing skb_reset_mac_header() in qmi_wwan, from Kristian Evensen.

11) Fix the destruction of tc action object races properly, from Cong
    Wang.

* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net: (31 commits)
  cls_u32: use tcf_exts_get_net() before call_rcu()
  cls_tcindex: use tcf_exts_get_net() before call_rcu()
  cls_rsvp: use tcf_exts_get_net() before call_rcu()
  cls_route: use tcf_exts_get_net() before call_rcu()
  cls_matchall: use tcf_exts_get_net() before call_rcu()
  cls_fw: use tcf_exts_get_net() before call_rcu()
  cls_flower: use tcf_exts_get_net() before call_rcu()
  cls_flow: use tcf_exts_get_net() before call_rcu()
  cls_cgroup: use tcf_exts_get_net() before call_rcu()
  cls_bpf: use tcf_exts_get_net() before call_rcu()
  cls_basic: use tcf_exts_get_net() before call_rcu()
  net_sched: introduce tcf_exts_get_net() and tcf_exts_put_net()
  Revert "net_sched: hold netns refcnt for each action"
  net: usb: asix: fill null-ptr-deref in asix_suspend
  Revert "net: usb: asix: fill null-ptr-deref in asix_suspend"
  qmi_wwan: Add missing skb_reset_mac_header-call
  bonding: fix slave stuck in BOND_LINK_FAIL state
  qrtr: Move to postcore_initcall
  net: qmi_wwan: fix divide by 0 on bad descriptors
  net: cdc_ether: fix divide by 0 on bad descriptors
  ...
  • Loading branch information
torvalds committed Nov 9, 2017
2 parents 87df261 + 6a17280 commit d1041cd
Show file tree
Hide file tree
Showing 46 changed files with 285 additions and 146 deletions.
3 changes: 2 additions & 1 deletion drivers/net/bonding/bond_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -2042,6 +2042,7 @@ static int bond_miimon_inspect(struct bonding *bond)

bond_for_each_slave_rcu(bond, slave, iter) {
slave->new_link = BOND_LINK_NOCHANGE;
slave->link_new_state = slave->link;

link_state = bond_check_dev_link(bond, slave->dev, 0);

Expand Down Expand Up @@ -3253,7 +3254,7 @@ u32 bond_xmit_hash(struct bonding *bond, struct sk_buff *skb)
hash ^= (hash >> 16);
hash ^= (hash >> 8);

return hash;
return hash >> 1;
}

/*-------------------------- Device entry points ----------------------------*/
Expand Down
6 changes: 3 additions & 3 deletions drivers/net/ethernet/chelsio/cxgb4/t4fw_version.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@

#define T4FW_VERSION_MAJOR 0x01
#define T4FW_VERSION_MINOR 0x10
#define T4FW_VERSION_MICRO 0x2D
#define T4FW_VERSION_MICRO 0x3F
#define T4FW_VERSION_BUILD 0x00

#define T4FW_MIN_VERSION_MAJOR 0x01
Expand All @@ -46,7 +46,7 @@

#define T5FW_VERSION_MAJOR 0x01
#define T5FW_VERSION_MINOR 0x10
#define T5FW_VERSION_MICRO 0x2D
#define T5FW_VERSION_MICRO 0x3F
#define T5FW_VERSION_BUILD 0x00

#define T5FW_MIN_VERSION_MAJOR 0x00
Expand All @@ -55,7 +55,7 @@

#define T6FW_VERSION_MAJOR 0x01
#define T6FW_VERSION_MINOR 0x10
#define T6FW_VERSION_MICRO 0x2D
#define T6FW_VERSION_MICRO 0x3F
#define T6FW_VERSION_BUILD 0x00

#define T6FW_MIN_VERSION_MAJOR 0x00
Expand Down
4 changes: 4 additions & 0 deletions drivers/net/ethernet/marvell/mvpp2.c
Original file line number Diff line number Diff line change
Expand Up @@ -6747,6 +6747,9 @@ static int mvpp2_irqs_init(struct mvpp2_port *port)
for (i = 0; i < port->nqvecs; i++) {
struct mvpp2_queue_vector *qv = port->qvecs + i;

if (qv->type == MVPP2_QUEUE_VECTOR_PRIVATE)
irq_set_status_flags(qv->irq, IRQ_NO_BALANCING);

err = request_irq(qv->irq, mvpp2_isr, 0, port->dev->name, qv);
if (err)
goto err;
Expand Down Expand Up @@ -6776,6 +6779,7 @@ static void mvpp2_irqs_deinit(struct mvpp2_port *port)
struct mvpp2_queue_vector *qv = port->qvecs + i;

irq_set_affinity_hint(qv->irq, NULL);
irq_clear_status_flags(qv->irq, IRQ_NO_BALANCING);
free_irq(qv->irq, qv);
}
}
Expand Down
13 changes: 8 additions & 5 deletions drivers/net/ethernet/mellanox/mlx5/core/en_fs.c
Original file line number Diff line number Diff line change
Expand Up @@ -365,29 +365,32 @@ static void mlx5e_execute_l2_action(struct mlx5e_priv *priv,
struct mlx5e_l2_hash_node *hn)
{
u8 action = hn->action;
u8 mac_addr[ETH_ALEN];
int l2_err = 0;

ether_addr_copy(mac_addr, hn->ai.addr);

switch (action) {
case MLX5E_ACTION_ADD:
mlx5e_add_l2_flow_rule(priv, &hn->ai, MLX5E_FULLMATCH);
if (!is_multicast_ether_addr(hn->ai.addr)) {
l2_err = mlx5_mpfs_add_mac(priv->mdev, hn->ai.addr);
if (!is_multicast_ether_addr(mac_addr)) {
l2_err = mlx5_mpfs_add_mac(priv->mdev, mac_addr);
hn->mpfs = !l2_err;
}
hn->action = MLX5E_ACTION_NONE;
break;

case MLX5E_ACTION_DEL:
if (!is_multicast_ether_addr(hn->ai.addr) && hn->mpfs)
l2_err = mlx5_mpfs_del_mac(priv->mdev, hn->ai.addr);
if (!is_multicast_ether_addr(mac_addr) && hn->mpfs)
l2_err = mlx5_mpfs_del_mac(priv->mdev, mac_addr);
mlx5e_del_l2_flow_rule(priv, &hn->ai);
mlx5e_del_l2_from_hash(hn);
break;
}

if (l2_err)
netdev_warn(priv->netdev, "MPFS, failed to %s mac %pM, err(%d)\n",
action == MLX5E_ACTION_ADD ? "add" : "del", hn->ai.addr, l2_err);
action == MLX5E_ACTION_ADD ? "add" : "del", mac_addr, l2_err);
}

static void mlx5e_sync_netdev_addr(struct mlx5e_priv *priv)
Expand Down
4 changes: 2 additions & 2 deletions drivers/net/usb/asix_devices.c
Original file line number Diff line number Diff line change
Expand Up @@ -626,7 +626,7 @@ static int asix_suspend(struct usb_interface *intf, pm_message_t message)
struct usbnet *dev = usb_get_intfdata(intf);
struct asix_common_private *priv = dev->driver_priv;

if (priv->suspend)
if (priv && priv->suspend)
priv->suspend(dev);

return usbnet_suspend(intf, message);
Expand Down Expand Up @@ -678,7 +678,7 @@ static int asix_resume(struct usb_interface *intf)
struct usbnet *dev = usb_get_intfdata(intf);
struct asix_common_private *priv = dev->driver_priv;

if (priv->resume)
if (priv && priv->resume)
priv->resume(dev);

return usbnet_resume(intf);
Expand Down
2 changes: 1 addition & 1 deletion drivers/net/usb/cdc_ether.c
Original file line number Diff line number Diff line change
Expand Up @@ -230,7 +230,7 @@ int usbnet_generic_cdc_bind(struct usbnet *dev, struct usb_interface *intf)
goto bad_desc;
}

if (header.usb_cdc_ether_desc) {
if (header.usb_cdc_ether_desc && info->ether->wMaxSegmentSize) {
dev->hard_mtu = le16_to_cpu(info->ether->wMaxSegmentSize);
/* because of Zaurus, we may be ignoring the host
* side link address we were given.
Expand Down
3 changes: 2 additions & 1 deletion drivers/net/usb/qmi_wwan.c
Original file line number Diff line number Diff line change
Expand Up @@ -499,6 +499,7 @@ static int qmi_wwan_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
return 1;
}
if (rawip) {
skb_reset_mac_header(skb);
skb->dev = dev->net; /* normally set by eth_type_trans */
skb->protocol = proto;
return 1;
Expand Down Expand Up @@ -681,7 +682,7 @@ static int qmi_wwan_bind(struct usbnet *dev, struct usb_interface *intf)
}

/* errors aren't fatal - we can live with the dynamic address */
if (cdc_ether) {
if (cdc_ether && cdc_ether->wMaxSegmentSize) {
dev->hard_mtu = le16_to_cpu(cdc_ether->wMaxSegmentSize);
usbnet_get_ethernet_addr(dev, cdc_ether->iMACAddress);
}
Expand Down
7 changes: 7 additions & 0 deletions include/linux/skbuff.h
Original file line number Diff line number Diff line change
Expand Up @@ -3770,6 +3770,13 @@ static inline void nf_reset_trace(struct sk_buff *skb)
#endif
}

static inline void ipvs_reset(struct sk_buff *skb)
{
#if IS_ENABLED(CONFIG_IP_VS)
skb->ipvs_property = 0;
#endif
}

/* Note: This doesn't put any conntrack and bridge info in dst. */
static inline void __nf_copy(struct sk_buff *dst, const struct sk_buff *src,
bool copy)
Expand Down
4 changes: 1 addition & 3 deletions include/net/act_api.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
struct tcf_idrinfo {
spinlock_t lock;
struct idr action_idr;
struct net *net;
};

struct tc_action_ops;
Expand Down Expand Up @@ -106,15 +105,14 @@ struct tc_action_net {

static inline
int tc_action_net_init(struct tc_action_net *tn,
const struct tc_action_ops *ops, struct net *net)
const struct tc_action_ops *ops)
{
int err = 0;

tn->idrinfo = kmalloc(sizeof(*tn->idrinfo), GFP_KERNEL);
if (!tn->idrinfo)
return -ENOMEM;
tn->ops = ops;
tn->idrinfo->net = net;
spin_lock_init(&tn->idrinfo->lock);
idr_init(&tn->idrinfo->action_idr);
return err;
Expand Down
24 changes: 24 additions & 0 deletions include/net/pkt_cls.h
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ struct tcf_exts {
__u32 type; /* for backward compat(TCA_OLD_COMPAT) */
int nr_actions;
struct tc_action **actions;
struct net *net;
#endif
/* Map to export classifier specific extension TLV types to the
* generic extensions API. Unsupported extensions must be set to 0.
Expand All @@ -107,6 +108,7 @@ static inline int tcf_exts_init(struct tcf_exts *exts, int action, int police)
#ifdef CONFIG_NET_CLS_ACT
exts->type = 0;
exts->nr_actions = 0;
exts->net = NULL;
exts->actions = kcalloc(TCA_ACT_MAX_PRIO, sizeof(struct tc_action *),
GFP_KERNEL);
if (!exts->actions)
Expand All @@ -117,6 +119,28 @@ static inline int tcf_exts_init(struct tcf_exts *exts, int action, int police)
return 0;
}

/* Return false if the netns is being destroyed in cleanup_net(). Callers
* need to do cleanup synchronously in this case, otherwise may race with
* tc_action_net_exit(). Return true for other cases.
*/
static inline bool tcf_exts_get_net(struct tcf_exts *exts)
{
#ifdef CONFIG_NET_CLS_ACT
exts->net = maybe_get_net(exts->net);
return exts->net != NULL;
#else
return true;
#endif
}

static inline void tcf_exts_put_net(struct tcf_exts *exts)
{
#ifdef CONFIG_NET_CLS_ACT
if (exts->net)
put_net(exts->net);
#endif
}

static inline void tcf_exts_to_list(const struct tcf_exts *exts,
struct list_head *actions)
{
Expand Down
1 change: 1 addition & 0 deletions net/core/skbuff.c
Original file line number Diff line number Diff line change
Expand Up @@ -4864,6 +4864,7 @@ void skb_scrub_packet(struct sk_buff *skb, bool xnet)
if (!xnet)
return;

ipvs_reset(skb);
skb_orphan(skb);
skb->mark = 0;
}
Expand Down
2 changes: 1 addition & 1 deletion net/ipv4/tcp_input.c
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ int sysctl_tcp_invalid_ratelimit __read_mostly = HZ/2;

#define FLAG_ACKED (FLAG_DATA_ACKED|FLAG_SYN_ACKED)
#define FLAG_NOT_DUP (FLAG_DATA|FLAG_WIN_UPDATE|FLAG_ACKED)
#define FLAG_CA_ALERT (FLAG_DATA_SACKED|FLAG_ECE)
#define FLAG_CA_ALERT (FLAG_DATA_SACKED|FLAG_ECE|FLAG_DSACKING_ACK)
#define FLAG_FORWARD_PROGRESS (FLAG_ACKED|FLAG_DATA_SACKED)

#define TCP_REMNANT (TCP_FLAG_FIN|TCP_FLAG_URG|TCP_FLAG_SYN|TCP_FLAG_PSH)
Expand Down
24 changes: 9 additions & 15 deletions net/l2tp/l2tp_ip.c
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@ static int l2tp_ip_recv(struct sk_buff *skb)
unsigned char *ptr, *optr;
struct l2tp_session *session;
struct l2tp_tunnel *tunnel = NULL;
struct iphdr *iph;
int length;

if (!pskb_may_pull(skb, 4))
Expand Down Expand Up @@ -178,24 +179,17 @@ static int l2tp_ip_recv(struct sk_buff *skb)
goto discard;

tunnel_id = ntohl(*(__be32 *) &skb->data[4]);
tunnel = l2tp_tunnel_find(net, tunnel_id);
if (tunnel) {
sk = tunnel->sock;
sock_hold(sk);
} else {
struct iphdr *iph = (struct iphdr *) skb_network_header(skb);

read_lock_bh(&l2tp_ip_lock);
sk = __l2tp_ip_bind_lookup(net, iph->daddr, iph->saddr,
inet_iif(skb), tunnel_id);
if (!sk) {
read_unlock_bh(&l2tp_ip_lock);
goto discard;
}
iph = (struct iphdr *)skb_network_header(skb);

sock_hold(sk);
read_lock_bh(&l2tp_ip_lock);
sk = __l2tp_ip_bind_lookup(net, iph->daddr, iph->saddr, inet_iif(skb),
tunnel_id);
if (!sk) {
read_unlock_bh(&l2tp_ip_lock);
goto discard;
}
sock_hold(sk);
read_unlock_bh(&l2tp_ip_lock);

if (!xfrm4_policy_check(sk, XFRM_POLICY_IN, skb))
goto discard_put;
Expand Down
24 changes: 9 additions & 15 deletions net/l2tp/l2tp_ip6.c
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@ static int l2tp_ip6_recv(struct sk_buff *skb)
unsigned char *ptr, *optr;
struct l2tp_session *session;
struct l2tp_tunnel *tunnel = NULL;
struct ipv6hdr *iph;
int length;

if (!pskb_may_pull(skb, 4))
Expand Down Expand Up @@ -192,24 +193,17 @@ static int l2tp_ip6_recv(struct sk_buff *skb)
goto discard;

tunnel_id = ntohl(*(__be32 *) &skb->data[4]);
tunnel = l2tp_tunnel_find(net, tunnel_id);
if (tunnel) {
sk = tunnel->sock;
sock_hold(sk);
} else {
struct ipv6hdr *iph = ipv6_hdr(skb);

read_lock_bh(&l2tp_ip6_lock);
sk = __l2tp_ip6_bind_lookup(net, &iph->daddr, &iph->saddr,
inet6_iif(skb), tunnel_id);
if (!sk) {
read_unlock_bh(&l2tp_ip6_lock);
goto discard;
}
iph = ipv6_hdr(skb);

sock_hold(sk);
read_lock_bh(&l2tp_ip6_lock);
sk = __l2tp_ip6_bind_lookup(net, &iph->daddr, &iph->saddr,
inet6_iif(skb), tunnel_id);
if (!sk) {
read_unlock_bh(&l2tp_ip6_lock);
goto discard;
}
sock_hold(sk);
read_unlock_bh(&l2tp_ip6_lock);

if (!xfrm6_policy_check(sk, XFRM_POLICY_IN, skb))
goto discard_put;
Expand Down
2 changes: 1 addition & 1 deletion net/qrtr/qrtr.c
Original file line number Diff line number Diff line change
Expand Up @@ -1085,7 +1085,7 @@ static int __init qrtr_proto_init(void)

return 0;
}
module_init(qrtr_proto_init);
postcore_initcall(qrtr_proto_init);

static void __exit qrtr_proto_fini(void)
{
Expand Down
2 changes: 0 additions & 2 deletions net/sched/act_api.c
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,6 @@ static void tcf_idr_remove(struct tcf_idrinfo *idrinfo, struct tc_action *p)
spin_lock_bh(&idrinfo->lock);
idr_remove_ext(&idrinfo->action_idr, p->tcfa_index);
spin_unlock_bh(&idrinfo->lock);
put_net(idrinfo->net);
gen_kill_estimator(&p->tcfa_rate_est);
free_tcf(p);
}
Expand Down Expand Up @@ -337,7 +336,6 @@ int tcf_idr_create(struct tc_action_net *tn, u32 index, struct nlattr *est,
p->idrinfo = idrinfo;
p->ops = ops;
INIT_LIST_HEAD(&p->list);
get_net(idrinfo->net);
*a = p;
return 0;
}
Expand Down
2 changes: 1 addition & 1 deletion net/sched/act_bpf.c
Original file line number Diff line number Diff line change
Expand Up @@ -398,7 +398,7 @@ static __net_init int bpf_init_net(struct net *net)
{
struct tc_action_net *tn = net_generic(net, bpf_net_id);

return tc_action_net_init(tn, &act_bpf_ops, net);
return tc_action_net_init(tn, &act_bpf_ops);
}

static void __net_exit bpf_exit_net(struct net *net)
Expand Down
2 changes: 1 addition & 1 deletion net/sched/act_connmark.c
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,7 @@ static __net_init int connmark_init_net(struct net *net)
{
struct tc_action_net *tn = net_generic(net, connmark_net_id);

return tc_action_net_init(tn, &act_connmark_ops, net);
return tc_action_net_init(tn, &act_connmark_ops);
}

static void __net_exit connmark_exit_net(struct net *net)
Expand Down
2 changes: 1 addition & 1 deletion net/sched/act_csum.c
Original file line number Diff line number Diff line change
Expand Up @@ -626,7 +626,7 @@ static __net_init int csum_init_net(struct net *net)
{
struct tc_action_net *tn = net_generic(net, csum_net_id);

return tc_action_net_init(tn, &act_csum_ops, net);
return tc_action_net_init(tn, &act_csum_ops);
}

static void __net_exit csum_exit_net(struct net *net)
Expand Down
2 changes: 1 addition & 1 deletion net/sched/act_gact.c
Original file line number Diff line number Diff line change
Expand Up @@ -232,7 +232,7 @@ static __net_init int gact_init_net(struct net *net)
{
struct tc_action_net *tn = net_generic(net, gact_net_id);

return tc_action_net_init(tn, &act_gact_ops, net);
return tc_action_net_init(tn, &act_gact_ops);
}

static void __net_exit gact_exit_net(struct net *net)
Expand Down
2 changes: 1 addition & 1 deletion net/sched/act_ife.c
Original file line number Diff line number Diff line change
Expand Up @@ -818,7 +818,7 @@ static __net_init int ife_init_net(struct net *net)
{
struct tc_action_net *tn = net_generic(net, ife_net_id);

return tc_action_net_init(tn, &act_ife_ops, net);
return tc_action_net_init(tn, &act_ife_ops);
}

static void __net_exit ife_exit_net(struct net *net)
Expand Down
Loading

0 comments on commit d1041cd

Please sign in to comment.