--- /dev/null
+From foo@baz Sat Apr 14 09:16:37 CEST 2018
+From: Bassem Boubaker <bassem.boubaker@actia.fr>
+Date: Wed, 11 Apr 2018 13:15:53 +0200
+Subject: cdc_ether: flag the Cinterion AHS8 modem by gemalto as WWAN
+
+From: Bassem Boubaker <bassem.boubaker@actia.fr>
+
+
+[ Upstream commit 53765341ee821c0a0f1dec41adc89c9096ad694c ]
+
+The Cinterion AHS8 is a 3G device with one embedded WWAN interface
+using cdc_ether as a driver.
+
+The modem is controlled via AT commands through the exposed TTYs.
+
+AT+CGDCONT write command can be used to activate or deactivate a WWAN
+connection for a PDP context defined with the same command. UE
+supports one WWAN adapter.
+
+Signed-off-by: Bassem Boubaker <bassem.boubaker@actia.fr>
+Acked-by: Oliver Neukum <oneukum@suse.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/usb/cdc_ether.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+--- a/drivers/net/usb/cdc_ether.c
++++ b/drivers/net/usb/cdc_ether.c
+@@ -896,6 +896,12 @@ static const struct usb_device_id produc
+ USB_CDC_PROTO_NONE),
+ .driver_info = (unsigned long)&wwan_info,
+ }, {
++ /* Cinterion AHS3 modem by GEMALTO */
++ USB_DEVICE_AND_INTERFACE_INFO(0x1e2d, 0x0055, USB_CLASS_COMM,
++ USB_CDC_SUBCLASS_ETHERNET,
++ USB_CDC_PROTO_NONE),
++ .driver_info = (unsigned long)&wwan_info,
++}, {
+ USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_ETHERNET,
+ USB_CDC_PROTO_NONE),
+ .driver_info = (unsigned long) &cdc_info,
--- /dev/null
+From foo@baz Sat Apr 14 09:16:37 CEST 2018
+From: Sabrina Dubroca <sd@queasysnail.net>
+Date: Tue, 10 Apr 2018 12:57:18 +0200
+Subject: ip_gre: clear feature flags when incompatible o_flags are set
+
+From: Sabrina Dubroca <sd@queasysnail.net>
+
+
+[ Upstream commit 1cc5954f44150bb70cac07c3cc5df7cf0dfb61ec ]
+
+Commit dd9d598c6657 ("ip_gre: add the support for i/o_flags update via
+netlink") added the ability to change o_flags, but missed that the
+GSO/LLTX features are disabled by default, and only enabled some gre
+features are unused. Thus we also need to disable the GSO/LLTX features
+on the device when the TUNNEL_SEQ or TUNNEL_CSUM flags are set.
+
+These two examples should result in the same features being set:
+
+ ip link add gre_none type gre local 192.168.0.10 remote 192.168.0.20 ttl 255 key 0
+
+ ip link set gre_none type gre seq
+ ip link add gre_seq type gre local 192.168.0.10 remote 192.168.0.20 ttl 255 key 1 seq
+
+Fixes: dd9d598c6657 ("ip_gre: add the support for i/o_flags update via netlink")
+Signed-off-by: Sabrina Dubroca <sd@queasysnail.net>
+Reviewed-by: Xin Long <lucien.xin@gmail.com>
+Acked-by: William Tu <u9012063@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/ipv4/ip_gre.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+--- a/net/ipv4/ip_gre.c
++++ b/net/ipv4/ip_gre.c
+@@ -796,8 +796,14 @@ static void ipgre_link_update(struct net
+ tunnel->encap.type == TUNNEL_ENCAP_NONE) {
+ dev->features |= NETIF_F_GSO_SOFTWARE;
+ dev->hw_features |= NETIF_F_GSO_SOFTWARE;
++ } else {
++ dev->features &= ~NETIF_F_GSO_SOFTWARE;
++ dev->hw_features &= ~NETIF_F_GSO_SOFTWARE;
+ }
+ dev->features |= NETIF_F_LLTX;
++ } else {
++ dev->hw_features &= ~NETIF_F_GSO_SOFTWARE;
++ dev->features &= ~(NETIF_F_LLTX | NETIF_F_GSO_SOFTWARE);
+ }
+ }
+
--- /dev/null
+From foo@baz Sat Apr 14 09:16:37 CEST 2018
+From: Guillaume Nault <g.nault@alphalink.fr>
+Date: Tue, 10 Apr 2018 21:01:13 +0200
+Subject: l2tp: fix race in duplicate tunnel detection
+
+From: Guillaume Nault <g.nault@alphalink.fr>
+
+
+[ Upstream commit f6cd651b056ffd3b4e8496afd44d4ed44bf69136 ]
+
+We can't use l2tp_tunnel_find() to prevent l2tp_nl_cmd_tunnel_create()
+from creating a duplicate tunnel. A tunnel can be concurrently
+registered after l2tp_tunnel_find() returns. Therefore, searching for
+duplicates must be done at registration time.
+
+Finally, remove l2tp_tunnel_find() entirely as it isn't use anywhere
+anymore.
+
+Fixes: 309795f4bec2 ("l2tp: Add netlink control API for L2TP")
+Signed-off-by: Guillaume Nault <g.nault@alphalink.fr>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/l2tp/l2tp_core.c | 35 ++++++++++++++---------------------
+ net/l2tp/l2tp_core.h | 1 -
+ net/l2tp/l2tp_netlink.c | 6 ------
+ 3 files changed, 14 insertions(+), 28 deletions(-)
+
+--- a/net/l2tp/l2tp_core.c
++++ b/net/l2tp/l2tp_core.c
+@@ -335,26 +335,6 @@ err_tlock:
+ }
+ EXPORT_SYMBOL_GPL(l2tp_session_register);
+
+-/* Lookup a tunnel by id
+- */
+-struct l2tp_tunnel *l2tp_tunnel_find(const struct net *net, u32 tunnel_id)
+-{
+- struct l2tp_tunnel *tunnel;
+- struct l2tp_net *pn = l2tp_pernet(net);
+-
+- rcu_read_lock_bh();
+- list_for_each_entry_rcu(tunnel, &pn->l2tp_tunnel_list, list) {
+- if (tunnel->tunnel_id == tunnel_id) {
+- rcu_read_unlock_bh();
+- return tunnel;
+- }
+- }
+- rcu_read_unlock_bh();
+-
+- return NULL;
+-}
+-EXPORT_SYMBOL_GPL(l2tp_tunnel_find);
+-
+ struct l2tp_tunnel *l2tp_tunnel_find_nth(const struct net *net, int nth)
+ {
+ struct l2tp_net *pn = l2tp_pernet(net);
+@@ -1510,6 +1490,7 @@ static int l2tp_validate_socket(const st
+ int l2tp_tunnel_register(struct l2tp_tunnel *tunnel, struct net *net,
+ struct l2tp_tunnel_cfg *cfg)
+ {
++ struct l2tp_tunnel *tunnel_walk;
+ struct l2tp_net *pn;
+ struct socket *sock;
+ struct sock *sk;
+@@ -1538,7 +1519,16 @@ int l2tp_tunnel_register(struct l2tp_tun
+ tunnel->l2tp_net = net;
+
+ pn = l2tp_pernet(net);
++
+ spin_lock_bh(&pn->l2tp_tunnel_list_lock);
++ list_for_each_entry(tunnel_walk, &pn->l2tp_tunnel_list, list) {
++ if (tunnel_walk->tunnel_id == tunnel->tunnel_id) {
++ spin_unlock_bh(&pn->l2tp_tunnel_list_lock);
++
++ ret = -EEXIST;
++ goto err_sock;
++ }
++ }
+ list_add_rcu(&tunnel->list, &pn->l2tp_tunnel_list);
+ spin_unlock_bh(&pn->l2tp_tunnel_list_lock);
+
+@@ -1567,7 +1557,10 @@ int l2tp_tunnel_register(struct l2tp_tun
+ return 0;
+
+ err_sock:
+- sockfd_put(sock);
++ if (tunnel->fd < 0)
++ sock_release(sock);
++ else
++ sockfd_put(sock);
+ err:
+ return ret;
+ }
+--- a/net/l2tp/l2tp_core.h
++++ b/net/l2tp/l2tp_core.h
+@@ -225,7 +225,6 @@ struct l2tp_session *l2tp_session_get(co
+ struct l2tp_session *l2tp_session_get_nth(struct l2tp_tunnel *tunnel, int nth);
+ struct l2tp_session *l2tp_session_get_by_ifname(const struct net *net,
+ const char *ifname);
+-struct l2tp_tunnel *l2tp_tunnel_find(const struct net *net, u32 tunnel_id);
+ struct l2tp_tunnel *l2tp_tunnel_find_nth(const struct net *net, int nth);
+
+ int l2tp_tunnel_create(struct net *net, int fd, int version, u32 tunnel_id,
+--- a/net/l2tp/l2tp_netlink.c
++++ b/net/l2tp/l2tp_netlink.c
+@@ -236,12 +236,6 @@ static int l2tp_nl_cmd_tunnel_create(str
+ if (info->attrs[L2TP_ATTR_DEBUG])
+ cfg.debug = nla_get_u32(info->attrs[L2TP_ATTR_DEBUG]);
+
+- tunnel = l2tp_tunnel_find(net, tunnel_id);
+- if (tunnel != NULL) {
+- ret = -EEXIST;
+- goto out;
+- }
+-
+ ret = -EINVAL;
+ switch (cfg.encap) {
+ case L2TP_ENCAPTYPE_UDP:
--- /dev/null
+From foo@baz Sat Apr 14 09:16:37 CEST 2018
+From: Guillaume Nault <g.nault@alphalink.fr>
+Date: Tue, 10 Apr 2018 21:01:12 +0200
+Subject: l2tp: fix races in tunnel creation
+
+From: Guillaume Nault <g.nault@alphalink.fr>
+
+
+[ Upstream commit 6b9f34239b00e6956a267abed2bc559ede556ad6 ]
+
+l2tp_tunnel_create() inserts the new tunnel into the namespace's tunnel
+list and sets the socket's ->sk_user_data field, before returning it to
+the caller. Therefore, there are two ways the tunnel can be accessed
+and freed, before the caller even had the opportunity to take a
+reference. In practice, syzbot could crash the module by closing the
+socket right after a new tunnel was returned to pppol2tp_create().
+
+This patch moves tunnel registration out of l2tp_tunnel_create(), so
+that the caller can safely hold a reference before publishing the
+tunnel. This second step is done with the new l2tp_tunnel_register()
+function, which is now responsible for associating the tunnel to its
+socket and for inserting it into the namespace's list.
+
+While moving the code to l2tp_tunnel_register(), a few modifications
+have been done. First, the socket validation tests are done in a helper
+function, for clarity. Also, modifying the socket is now done after
+having inserted the tunnel to the namespace's tunnels list. This will
+allow insertion to fail, without having to revert theses modifications
+in the error path (a followup patch will check for duplicate tunnels
+before insertion). Either the socket is a kernel socket which we
+control, or it is a user-space socket for which we have a reference on
+the file descriptor. In any case, the socket isn't going to be closed
+from under us.
+
+Reported-by: syzbot+fbeeb5c3b538e8545644@syzkaller.appspotmail.com
+Fixes: fd558d186df2 ("l2tp: Split pppol2tp patch into separate l2tp and ppp parts")
+Signed-off-by: Guillaume Nault <g.nault@alphalink.fr>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/l2tp/l2tp_core.c | 192 +++++++++++++++++++++---------------------------
+ net/l2tp/l2tp_core.h | 3
+ net/l2tp/l2tp_netlink.c | 16 +++-
+ net/l2tp/l2tp_ppp.c | 9 ++
+ 4 files changed, 110 insertions(+), 110 deletions(-)
+
+--- a/net/l2tp/l2tp_core.c
++++ b/net/l2tp/l2tp_core.c
+@@ -1445,74 +1445,11 @@ int l2tp_tunnel_create(struct net *net,
+ {
+ struct l2tp_tunnel *tunnel = NULL;
+ int err;
+- struct socket *sock = NULL;
+- struct sock *sk = NULL;
+- struct l2tp_net *pn;
+ enum l2tp_encap_type encap = L2TP_ENCAPTYPE_UDP;
+
+- /* Get the tunnel socket from the fd, which was opened by
+- * the userspace L2TP daemon. If not specified, create a
+- * kernel socket.
+- */
+- if (fd < 0) {
+- err = l2tp_tunnel_sock_create(net, tunnel_id, peer_tunnel_id,
+- cfg, &sock);
+- if (err < 0)
+- goto err;
+- } else {
+- sock = sockfd_lookup(fd, &err);
+- if (!sock) {
+- pr_err("tunl %u: sockfd_lookup(fd=%d) returned %d\n",
+- tunnel_id, fd, err);
+- err = -EBADF;
+- goto err;
+- }
+-
+- /* Reject namespace mismatches */
+- if (!net_eq(sock_net(sock->sk), net)) {
+- pr_err("tunl %u: netns mismatch\n", tunnel_id);
+- err = -EINVAL;
+- goto err;
+- }
+- }
+-
+- sk = sock->sk;
+-
+ if (cfg != NULL)
+ encap = cfg->encap;
+
+- /* Quick sanity checks */
+- err = -EPROTONOSUPPORT;
+- if (sk->sk_type != SOCK_DGRAM) {
+- pr_debug("tunl %hu: fd %d wrong socket type\n",
+- tunnel_id, fd);
+- goto err;
+- }
+- switch (encap) {
+- case L2TP_ENCAPTYPE_UDP:
+- if (sk->sk_protocol != IPPROTO_UDP) {
+- pr_err("tunl %hu: fd %d wrong protocol, got %d, expected %d\n",
+- tunnel_id, fd, sk->sk_protocol, IPPROTO_UDP);
+- goto err;
+- }
+- break;
+- case L2TP_ENCAPTYPE_IP:
+- if (sk->sk_protocol != IPPROTO_L2TP) {
+- pr_err("tunl %hu: fd %d wrong protocol, got %d, expected %d\n",
+- tunnel_id, fd, sk->sk_protocol, IPPROTO_L2TP);
+- goto err;
+- }
+- break;
+- }
+-
+- /* Check if this socket has already been prepped */
+- tunnel = l2tp_tunnel(sk);
+- if (tunnel != NULL) {
+- /* This socket has already been prepped */
+- err = -EBUSY;
+- goto err;
+- }
+-
+ tunnel = kzalloc(sizeof(struct l2tp_tunnel), GFP_KERNEL);
+ if (tunnel == NULL) {
+ err = -ENOMEM;
+@@ -1529,72 +1466,113 @@ int l2tp_tunnel_create(struct net *net,
+ rwlock_init(&tunnel->hlist_lock);
+ tunnel->acpt_newsess = true;
+
+- /* The net we belong to */
+- tunnel->l2tp_net = net;
+- pn = l2tp_pernet(net);
+-
+ if (cfg != NULL)
+ tunnel->debug = cfg->debug;
+
+- /* Mark socket as an encapsulation socket. See net/ipv4/udp.c */
+ tunnel->encap = encap;
+- if (encap == L2TP_ENCAPTYPE_UDP) {
+- struct udp_tunnel_sock_cfg udp_cfg = { };
+-
+- udp_cfg.sk_user_data = tunnel;
+- udp_cfg.encap_type = UDP_ENCAP_L2TPINUDP;
+- udp_cfg.encap_rcv = l2tp_udp_encap_recv;
+- udp_cfg.encap_destroy = l2tp_udp_encap_destroy;
+-
+- setup_udp_tunnel_sock(net, sock, &udp_cfg);
+- } else {
+- sk->sk_user_data = tunnel;
+- }
+
+- /* Bump the reference count. The tunnel context is deleted
+- * only when this drops to zero. A reference is also held on
+- * the tunnel socket to ensure that it is not released while
+- * the tunnel is extant. Must be done before sk_destruct is
+- * set.
+- */
+ refcount_set(&tunnel->ref_count, 1);
+- sock_hold(sk);
+- tunnel->sock = sk;
+ tunnel->fd = fd;
+
+- /* Hook on the tunnel socket destructor so that we can cleanup
+- * if the tunnel socket goes away.
+- */
+- tunnel->old_sk_destruct = sk->sk_destruct;
+- sk->sk_destruct = &l2tp_tunnel_destruct;
+- lockdep_set_class_and_name(&sk->sk_lock.slock, &l2tp_socket_class, "l2tp_sock");
+-
+- sk->sk_allocation = GFP_ATOMIC;
+-
+ /* Init delete workqueue struct */
+ INIT_WORK(&tunnel->del_work, l2tp_tunnel_del_work);
+
+- /* Add tunnel to our list */
+ INIT_LIST_HEAD(&tunnel->list);
+- spin_lock_bh(&pn->l2tp_tunnel_list_lock);
+- list_add_rcu(&tunnel->list, &pn->l2tp_tunnel_list);
+- spin_unlock_bh(&pn->l2tp_tunnel_list_lock);
+
+ err = 0;
+ err:
+ if (tunnelp)
+ *tunnelp = tunnel;
+
+- /* If tunnel's socket was created by the kernel, it doesn't
+- * have a file.
+- */
+- if (sock && sock->file)
+- sockfd_put(sock);
+-
+ return err;
+ }
+ EXPORT_SYMBOL_GPL(l2tp_tunnel_create);
+
++static int l2tp_validate_socket(const struct sock *sk, const struct net *net,
++ enum l2tp_encap_type encap)
++{
++ if (!net_eq(sock_net(sk), net))
++ return -EINVAL;
++
++ if (sk->sk_type != SOCK_DGRAM)
++ return -EPROTONOSUPPORT;
++
++ if ((encap == L2TP_ENCAPTYPE_UDP && sk->sk_protocol != IPPROTO_UDP) ||
++ (encap == L2TP_ENCAPTYPE_IP && sk->sk_protocol != IPPROTO_L2TP))
++ return -EPROTONOSUPPORT;
++
++ if (sk->sk_user_data)
++ return -EBUSY;
++
++ return 0;
++}
++
++int l2tp_tunnel_register(struct l2tp_tunnel *tunnel, struct net *net,
++ struct l2tp_tunnel_cfg *cfg)
++{
++ struct l2tp_net *pn;
++ struct socket *sock;
++ struct sock *sk;
++ int ret;
++
++ if (tunnel->fd < 0) {
++ ret = l2tp_tunnel_sock_create(net, tunnel->tunnel_id,
++ tunnel->peer_tunnel_id, cfg,
++ &sock);
++ if (ret < 0)
++ goto err;
++ } else {
++ sock = sockfd_lookup(tunnel->fd, &ret);
++ if (!sock)
++ goto err;
++
++ ret = l2tp_validate_socket(sock->sk, net, tunnel->encap);
++ if (ret < 0)
++ goto err_sock;
++ }
++
++ sk = sock->sk;
++
++ sock_hold(sk);
++ tunnel->sock = sk;
++ tunnel->l2tp_net = net;
++
++ pn = l2tp_pernet(net);
++ spin_lock_bh(&pn->l2tp_tunnel_list_lock);
++ list_add_rcu(&tunnel->list, &pn->l2tp_tunnel_list);
++ spin_unlock_bh(&pn->l2tp_tunnel_list_lock);
++
++ if (tunnel->encap == L2TP_ENCAPTYPE_UDP) {
++ struct udp_tunnel_sock_cfg udp_cfg = {
++ .sk_user_data = tunnel,
++ .encap_type = UDP_ENCAP_L2TPINUDP,
++ .encap_rcv = l2tp_udp_encap_recv,
++ .encap_destroy = l2tp_udp_encap_destroy,
++ };
++
++ setup_udp_tunnel_sock(net, sock, &udp_cfg);
++ } else {
++ sk->sk_user_data = tunnel;
++ }
++
++ tunnel->old_sk_destruct = sk->sk_destruct;
++ sk->sk_destruct = &l2tp_tunnel_destruct;
++ lockdep_set_class_and_name(&sk->sk_lock.slock, &l2tp_socket_class,
++ "l2tp_sock");
++ sk->sk_allocation = GFP_ATOMIC;
++
++ if (tunnel->fd >= 0)
++ sockfd_put(sock);
++
++ return 0;
++
++err_sock:
++ sockfd_put(sock);
++err:
++ return ret;
++}
++EXPORT_SYMBOL_GPL(l2tp_tunnel_register);
++
+ /* This function is used by the netlink TUNNEL_DELETE command.
+ */
+ void l2tp_tunnel_delete(struct l2tp_tunnel *tunnel)
+--- a/net/l2tp/l2tp_core.h
++++ b/net/l2tp/l2tp_core.h
+@@ -231,6 +231,9 @@ struct l2tp_tunnel *l2tp_tunnel_find_nth
+ int l2tp_tunnel_create(struct net *net, int fd, int version, u32 tunnel_id,
+ u32 peer_tunnel_id, struct l2tp_tunnel_cfg *cfg,
+ struct l2tp_tunnel **tunnelp);
++int l2tp_tunnel_register(struct l2tp_tunnel *tunnel, struct net *net,
++ struct l2tp_tunnel_cfg *cfg);
++
+ void l2tp_tunnel_closeall(struct l2tp_tunnel *tunnel);
+ void l2tp_tunnel_delete(struct l2tp_tunnel *tunnel);
+ struct l2tp_session *l2tp_session_create(int priv_size,
+--- a/net/l2tp/l2tp_netlink.c
++++ b/net/l2tp/l2tp_netlink.c
+@@ -251,9 +251,19 @@ static int l2tp_nl_cmd_tunnel_create(str
+ break;
+ }
+
+- if (ret >= 0)
+- ret = l2tp_tunnel_notify(&l2tp_nl_family, info,
+- tunnel, L2TP_CMD_TUNNEL_CREATE);
++ if (ret < 0)
++ goto out;
++
++ l2tp_tunnel_inc_refcount(tunnel);
++ ret = l2tp_tunnel_register(tunnel, net, &cfg);
++ if (ret < 0) {
++ kfree(tunnel);
++ goto out;
++ }
++ ret = l2tp_tunnel_notify(&l2tp_nl_family, info, tunnel,
++ L2TP_CMD_TUNNEL_CREATE);
++ l2tp_tunnel_dec_refcount(tunnel);
++
+ out:
+ return ret;
+ }
+--- a/net/l2tp/l2tp_ppp.c
++++ b/net/l2tp/l2tp_ppp.c
+@@ -698,6 +698,15 @@ static int pppol2tp_connect(struct socke
+ error = l2tp_tunnel_create(sock_net(sk), fd, ver, tunnel_id, peer_tunnel_id, &tcfg, &tunnel);
+ if (error < 0)
+ goto end;
++
++ l2tp_tunnel_inc_refcount(tunnel);
++ error = l2tp_tunnel_register(tunnel, sock_net(sk),
++ &tcfg);
++ if (error < 0) {
++ kfree(tunnel);
++ goto end;
++ }
++ drop_tunnel = true;
+ }
+ } else {
+ /* Error if we can't find the tunnel */
--- /dev/null
+From foo@baz Sat Apr 14 09:16:37 CEST 2018
+From: Phil Elwell <phil@raspberrypi.org>
+Date: Wed, 11 Apr 2018 10:59:17 +0100
+Subject: lan78xx: Correctly indicate invalid OTP
+
+From: Phil Elwell <phil@raspberrypi.org>
+
+
+[ Upstream commit 4bfc33807a9a02764bdd1e42e794b3b401240f27 ]
+
+lan78xx_read_otp tries to return -EINVAL in the event of invalid OTP
+content, but the value gets overwritten before it is returned and the
+read goes ahead anyway. Make the read conditional as it should be
+and preserve the error code.
+
+Fixes: 55d7de9de6c3 ("Microchip's LAN7800 family USB 2/3 to 10/100/1000 Ethernet device driver")
+Signed-off-by: Phil Elwell <phil@raspberrypi.org>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/usb/lan78xx.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/drivers/net/usb/lan78xx.c
++++ b/drivers/net/usb/lan78xx.c
+@@ -928,7 +928,8 @@ static int lan78xx_read_otp(struct lan78
+ offset += 0x100;
+ else
+ ret = -EINVAL;
+- ret = lan78xx_read_raw_otp(dev, offset, length, data);
++ if (!ret)
++ ret = lan78xx_read_raw_otp(dev, offset, length, data);
+ }
+
+ return ret;
--- /dev/null
+From foo@baz Sat Apr 14 09:16:37 CEST 2018
+From: Ka-Cheong Poon <ka-cheong.poon@oracle.com>
+Date: Wed, 11 Apr 2018 00:57:25 -0700
+Subject: rds: MP-RDS may use an invalid c_path
+
+From: Ka-Cheong Poon <ka-cheong.poon@oracle.com>
+
+
+[ Upstream commit a43cced9a348901f9015f4730b70b69e7c41a9c9 ]
+
+rds_sendmsg() calls rds_send_mprds_hash() to find a c_path to use to
+send a message. Suppose the RDS connection is not yet up. In
+rds_send_mprds_hash(), it does
+
+ if (conn->c_npaths == 0)
+ wait_event_interruptible(conn->c_hs_waitq,
+ (conn->c_npaths != 0));
+
+If it is interrupted before the connection is set up,
+rds_send_mprds_hash() will return a non-zero hash value. Hence
+rds_sendmsg() will use a non-zero c_path to send the message. But if
+the RDS connection ends up to be non-MP capable, the message will be
+lost as only the zero c_path can be used.
+
+Signed-off-by: Ka-Cheong Poon <ka-cheong.poon@oracle.com>
+Acked-by: Santosh Shilimkar <santosh.shilimkar@oracle.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/rds/send.c | 15 ++++++++++-----
+ 1 file changed, 10 insertions(+), 5 deletions(-)
+
+--- a/net/rds/send.c
++++ b/net/rds/send.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2006 Oracle. All rights reserved.
++ * Copyright (c) 2006, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses. You may choose to be licensed under the terms of the GNU
+@@ -986,10 +986,15 @@ static int rds_send_mprds_hash(struct rd
+ if (conn->c_npaths == 0 && hash != 0) {
+ rds_send_ping(conn, 0);
+
+- if (conn->c_npaths == 0) {
+- wait_event_interruptible(conn->c_hs_waitq,
+- (conn->c_npaths != 0));
+- }
++ /* The underlying connection is not up yet. Need to wait
++ * until it is up to be sure that the non-zero c_path can be
++ * used. But if we are interrupted, we have to use the zero
++ * c_path in case the connection ends up being non-MP capable.
++ */
++ if (conn->c_npaths == 0)
++ if (wait_event_interruptible(conn->c_hs_waitq,
++ conn->c_npaths != 0))
++ hash = 0;
+ if (conn->c_npaths == 1)
+ hash = 0;
+ }
drm-i915-edp-do-not-do-link-training-fallback-or-prune-modes-on-edp.patch
netfilter-ipset-missing-nfnl_lock-nfnl_unlock-is-added-to-ip_set_net_exit.patch
+cdc_ether-flag-the-cinterion-ahs8-modem-by-gemalto-as-wwan.patch
+rds-mp-rds-may-use-an-invalid-c_path.patch
+slip-check-if-rstate-is-initialized-before-uncompressing.patch
+vhost-fix-vhost_vq_access_ok-log-check.patch
+l2tp-fix-races-in-tunnel-creation.patch
+l2tp-fix-race-in-duplicate-tunnel-detection.patch
+ip_gre-clear-feature-flags-when-incompatible-o_flags-are-set.patch
+vhost-fix-vhost_copy_to_user.patch
+lan78xx-correctly-indicate-invalid-otp.patch
--- /dev/null
+From foo@baz Sat Apr 14 09:16:37 CEST 2018
+From: Tejaswi Tanikella <tejaswit@codeaurora.org>
+Date: Wed, 11 Apr 2018 16:34:47 +0530
+Subject: slip: Check if rstate is initialized before uncompressing
+
+From: Tejaswi Tanikella <tejaswit@codeaurora.org>
+
+
+[ Upstream commit 3f01ddb962dc506916c243f9524e8bef97119b77 ]
+
+On receiving a packet the state index points to the rstate which must be
+used to fill up IP and TCP headers. But if the state index points to a
+rstate which is unitialized, i.e. filled with zeros, it gets stuck in an
+infinite loop inside ip_fast_csum trying to compute the ip checsum of a
+header with zero length.
+
+89.666953: <2> [<ffffff9dd3e94d38>] slhc_uncompress+0x464/0x468
+89.666965: <2> [<ffffff9dd3e87d88>] ppp_receive_nonmp_frame+0x3b4/0x65c
+89.666978: <2> [<ffffff9dd3e89dd4>] ppp_receive_frame+0x64/0x7e0
+89.666991: <2> [<ffffff9dd3e8a708>] ppp_input+0x104/0x198
+89.667005: <2> [<ffffff9dd3e93868>] pppopns_recv_core+0x238/0x370
+89.667027: <2> [<ffffff9dd4428fc8>] __sk_receive_skb+0xdc/0x250
+89.667040: <2> [<ffffff9dd3e939e4>] pppopns_recv+0x44/0x60
+89.667053: <2> [<ffffff9dd4426848>] __sock_queue_rcv_skb+0x16c/0x24c
+89.667065: <2> [<ffffff9dd4426954>] sock_queue_rcv_skb+0x2c/0x38
+89.667085: <2> [<ffffff9dd44f7358>] raw_rcv+0x124/0x154
+89.667098: <2> [<ffffff9dd44f7568>] raw_local_deliver+0x1e0/0x22c
+89.667117: <2> [<ffffff9dd44c8ba0>] ip_local_deliver_finish+0x70/0x24c
+89.667131: <2> [<ffffff9dd44c92f4>] ip_local_deliver+0x100/0x10c
+
+./scripts/faddr2line vmlinux slhc_uncompress+0x464/0x468 output:
+ ip_fast_csum at arch/arm64/include/asm/checksum.h:40
+ (inlined by) slhc_uncompress at drivers/net/slip/slhc.c:615
+
+Adding a variable to indicate if the current rstate is initialized. If
+such a packet arrives, move to toss state.
+
+Signed-off-by: Tejaswi Tanikella <tejaswit@codeaurora.org>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/slip/slhc.c | 5 +++++
+ include/net/slhc_vj.h | 1 +
+ 2 files changed, 6 insertions(+)
+
+--- a/drivers/net/slip/slhc.c
++++ b/drivers/net/slip/slhc.c
+@@ -509,6 +509,10 @@ slhc_uncompress(struct slcompress *comp,
+ if(x < 0 || x > comp->rslot_limit)
+ goto bad;
+
++ /* Check if the cstate is initialized */
++ if (!comp->rstate[x].initialized)
++ goto bad;
++
+ comp->flags &=~ SLF_TOSS;
+ comp->recv_current = x;
+ } else {
+@@ -673,6 +677,7 @@ slhc_remember(struct slcompress *comp, u
+ if (cs->cs_tcp.doff > 5)
+ memcpy(cs->cs_tcpopt, icp + ihl*4 + sizeof(struct tcphdr), (cs->cs_tcp.doff - 5) * 4);
+ cs->cs_hsize = ihl*2 + cs->cs_tcp.doff*2;
++ cs->initialized = true;
+ /* Put headers back on packet
+ * Neither header checksum is recalculated
+ */
+--- a/include/net/slhc_vj.h
++++ b/include/net/slhc_vj.h
+@@ -127,6 +127,7 @@ typedef __u32 int32;
+ */
+ struct cstate {
+ byte_t cs_this; /* connection id number (xmit) */
++ bool initialized; /* true if initialized */
+ struct cstate *next; /* next in ring (xmit) */
+ struct iphdr cs_ip; /* ip/tcp hdr from most recent packet */
+ struct tcphdr cs_tcp;
--- /dev/null
+From foo@baz Sat Apr 14 09:16:37 CEST 2018
+From: Eric Auger <eric.auger@redhat.com>
+Date: Wed, 11 Apr 2018 15:30:38 +0200
+Subject: vhost: Fix vhost_copy_to_user()
+
+From: Eric Auger <eric.auger@redhat.com>
+
+
+[ Upstream commit 7ced6c98c7ab7a1f6743931e28671b833af79b1e ]
+
+vhost_copy_to_user is used to copy vring used elements to userspace.
+We should use VHOST_ADDR_USED instead of VHOST_ADDR_DESC.
+
+Fixes: f88949138058 ("vhost: introduce O(1) vq metadata cache")
+Signed-off-by: Eric Auger <eric.auger@redhat.com>
+Acked-by: Jason Wang <jasowang@redhat.com>
+Acked-by: Michael S. Tsirkin <mst@redhat.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/vhost/vhost.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/vhost/vhost.c
++++ b/drivers/vhost/vhost.c
+@@ -756,7 +756,7 @@ static int vhost_copy_to_user(struct vho
+ struct iov_iter t;
+ void __user *uaddr = vhost_vq_meta_fetch(vq,
+ (u64)(uintptr_t)to, size,
+- VHOST_ADDR_DESC);
++ VHOST_ADDR_USED);
+
+ if (uaddr)
+ return __copy_to_user(uaddr, from, size);
--- /dev/null
+From foo@baz Sat Apr 14 09:16:37 CEST 2018
+From: Stefan Hajnoczi <stefanha@redhat.com>
+Date: Wed, 11 Apr 2018 10:35:40 +0800
+Subject: vhost: fix vhost_vq_access_ok() log check
+
+From: Stefan Hajnoczi <stefanha@redhat.com>
+
+
+[ Upstream commit d14d2b78090c7de0557362b26a4ca591aa6a9faa ]
+
+Commit d65026c6c62e7d9616c8ceb5a53b68bcdc050525 ("vhost: validate log
+when IOTLB is enabled") introduced a regression. The logic was
+originally:
+
+ if (vq->iotlb)
+ return 1;
+ return A && B;
+
+After the patch the short-circuit logic for A was inverted:
+
+ if (A || vq->iotlb)
+ return A;
+ return B;
+
+This patch fixes the regression by rewriting the checks in the obvious
+way, no longer returning A when vq->iotlb is non-NULL (which is hard to
+understand).
+
+Reported-by: syzbot+65a84dde0214b0387ccd@syzkaller.appspotmail.com
+Cc: Jason Wang <jasowang@redhat.com>
+Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
+Acked-by: Michael S. Tsirkin <mst@redhat.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/vhost/vhost.c | 8 +++++---
+ 1 file changed, 5 insertions(+), 3 deletions(-)
+
+--- a/drivers/vhost/vhost.c
++++ b/drivers/vhost/vhost.c
+@@ -1256,10 +1256,12 @@ static int vq_log_access_ok(struct vhost
+ /* Caller should have vq mutex and device mutex */
+ int vhost_vq_access_ok(struct vhost_virtqueue *vq)
+ {
+- int ret = vq_log_access_ok(vq, vq->log_base);
++ if (!vq_log_access_ok(vq, vq->log_base))
++ return 0;
+
+- if (ret || vq->iotlb)
+- return ret;
++ /* Access validation occurs at prefetch time with IOTLB */
++ if (vq->iotlb)
++ return 1;
+
+ return vq_access_ok(vq, vq->num, vq->desc, vq->avail, vq->used);
+ }