From e0e2cfbbe25da25570ed6414c94a7567645364f6 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Sat, 14 Apr 2018 16:00:33 +0200 Subject: [PATCH] 4.16-stable patches added patches: cdc_ether-flag-the-cinterion-ahs8-modem-by-gemalto-as-wwan.patch ip_gre-clear-feature-flags-when-incompatible-o_flags-are-set.patch l2tp-fix-race-in-duplicate-tunnel-detection.patch l2tp-fix-races-in-tunnel-creation.patch lan78xx-correctly-indicate-invalid-otp.patch rds-mp-rds-may-use-an-invalid-c_path.patch slip-check-if-rstate-is-initialized-before-uncompressing.patch vhost-fix-vhost_copy_to_user.patch vhost-fix-vhost_vq_access_ok-log-check.patch --- ...terion-ahs8-modem-by-gemalto-as-wwan.patch | 42 +++ ...gs-when-incompatible-o_flags-are-set.patch | 50 +++ ...x-race-in-duplicate-tunnel-detection.patch | 119 +++++++ .../l2tp-fix-races-in-tunnel-creation.patch | 336 ++++++++++++++++++ ...n78xx-correctly-indicate-invalid-otp.patch | 35 ++ ...rds-mp-rds-may-use-an-invalid-c_path.patch | 61 ++++ queue-4.16/series | 9 + ...-is-initialized-before-uncompressing.patch | 76 ++++ queue-4.16/vhost-fix-vhost_copy_to_user.patch | 34 ++ ...ost-fix-vhost_vq_access_ok-log-check.patch | 56 +++ 10 files changed, 818 insertions(+) create mode 100644 queue-4.16/cdc_ether-flag-the-cinterion-ahs8-modem-by-gemalto-as-wwan.patch create mode 100644 queue-4.16/ip_gre-clear-feature-flags-when-incompatible-o_flags-are-set.patch create mode 100644 queue-4.16/l2tp-fix-race-in-duplicate-tunnel-detection.patch create mode 100644 queue-4.16/l2tp-fix-races-in-tunnel-creation.patch create mode 100644 queue-4.16/lan78xx-correctly-indicate-invalid-otp.patch create mode 100644 queue-4.16/rds-mp-rds-may-use-an-invalid-c_path.patch create mode 100644 queue-4.16/slip-check-if-rstate-is-initialized-before-uncompressing.patch create mode 100644 queue-4.16/vhost-fix-vhost_copy_to_user.patch create mode 100644 queue-4.16/vhost-fix-vhost_vq_access_ok-log-check.patch diff --git a/queue-4.16/cdc_ether-flag-the-cinterion-ahs8-modem-by-gemalto-as-wwan.patch b/queue-4.16/cdc_ether-flag-the-cinterion-ahs8-modem-by-gemalto-as-wwan.patch new file mode 100644 index 00000000000..1eb8522d3f9 --- /dev/null +++ b/queue-4.16/cdc_ether-flag-the-cinterion-ahs8-modem-by-gemalto-as-wwan.patch @@ -0,0 +1,42 @@ +From foo@baz Sat Apr 14 09:15:32 CEST 2018 +From: Bassem Boubaker +Date: Wed, 11 Apr 2018 13:15:53 +0200 +Subject: cdc_ether: flag the Cinterion AHS8 modem by gemalto as WWAN + +From: Bassem Boubaker + + +[ 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 +Acked-by: Oliver Neukum +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + 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 +@@ -902,6 +902,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, diff --git a/queue-4.16/ip_gre-clear-feature-flags-when-incompatible-o_flags-are-set.patch b/queue-4.16/ip_gre-clear-feature-flags-when-incompatible-o_flags-are-set.patch new file mode 100644 index 00000000000..a7f1de42692 --- /dev/null +++ b/queue-4.16/ip_gre-clear-feature-flags-when-incompatible-o_flags-are-set.patch @@ -0,0 +1,50 @@ +From foo@baz Sat Apr 14 09:15:32 CEST 2018 +From: Sabrina Dubroca +Date: Tue, 10 Apr 2018 12:57:18 +0200 +Subject: ip_gre: clear feature flags when incompatible o_flags are set + +From: Sabrina Dubroca + + +[ 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 +Reviewed-by: Xin Long +Acked-by: William Tu +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/ipv4/ip_gre.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +--- a/net/ipv4/ip_gre.c ++++ b/net/ipv4/ip_gre.c +@@ -778,8 +778,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); + } + } + diff --git a/queue-4.16/l2tp-fix-race-in-duplicate-tunnel-detection.patch b/queue-4.16/l2tp-fix-race-in-duplicate-tunnel-detection.patch new file mode 100644 index 00000000000..49b29c69131 --- /dev/null +++ b/queue-4.16/l2tp-fix-race-in-duplicate-tunnel-detection.patch @@ -0,0 +1,119 @@ +From foo@baz Sat Apr 14 09:15:32 CEST 2018 +From: Guillaume Nault +Date: Tue, 10 Apr 2018 21:01:13 +0200 +Subject: l2tp: fix race in duplicate tunnel detection + +From: Guillaume Nault + + +[ 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 +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + 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); +@@ -1501,6 +1481,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; +@@ -1529,7 +1510,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); + +@@ -1558,7 +1548,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 +@@ -220,7 +220,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: diff --git a/queue-4.16/l2tp-fix-races-in-tunnel-creation.patch b/queue-4.16/l2tp-fix-races-in-tunnel-creation.patch new file mode 100644 index 00000000000..19cebf17efc --- /dev/null +++ b/queue-4.16/l2tp-fix-races-in-tunnel-creation.patch @@ -0,0 +1,336 @@ +From foo@baz Sat Apr 14 09:15:32 CEST 2018 +From: Guillaume Nault +Date: Tue, 10 Apr 2018 21:01:12 +0200 +Subject: l2tp: fix races in tunnel creation + +From: Guillaume Nault + + +[ 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 +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + 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 +@@ -1436,74 +1436,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; +@@ -1520,72 +1457,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 +@@ -226,6 +226,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 */ diff --git a/queue-4.16/lan78xx-correctly-indicate-invalid-otp.patch b/queue-4.16/lan78xx-correctly-indicate-invalid-otp.patch new file mode 100644 index 00000000000..e256fbce876 --- /dev/null +++ b/queue-4.16/lan78xx-correctly-indicate-invalid-otp.patch @@ -0,0 +1,35 @@ +From foo@baz Sat Apr 14 09:15:32 CEST 2018 +From: Phil Elwell +Date: Wed, 11 Apr 2018 10:59:17 +0100 +Subject: lan78xx: Correctly indicate invalid OTP + +From: Phil Elwell + + +[ 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 +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + 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; diff --git a/queue-4.16/rds-mp-rds-may-use-an-invalid-c_path.patch b/queue-4.16/rds-mp-rds-may-use-an-invalid-c_path.patch new file mode 100644 index 00000000000..17d1d9aad43 --- /dev/null +++ b/queue-4.16/rds-mp-rds-may-use-an-invalid-c_path.patch @@ -0,0 +1,61 @@ +From foo@baz Sat Apr 14 09:15:32 CEST 2018 +From: Ka-Cheong Poon +Date: Wed, 11 Apr 2018 00:57:25 -0700 +Subject: rds: MP-RDS may use an invalid c_path + +From: Ka-Cheong Poon + + +[ 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 +Acked-by: Santosh Shilimkar +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + 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 +@@ -997,10 +997,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; + } diff --git a/queue-4.16/series b/queue-4.16/series index e69de29bb2d..b5375d8051e 100644 --- a/queue-4.16/series +++ b/queue-4.16/series @@ -0,0 +1,9 @@ +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 diff --git a/queue-4.16/slip-check-if-rstate-is-initialized-before-uncompressing.patch b/queue-4.16/slip-check-if-rstate-is-initialized-before-uncompressing.patch new file mode 100644 index 00000000000..54541dd42a6 --- /dev/null +++ b/queue-4.16/slip-check-if-rstate-is-initialized-before-uncompressing.patch @@ -0,0 +1,76 @@ +From foo@baz Sat Apr 14 09:15:32 CEST 2018 +From: Tejaswi Tanikella +Date: Wed, 11 Apr 2018 16:34:47 +0530 +Subject: slip: Check if rstate is initialized before uncompressing + +From: Tejaswi Tanikella + + +[ 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> [] slhc_uncompress+0x464/0x468 +89.666965: <2> [] ppp_receive_nonmp_frame+0x3b4/0x65c +89.666978: <2> [] ppp_receive_frame+0x64/0x7e0 +89.666991: <2> [] ppp_input+0x104/0x198 +89.667005: <2> [] pppopns_recv_core+0x238/0x370 +89.667027: <2> [] __sk_receive_skb+0xdc/0x250 +89.667040: <2> [] pppopns_recv+0x44/0x60 +89.667053: <2> [] __sock_queue_rcv_skb+0x16c/0x24c +89.667065: <2> [] sock_queue_rcv_skb+0x2c/0x38 +89.667085: <2> [] raw_rcv+0x124/0x154 +89.667098: <2> [] raw_local_deliver+0x1e0/0x22c +89.667117: <2> [] ip_local_deliver_finish+0x70/0x24c +89.667131: <2> [] 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 +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + 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; diff --git a/queue-4.16/vhost-fix-vhost_copy_to_user.patch b/queue-4.16/vhost-fix-vhost_copy_to_user.patch new file mode 100644 index 00000000000..c75ac7fdebd --- /dev/null +++ b/queue-4.16/vhost-fix-vhost_copy_to_user.patch @@ -0,0 +1,34 @@ +From foo@baz Sat Apr 14 09:15:32 CEST 2018 +From: Eric Auger +Date: Wed, 11 Apr 2018 15:30:38 +0200 +Subject: vhost: Fix vhost_copy_to_user() + +From: Eric Auger + + +[ 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 +Acked-by: Jason Wang +Acked-by: Michael S. Tsirkin +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/vhost/vhost.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/vhost/vhost.c ++++ b/drivers/vhost/vhost.c +@@ -744,7 +744,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); diff --git a/queue-4.16/vhost-fix-vhost_vq_access_ok-log-check.patch b/queue-4.16/vhost-fix-vhost_vq_access_ok-log-check.patch new file mode 100644 index 00000000000..c3c019d7335 --- /dev/null +++ b/queue-4.16/vhost-fix-vhost_vq_access_ok-log-check.patch @@ -0,0 +1,56 @@ +From foo@baz Sat Apr 14 09:15:32 CEST 2018 +From: Stefan Hajnoczi +Date: Wed, 11 Apr 2018 10:35:40 +0800 +Subject: vhost: fix vhost_vq_access_ok() log check + +From: Stefan Hajnoczi + + +[ 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 +Signed-off-by: Stefan Hajnoczi +Acked-by: Michael S. Tsirkin +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/vhost/vhost.c | 8 +++++--- + 1 file changed, 5 insertions(+), 3 deletions(-) + +--- a/drivers/vhost/vhost.c ++++ b/drivers/vhost/vhost.c +@@ -1244,10 +1244,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); + } -- 2.47.3