This is the start of the stable review cycle for the 4.4.219 release. There are 29 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Mon, 13 Apr 2020 11:51:28 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at: https://www.kernel.org/pub/linux/kernel/v4.x/stable-review/patch-4.4.219-rc1... or in the git tree and branch at: git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git linux-4.4.y and the diffstat can be found below.
thanks,
greg k-h
------------- Pseudo-Shortlog of commits:
Greg Kroah-Hartman gregkh@linuxfoundation.org Linux 4.4.219-rc1
Hans Verkuil hans.verkuil@cisco.com drm_dp_mst_topology: fix broken drm_dp_sideband_parse_remote_dpcd_read()
Taniya Das tdas@codeaurora.org clk: qcom: rcg: Return failure for RCG update
Avihai Horon avihaih@mellanox.com RDMA/cm: Update num_paths in cma_resolve_iboe_route error flow
Qiujun Huang hqjagain@gmail.com Bluetooth: RFCOMM: fix ODEBUG bug in rfcomm_dev_ioctl
Kaike Wan kaike.wan@intel.com IB/hfi1: Call kobject_put() when kobject_init_and_add() fails
Paul Cercueil paul@crapouillou.net ASoC: jz4740-i2s: Fix divider written at incorrect offset in register
Ross Lagerwall ross.lagerwall@citrix.com xen-netfront: Update features after registering netdev
Ross Lagerwall ross.lagerwall@citrix.com xen-netfront: Fix mismatched rtnl_unlock
Gustavo A. R. Silva gustavo@embeddedor.com power: supply: axp288_charger: Fix unchecked return value
David Ahern dsahern@kernel.org tools/accounting/getdelays.c: fix netlink attribute length
Jason A. Donenfeld Jason@zx2c4.com random: always use batched entropy for get_random_u{32,64}
Richard Palethorpe rpalethorpe@suse.com slcan: Don't transmit uninitialized stack data in padding
Jisheng Zhang Jisheng.Zhang@synaptics.com net: stmmac: dwmac1000: fix out-of-bounds mac address reg setting
Randy Dunlap rdunlap@infradead.org mm: mempolicy: require at least one nodeid for MPOL_PREFERRED
Daniel Jordan daniel.m.jordan@oracle.com padata: always acquire cpu_hotplug_lock before pinst->lock
Krzysztof Opasiak k.opasiak@samsung.com usb: gadget: printer: Drop unused device qualifier descriptor
Krzysztof Opasiak k.opasiak@samsung.com usb: gadget: uac2: Drop unused device qualifier descriptor
Guillaume Nault g.nault@alphalink.fr l2tp: fix race between l2tp_session_delete() and l2tp_tunnel_closeall()
Guillaume Nault g.nault@alphalink.fr l2tp: ensure sessions are freed after their PPPOL2TP socket
Gao Feng fgao@ikuai8.com l2tp: Refactor the codes with existing macros instead of literal number
Guillaume Nault g.nault@alphalink.fr l2tp: fix duplicate session creation
Guillaume Nault g.nault@alphalink.fr l2tp: ensure session can't get removed during pppol2tp_session_ioctl()
Guillaume Nault g.nault@alphalink.fr l2tp: fix race in l2tp_recv_common()
Shmulik Ladkani shmulik.ladkani@gmail.com net: l2tp: Make l2tp_ip6 namespace aware
phil.turnbull@oracle.com phil.turnbull@oracle.com l2tp: Correctly return -EBADF from pppol2tp_getname.
Marcelo Ricardo Leitner marcelo.leitner@gmail.com sctp: fix possibly using a bad saddr with a given dst
William Dauchy w.dauchy@criteo.com net, ip_tunnel: fix interface lookup with no key
Qian Cai cai@lca.pw ipv4: fix a RCU-list lock in fib_triestat_seq_show
Gerd Hoffmann kraxel@redhat.com drm/bochs: downgrade pci_request_region failure from error to warning
-------------
Diffstat:
Documentation/accounting/getdelays.c | 2 +- Makefile | 4 +- drivers/char/random.c | 6 - drivers/clk/qcom/clk-rcg2.c | 2 +- drivers/gpu/drm/bochs/bochs_hw.c | 6 +- drivers/gpu/drm/drm_dp_mst_topology.c | 1 + drivers/infiniband/core/cma.c | 1 + drivers/net/can/slcan.c | 4 +- .../net/ethernet/stmicro/stmmac/dwmac1000_core.c | 2 +- drivers/net/xen-netfront.c | 11 +- drivers/power/axp288_charger.c | 4 + drivers/staging/rdma/hfi1/sysfs.c | 13 +- drivers/usb/gadget/function/f_printer.c | 8 -- drivers/usb/gadget/function/f_uac2.c | 12 -- kernel/padata.c | 4 +- mm/mempolicy.c | 6 +- net/bluetooth/rfcomm/tty.c | 4 +- net/ipv4/fib_trie.c | 3 + net/ipv4/ip_tunnel.c | 6 +- net/l2tp/l2tp_core.c | 149 ++++++++++++++++----- net/l2tp/l2tp_core.h | 4 + net/l2tp/l2tp_eth.c | 10 +- net/l2tp/l2tp_ip.c | 17 ++- net/l2tp/l2tp_ip6.c | 28 ++-- net/l2tp/l2tp_ppp.c | 110 +++++++-------- net/sctp/ipv6.c | 20 ++- net/sctp/protocol.c | 28 ++-- sound/soc/jz4740/jz4740-i2s.c | 2 +- 28 files changed, 285 insertions(+), 182 deletions(-)
From: Gerd Hoffmann kraxel@redhat.com
[ Upstream commit 8c34cd1a7f089dc03933289c5d4a4d1489549828 ]
Shutdown of firmware framebuffer has a bunch of problems. Because of this the framebuffer region might still be reserved even after drm_fb_helper_remove_conflicting_pci_framebuffers() returned.
Don't consider pci_request_region() failure for the framebuffer region as fatal error to workaround this issue.
Reported-by: Marek Marczykowski-Górecki marmarek@invisiblethingslab.com Signed-off-by: Gerd Hoffmann kraxel@redhat.com Acked-by: Sam Ravnborg sam@ravnborg.org Link: http://patchwork.freedesktop.org/patch/msgid/20200313084152.2734-1-kraxel@re... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/bochs/bochs_hw.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/drivers/gpu/drm/bochs/bochs_hw.c b/drivers/gpu/drm/bochs/bochs_hw.c index a39b0343c197d..401c218567af9 100644 --- a/drivers/gpu/drm/bochs/bochs_hw.c +++ b/drivers/gpu/drm/bochs/bochs_hw.c @@ -97,10 +97,8 @@ int bochs_hw_init(struct drm_device *dev, uint32_t flags) size = min(size, mem); }
- if (pci_request_region(pdev, 0, "bochs-drm") != 0) { - DRM_ERROR("Cannot request framebuffer\n"); - return -EBUSY; - } + if (pci_request_region(pdev, 0, "bochs-drm") != 0) + DRM_WARN("Cannot request framebuffer, boot fb still active?\n");
bochs->fb_map = ioremap(addr, size); if (bochs->fb_map == NULL) {
From: Qian Cai cai@lca.pw
[ Upstream commit fbe4e0c1b298b4665ee6915266c9d6c5b934ef4a ]
fib_triestat_seq_show() calls hlist_for_each_entry_rcu(tb, head, tb_hlist) without rcu_read_lock() will trigger a warning,
net/ipv4/fib_trie.c:2579 RCU-list traversed in non-reader section!!
other info that might help us debug this:
rcu_scheduler_active = 2, debug_locks = 1 1 lock held by proc01/115277: #0: c0000014507acf00 (&p->lock){+.+.}-{3:3}, at: seq_read+0x58/0x670
Call Trace: dump_stack+0xf4/0x164 (unreliable) lockdep_rcu_suspicious+0x140/0x164 fib_triestat_seq_show+0x750/0x880 seq_read+0x1a0/0x670 proc_reg_read+0x10c/0x1b0 __vfs_read+0x3c/0x70 vfs_read+0xac/0x170 ksys_read+0x7c/0x140 system_call+0x5c/0x68
Fix it by adding a pair of rcu_read_lock/unlock() and use cond_resched_rcu() to avoid the situation where walking of a large number of items may prevent scheduling for a long time.
Signed-off-by: Qian Cai cai@lca.pw Reviewed-by: Eric Dumazet edumazet@google.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- net/ipv4/fib_trie.c | 3 +++ 1 file changed, 3 insertions(+)
--- a/net/ipv4/fib_trie.c +++ b/net/ipv4/fib_trie.c @@ -2230,6 +2230,7 @@ static int fib_triestat_seq_show(struct " %Zd bytes, size of tnode: %Zd bytes.\n", LEAF_SIZE, TNODE_SIZE(0));
+ rcu_read_lock(); for (h = 0; h < FIB_TABLE_HASHSZ; h++) { struct hlist_head *head = &net->ipv4.fib_table_hash[h]; struct fib_table *tb; @@ -2249,7 +2250,9 @@ static int fib_triestat_seq_show(struct trie_show_usage(seq, t->stats); #endif } + cond_resched_rcu(); } + rcu_read_unlock();
return 0; }
From: William Dauchy w.dauchy@criteo.com
[ Upstream commit 25629fdaff2ff509dd0b3f5ff93d70a75e79e0a1 ]
when creating a new ipip interface with no local/remote configuration, the lookup is done with TUNNEL_NO_KEY flag, making it impossible to match the new interface (only possible match being fallback or metada case interface); e.g: `ip link add tunl1 type ipip dev eth0`
To fix this case, adding a flag check before the key comparison so we permit to match an interface with no local/remote config; it also avoids breaking possible userland tools relying on TUNNEL_NO_KEY flag and uninitialised key.
context being on my side, I'm creating an extra ipip interface attached to the physical one, and moving it to a dedicated namespace.
Fixes: c54419321455 ("GRE: Refactor GRE tunneling code.") Signed-off-by: William Dauchy w.dauchy@criteo.com Signed-off-by: Nicolas Dichtel nicolas.dichtel@6wind.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- net/ipv4/ip_tunnel.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-)
--- a/net/ipv4/ip_tunnel.c +++ b/net/ipv4/ip_tunnel.c @@ -155,11 +155,8 @@ struct ip_tunnel *ip_tunnel_lookup(struc cand = t; }
- if (flags & TUNNEL_NO_KEY) - goto skip_key_lookup; - hlist_for_each_entry_rcu(t, head, hash_node) { - if (t->parms.i_key != key || + if ((!(flags & TUNNEL_NO_KEY) && t->parms.i_key != key) || t->parms.iph.saddr != 0 || t->parms.iph.daddr != 0 || !(t->dev->flags & IFF_UP)) @@ -171,7 +168,6 @@ struct ip_tunnel *ip_tunnel_lookup(struc cand = t; }
-skip_key_lookup: if (cand) return cand;
From: Marcelo Ricardo Leitner marcelo.leitner@gmail.com
[ Upstream commit 582eea230536a6f104097dd46205822005d5fe3a ]
Under certain circumstances, depending on the order of addresses on the interfaces, it could be that sctp_v[46]_get_dst() would return a dst with a mismatched struct flowi.
For example, if when walking through the bind addresses and the first one is not a match, it saves the dst as a fallback (added in 410f03831c07), but not the flowi. Then if the next one is also not a match, the previous dst will be returned but with the flowi information for the 2nd address, which is wrong.
The fix is to use a locally stored flowi that can be used for such attempts, and copy it to the parameter only in case it is a possible match, together with the corresponding dst entry.
The patch updates IPv6 code mostly just to be in sync. Even though the issue is also present there, it fallback is not expected to work with IPv6.
Fixes: 410f03831c07 ("sctp: add routing output fallback") Reported-by: Jin Meng meng.a.jin@nokia-sbell.com Signed-off-by: Marcelo Ricardo Leitner marcelo.leitner@gmail.com Tested-by: Xin Long lucien.xin@gmail.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- net/sctp/ipv6.c | 20 ++++++++++++++------ net/sctp/protocol.c | 28 +++++++++++++++++++--------- 2 files changed, 33 insertions(+), 15 deletions(-)
--- a/net/sctp/ipv6.c +++ b/net/sctp/ipv6.c @@ -234,7 +234,8 @@ static void sctp_v6_get_dst(struct sctp_ { struct sctp_association *asoc = t->asoc; struct dst_entry *dst = NULL; - struct flowi6 *fl6 = &fl->u.ip6; + struct flowi _fl; + struct flowi6 *fl6 = &_fl.u.ip6; struct sctp_bind_addr *bp; struct ipv6_pinfo *np = inet6_sk(sk); struct sctp_sockaddr_entry *laddr; @@ -244,7 +245,7 @@ static void sctp_v6_get_dst(struct sctp_ __u8 matchlen = 0; sctp_scope_t scope;
- memset(fl6, 0, sizeof(struct flowi6)); + memset(&_fl, 0, sizeof(_fl)); fl6->daddr = daddr->v6.sin6_addr; fl6->fl6_dport = daddr->v6.sin6_port; fl6->flowi6_proto = IPPROTO_SCTP; @@ -268,8 +269,11 @@ static void sctp_v6_get_dst(struct sctp_ rcu_read_unlock();
dst = ip6_dst_lookup_flow(sk, fl6, final_p); - if (!asoc || saddr) + if (!asoc || saddr) { + t->dst = dst; + memcpy(fl, &_fl, sizeof(_fl)); goto out; + }
bp = &asoc->base.bind_addr; scope = sctp_scope(daddr); @@ -292,6 +296,8 @@ static void sctp_v6_get_dst(struct sctp_ if ((laddr->a.sa.sa_family == AF_INET6) && (sctp_v6_cmp_addr(&dst_saddr, &laddr->a))) { rcu_read_unlock(); + t->dst = dst; + memcpy(fl, &_fl, sizeof(_fl)); goto out; } } @@ -330,6 +336,8 @@ static void sctp_v6_get_dst(struct sctp_ if (!IS_ERR_OR_NULL(dst)) dst_release(dst); dst = bdst; + t->dst = dst; + memcpy(fl, &_fl, sizeof(_fl)); break; }
@@ -343,6 +351,8 @@ static void sctp_v6_get_dst(struct sctp_ dst_release(dst); dst = bdst; matchlen = bmatchlen; + t->dst = dst; + memcpy(fl, &_fl, sizeof(_fl)); } rcu_read_unlock();
@@ -351,14 +361,12 @@ out: struct rt6_info *rt;
rt = (struct rt6_info *)dst; - t->dst = dst; t->dst_cookie = rt6_get_cookie(rt); pr_debug("rt6_dst:%pI6/%d rt6_src:%pI6\n", &rt->rt6i_dst.addr, rt->rt6i_dst.plen, - &fl6->saddr); + &fl->u.ip6.saddr); } else { t->dst = NULL; - pr_debug("no route\n"); } } --- a/net/sctp/protocol.c +++ b/net/sctp/protocol.c @@ -428,14 +428,15 @@ static void sctp_v4_get_dst(struct sctp_ { struct sctp_association *asoc = t->asoc; struct rtable *rt; - struct flowi4 *fl4 = &fl->u.ip4; + struct flowi _fl; + struct flowi4 *fl4 = &_fl.u.ip4; struct sctp_bind_addr *bp; struct sctp_sockaddr_entry *laddr; struct dst_entry *dst = NULL; union sctp_addr *daddr = &t->ipaddr; union sctp_addr dst_saddr;
- memset(fl4, 0x0, sizeof(struct flowi4)); + memset(&_fl, 0x0, sizeof(_fl)); fl4->daddr = daddr->v4.sin_addr.s_addr; fl4->fl4_dport = daddr->v4.sin_port; fl4->flowi4_proto = IPPROTO_SCTP; @@ -453,8 +454,11 @@ static void sctp_v4_get_dst(struct sctp_ &fl4->saddr);
rt = ip_route_output_key(sock_net(sk), fl4); - if (!IS_ERR(rt)) + if (!IS_ERR(rt)) { dst = &rt->dst; + t->dst = dst; + memcpy(fl, &_fl, sizeof(_fl)); + }
/* If there is no association or if a source address is passed, no * more validation is required. @@ -517,27 +521,33 @@ static void sctp_v4_get_dst(struct sctp_ odev = __ip_dev_find(sock_net(sk), laddr->a.v4.sin_addr.s_addr, false); if (!odev || odev->ifindex != fl4->flowi4_oif) { - if (!dst) + if (!dst) { dst = &rt->dst; - else + t->dst = dst; + memcpy(fl, &_fl, sizeof(_fl)); + } else { dst_release(&rt->dst); + } continue; }
dst_release(dst); dst = &rt->dst; + t->dst = dst; + memcpy(fl, &_fl, sizeof(_fl)); break; }
out_unlock: rcu_read_unlock(); out: - t->dst = dst; - if (dst) + if (dst) { pr_debug("rt_dst:%pI4, rt_src:%pI4\n", - &fl4->daddr, &fl4->saddr); - else + &fl->u.ip4.daddr, &fl->u.ip4.saddr); + } else { + t->dst = NULL; pr_debug("no route\n"); + } }
/* For v4, the source address is cached in the route entry(dst). So no need
From: phil.turnbull@oracle.com phil.turnbull@oracle.com
commit 4ac36a4adaf80013a60013d6f829f5863d5d0e05 upstream.
If 'tunnel' is NULL we should return -EBADF but the 'end_put_sess' path unconditionally sets 'error' back to zero. Rework the error path so it more closely matches pppol2tp_sendmsg.
Fixes: fd558d186df2 ("l2tp: Split pppol2tp patch into separate l2tp and ppp parts") Signed-off-by: Phil Turnbull phil.turnbull@oracle.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Will Deacon will@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- net/l2tp/l2tp_ppp.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-)
--- a/net/l2tp/l2tp_ppp.c +++ b/net/l2tp/l2tp_ppp.c @@ -889,10 +889,8 @@ static int pppol2tp_getname(struct socke
pls = l2tp_session_priv(session); tunnel = l2tp_sock_to_tunnel(pls->tunnel_sock); - if (tunnel == NULL) { - error = -EBADF; + if (tunnel == NULL) goto end_put_sess; - }
inet = inet_sk(tunnel->sock); if ((tunnel->version == 2) && (tunnel->sock->sk_family == AF_INET)) { @@ -970,12 +968,11 @@ static int pppol2tp_getname(struct socke }
*usockaddr_len = len; + error = 0;
sock_put(pls->tunnel_sock); end_put_sess: sock_put(sk); - error = 0; - end: return error; }
From: Shmulik Ladkani shmulik.ladkani@gmail.com
commit 0e6b5259824e97a0f7e7b450421ff12865d3b0e2 upstream.
l2tp_ip6 tunnel and session lookups were still using init_net, although the l2tp core infrastructure already supports lookups keyed by 'net'.
As a result, l2tp_ip6_recv discarded packets for tunnels/sessions created in namespaces other than the init_net.
Fix, by using dev_net(skb->dev) or sock_net(sk) where appropriate.
Signed-off-by: Shmulik Ladkani shmulik.ladkani@gmail.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Will Deacon will@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- net/l2tp/l2tp_ip6.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-)
--- a/net/l2tp/l2tp_ip6.c +++ b/net/l2tp/l2tp_ip6.c @@ -127,6 +127,7 @@ static inline struct sock *l2tp_ip6_bind */ static int l2tp_ip6_recv(struct sk_buff *skb) { + struct net *net = dev_net(skb->dev); struct sock *sk; u32 session_id; u32 tunnel_id; @@ -153,7 +154,7 @@ static int l2tp_ip6_recv(struct sk_buff }
/* Ok, this is a data packet. Lookup the session. */ - session = l2tp_session_find(&init_net, NULL, session_id); + session = l2tp_session_find(net, NULL, session_id); if (session == NULL) goto discard;
@@ -190,7 +191,7 @@ pass_up: goto discard;
tunnel_id = ntohl(*(__be32 *) &skb->data[4]); - tunnel = l2tp_tunnel_find(&init_net, tunnel_id); + tunnel = l2tp_tunnel_find(net, tunnel_id); if (tunnel) { sk = tunnel->sock; sock_hold(sk); @@ -198,7 +199,7 @@ pass_up: struct ipv6hdr *iph = ipv6_hdr(skb);
read_lock_bh(&l2tp_ip6_lock); - sk = __l2tp_ip6_bind_lookup(&init_net, &iph->daddr, + sk = __l2tp_ip6_bind_lookup(net, &iph->daddr, 0, tunnel_id); if (!sk) { read_unlock_bh(&l2tp_ip6_lock); @@ -267,6 +268,7 @@ static int l2tp_ip6_bind(struct sock *sk struct inet_sock *inet = inet_sk(sk); struct ipv6_pinfo *np = inet6_sk(sk); struct sockaddr_l2tpip6 *addr = (struct sockaddr_l2tpip6 *) uaddr; + struct net *net = sock_net(sk); __be32 v4addr = 0; int addr_type; int err; @@ -288,7 +290,7 @@ static int l2tp_ip6_bind(struct sock *sk
err = -EADDRINUSE; read_lock_bh(&l2tp_ip6_lock); - if (__l2tp_ip6_bind_lookup(&init_net, &addr->l2tp_addr, + if (__l2tp_ip6_bind_lookup(net, &addr->l2tp_addr, sk->sk_bound_dev_if, addr->l2tp_conn_id)) goto out_in_use; read_unlock_bh(&l2tp_ip6_lock); @@ -461,7 +463,7 @@ static int l2tp_ip6_backlog_recv(struct return 0;
drop: - IP_INC_STATS(&init_net, IPSTATS_MIB_INDISCARDS); + IP_INC_STATS(sock_net(sk), IPSTATS_MIB_INDISCARDS); kfree_skb(skb); return -1; }
From: Guillaume Nault g.nault@alphalink.fr
commit 61b9a047729bb230978178bca6729689d0c50ca2 upstream.
Taking a reference on sessions in l2tp_recv_common() is racy; this has to be done by the callers.
To this end, a new function is required (l2tp_session_get()) to atomically lookup a session and take a reference on it. Callers then have to manually drop this reference.
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: Will Deacon will@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- net/l2tp/l2tp_core.c | 73 +++++++++++++++++++++++++++++++++++++++++---------- net/l2tp/l2tp_core.h | 3 ++ net/l2tp/l2tp_ip.c | 17 ++++++++--- net/l2tp/l2tp_ip6.c | 18 +++++++++--- 4 files changed, 88 insertions(+), 23 deletions(-)
--- a/net/l2tp/l2tp_core.c +++ b/net/l2tp/l2tp_core.c @@ -277,6 +277,55 @@ struct l2tp_session *l2tp_session_find(s } EXPORT_SYMBOL_GPL(l2tp_session_find);
+/* Like l2tp_session_find() but takes a reference on the returned session. + * Optionally calls session->ref() too if do_ref is true. + */ +struct l2tp_session *l2tp_session_get(struct net *net, + struct l2tp_tunnel *tunnel, + u32 session_id, bool do_ref) +{ + struct hlist_head *session_list; + struct l2tp_session *session; + + if (!tunnel) { + struct l2tp_net *pn = l2tp_pernet(net); + + session_list = l2tp_session_id_hash_2(pn, session_id); + + rcu_read_lock_bh(); + hlist_for_each_entry_rcu(session, session_list, global_hlist) { + if (session->session_id == session_id) { + l2tp_session_inc_refcount(session); + if (do_ref && session->ref) + session->ref(session); + rcu_read_unlock_bh(); + + return session; + } + } + rcu_read_unlock_bh(); + + return NULL; + } + + session_list = l2tp_session_id_hash(tunnel, session_id); + read_lock_bh(&tunnel->hlist_lock); + hlist_for_each_entry(session, session_list, hlist) { + if (session->session_id == session_id) { + l2tp_session_inc_refcount(session); + if (do_ref && session->ref) + session->ref(session); + read_unlock_bh(&tunnel->hlist_lock); + + return session; + } + } + read_unlock_bh(&tunnel->hlist_lock); + + return NULL; +} +EXPORT_SYMBOL_GPL(l2tp_session_get); + struct l2tp_session *l2tp_session_get_nth(struct l2tp_tunnel *tunnel, int nth, bool do_ref) { @@ -636,6 +685,9 @@ discard: * a data (not control) frame before coming here. Fields up to the * session-id have already been parsed and ptr points to the data * after the session-id. + * + * session->ref() must have been called prior to l2tp_recv_common(). + * session->deref() will be called automatically after skb is processed. */ void l2tp_recv_common(struct l2tp_session *session, struct sk_buff *skb, unsigned char *ptr, unsigned char *optr, u16 hdrflags, @@ -645,14 +697,6 @@ void l2tp_recv_common(struct l2tp_sessio int offset; u32 ns, nr;
- /* The ref count is increased since we now hold a pointer to - * the session. Take care to decrement the refcnt when exiting - * this function from now on... - */ - l2tp_session_inc_refcount(session); - if (session->ref) - (*session->ref)(session); - /* Parse and check optional cookie */ if (session->peer_cookie_len > 0) { if (memcmp(ptr, &session->peer_cookie[0], session->peer_cookie_len)) { @@ -803,8 +847,6 @@ void l2tp_recv_common(struct l2tp_sessio /* Try to dequeue as many skbs from reorder_q as we can. */ l2tp_recv_dequeue(session);
- l2tp_session_dec_refcount(session); - return;
discard: @@ -813,8 +855,6 @@ discard:
if (session->deref) (*session->deref)(session); - - l2tp_session_dec_refcount(session); } EXPORT_SYMBOL(l2tp_recv_common);
@@ -921,8 +961,14 @@ static int l2tp_udp_recv_core(struct l2t }
/* Find the session context */ - session = l2tp_session_find(tunnel->l2tp_net, tunnel, session_id); + session = l2tp_session_get(tunnel->l2tp_net, tunnel, session_id, true); if (!session || !session->recv_skb) { + if (session) { + if (session->deref) + session->deref(session); + l2tp_session_dec_refcount(session); + } + /* Not found? Pass to userspace to deal with */ l2tp_info(tunnel, L2TP_MSG_DATA, "%s: no session found (%u/%u). Passing up.\n", @@ -935,6 +981,7 @@ static int l2tp_udp_recv_core(struct l2t goto error;
l2tp_recv_common(session, skb, ptr, optr, hdrflags, length, payload_hook); + l2tp_session_dec_refcount(session);
return 0;
--- a/net/l2tp/l2tp_core.h +++ b/net/l2tp/l2tp_core.h @@ -243,6 +243,9 @@ out: return tunnel; }
+struct l2tp_session *l2tp_session_get(struct net *net, + struct l2tp_tunnel *tunnel, + u32 session_id, bool do_ref); struct l2tp_session *l2tp_session_find(struct net *net, struct l2tp_tunnel *tunnel, u32 session_id); --- a/net/l2tp/l2tp_ip.c +++ b/net/l2tp/l2tp_ip.c @@ -142,19 +142,19 @@ static int l2tp_ip_recv(struct sk_buff * }
/* Ok, this is a data packet. Lookup the session. */ - session = l2tp_session_find(net, NULL, session_id); - if (session == NULL) + session = l2tp_session_get(net, NULL, session_id, true); + if (!session) goto discard;
tunnel = session->tunnel; - if (tunnel == NULL) - goto discard; + if (!tunnel) + goto discard_sess;
/* Trace packet contents, if enabled */ if (tunnel->debug & L2TP_MSG_DATA) { length = min(32u, skb->len); if (!pskb_may_pull(skb, length)) - goto discard; + goto discard_sess;
/* Point to L2TP header */ optr = ptr = skb->data; @@ -167,6 +167,7 @@ static int l2tp_ip_recv(struct sk_buff * goto discard;
l2tp_recv_common(session, skb, ptr, optr, 0, skb->len, tunnel->recv_payload_hook); + l2tp_session_dec_refcount(session);
return 0;
@@ -204,6 +205,12 @@ pass_up:
return sk_receive_skb(sk, skb, 1);
+discard_sess: + if (session->deref) + session->deref(session); + l2tp_session_dec_refcount(session); + goto discard; + discard_put: sock_put(sk);
--- a/net/l2tp/l2tp_ip6.c +++ b/net/l2tp/l2tp_ip6.c @@ -154,19 +154,19 @@ static int l2tp_ip6_recv(struct sk_buff }
/* Ok, this is a data packet. Lookup the session. */ - session = l2tp_session_find(net, NULL, session_id); - if (session == NULL) + session = l2tp_session_get(net, NULL, session_id, true); + if (!session) goto discard;
tunnel = session->tunnel; - if (tunnel == NULL) - goto discard; + if (!tunnel) + goto discard_sess;
/* Trace packet contents, if enabled */ if (tunnel->debug & L2TP_MSG_DATA) { length = min(32u, skb->len); if (!pskb_may_pull(skb, length)) - goto discard; + goto discard_sess;
/* Point to L2TP header */ optr = ptr = skb->data; @@ -180,6 +180,8 @@ static int l2tp_ip6_recv(struct sk_buff
l2tp_recv_common(session, skb, ptr, optr, 0, skb->len, tunnel->recv_payload_hook); + l2tp_session_dec_refcount(session); + return 0;
pass_up: @@ -217,6 +219,12 @@ pass_up:
return sk_receive_skb(sk, skb, 1);
+discard_sess: + if (session->deref) + session->deref(session); + l2tp_session_dec_refcount(session); + goto discard; + discard_put: sock_put(sk);
From: Guillaume Nault g.nault@alphalink.fr
commit 57377d63547861919ee634b845c7caa38de4a452 upstream.
Holding a reference on session is required before calling pppol2tp_session_ioctl(). The session could get freed while processing the ioctl otherwise. Since pppol2tp_session_ioctl() uses the session's socket, we also need to take a reference on it in l2tp_session_get().
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: Will Deacon will@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- net/l2tp/l2tp_ppp.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-)
--- a/net/l2tp/l2tp_ppp.c +++ b/net/l2tp/l2tp_ppp.c @@ -1168,11 +1168,18 @@ static int pppol2tp_tunnel_ioctl(struct if (stats.session_id != 0) { /* resend to session ioctl handler */ struct l2tp_session *session = - l2tp_session_find(sock_net(sk), tunnel, stats.session_id); - if (session != NULL) - err = pppol2tp_session_ioctl(session, cmd, arg); - else + l2tp_session_get(sock_net(sk), tunnel, + stats.session_id, true); + + if (session) { + err = pppol2tp_session_ioctl(session, cmd, + arg); + if (session->deref) + session->deref(session); + l2tp_session_dec_refcount(session); + } else { err = -EBADR; + } break; } #ifdef CONFIG_XFRM
From: Guillaume Nault g.nault@alphalink.fr
commit dbdbc73b44782e22b3b4b6e8b51e7a3d245f3086 upstream.
l2tp_session_create() relies on its caller for checking for duplicate sessions. This is racy since a session can be concurrently inserted after the caller's verification.
Fix this by letting l2tp_session_create() verify sessions uniqueness upon insertion. Callers need to be adapted to check for l2tp_session_create()'s return code instead of calling l2tp_session_find().
pppol2tp_connect() is a bit special because it has to work on existing sessions (if they're not connected) or to create a new session if none is found. When acting on a preexisting session, a reference must be held or it could go away on us. So we have to use l2tp_session_get() instead of l2tp_session_find() and drop the reference before exiting.
Fixes: d9e31d17ceba ("l2tp: Add L2TP ethernet pseudowire support") 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: Will Deacon will@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- net/l2tp/l2tp_core.c | 70 ++++++++++++++++++++++++++++++++++++++------------- net/l2tp/l2tp_eth.c | 10 +------ net/l2tp/l2tp_ppp.c | 60 +++++++++++++++++++++---------------------- 3 files changed, 84 insertions(+), 56 deletions(-)
--- a/net/l2tp/l2tp_core.c +++ b/net/l2tp/l2tp_core.c @@ -377,6 +377,48 @@ struct l2tp_session *l2tp_session_find_b } EXPORT_SYMBOL_GPL(l2tp_session_find_by_ifname);
+static int l2tp_session_add_to_tunnel(struct l2tp_tunnel *tunnel, + struct l2tp_session *session) +{ + struct l2tp_session *session_walk; + struct hlist_head *g_head; + struct hlist_head *head; + struct l2tp_net *pn; + + head = l2tp_session_id_hash(tunnel, session->session_id); + + write_lock_bh(&tunnel->hlist_lock); + hlist_for_each_entry(session_walk, head, hlist) + if (session_walk->session_id == session->session_id) + goto exist; + + if (tunnel->version == L2TP_HDR_VER_3) { + pn = l2tp_pernet(tunnel->l2tp_net); + g_head = l2tp_session_id_hash_2(l2tp_pernet(tunnel->l2tp_net), + session->session_id); + + spin_lock_bh(&pn->l2tp_session_hlist_lock); + hlist_for_each_entry(session_walk, g_head, global_hlist) + if (session_walk->session_id == session->session_id) + goto exist_glob; + + hlist_add_head_rcu(&session->global_hlist, g_head); + spin_unlock_bh(&pn->l2tp_session_hlist_lock); + } + + hlist_add_head(&session->hlist, head); + write_unlock_bh(&tunnel->hlist_lock); + + return 0; + +exist_glob: + spin_unlock_bh(&pn->l2tp_session_hlist_lock); +exist: + write_unlock_bh(&tunnel->hlist_lock); + + return -EEXIST; +} + /* Lookup a tunnel by id */ struct l2tp_tunnel *l2tp_tunnel_find(struct net *net, u32 tunnel_id) @@ -1792,6 +1834,7 @@ EXPORT_SYMBOL_GPL(l2tp_session_set_heade struct l2tp_session *l2tp_session_create(int priv_size, struct l2tp_tunnel *tunnel, u32 session_id, u32 peer_session_id, struct l2tp_session_cfg *cfg) { struct l2tp_session *session; + int err;
session = kzalloc(sizeof(struct l2tp_session) + priv_size, GFP_KERNEL); if (session != NULL) { @@ -1847,6 +1890,13 @@ struct l2tp_session *l2tp_session_create
l2tp_session_set_header_len(session, tunnel->version);
+ err = l2tp_session_add_to_tunnel(tunnel, session); + if (err) { + kfree(session); + + return ERR_PTR(err); + } + /* Bump the reference count. The session context is deleted * only when this drops to zero. */ @@ -1856,28 +1906,14 @@ struct l2tp_session *l2tp_session_create /* Ensure tunnel socket isn't deleted */ sock_hold(tunnel->sock);
- /* Add session to the tunnel's hash list */ - write_lock_bh(&tunnel->hlist_lock); - hlist_add_head(&session->hlist, - l2tp_session_id_hash(tunnel, session_id)); - write_unlock_bh(&tunnel->hlist_lock); - - /* And to the global session list if L2TPv3 */ - if (tunnel->version != L2TP_HDR_VER_2) { - struct l2tp_net *pn = l2tp_pernet(tunnel->l2tp_net); - - spin_lock_bh(&pn->l2tp_session_hlist_lock); - hlist_add_head_rcu(&session->global_hlist, - l2tp_session_id_hash_2(pn, session_id)); - spin_unlock_bh(&pn->l2tp_session_hlist_lock); - } - /* Ignore management session in session count value */ if (session->session_id != 0) atomic_inc(&l2tp_session_count); + + return session; }
- return session; + return ERR_PTR(-ENOMEM); } EXPORT_SYMBOL_GPL(l2tp_session_create);
--- a/net/l2tp/l2tp_eth.c +++ b/net/l2tp/l2tp_eth.c @@ -223,12 +223,6 @@ static int l2tp_eth_create(struct net *n goto out; }
- session = l2tp_session_find(net, tunnel, session_id); - if (session) { - rc = -EEXIST; - goto out; - } - if (cfg->ifname) { dev = dev_get_by_name(net, cfg->ifname); if (dev) { @@ -242,8 +236,8 @@ static int l2tp_eth_create(struct net *n
session = l2tp_session_create(sizeof(*spriv), tunnel, session_id, peer_session_id, cfg); - if (!session) { - rc = -ENOMEM; + if (IS_ERR(session)) { + rc = PTR_ERR(session); goto out; }
--- a/net/l2tp/l2tp_ppp.c +++ b/net/l2tp/l2tp_ppp.c @@ -600,6 +600,7 @@ static int pppol2tp_connect(struct socke int error = 0; u32 tunnel_id, peer_tunnel_id; u32 session_id, peer_session_id; + bool drop_refcnt = false; int ver = 2; int fd;
@@ -708,36 +709,36 @@ static int pppol2tp_connect(struct socke if (tunnel->peer_tunnel_id == 0) tunnel->peer_tunnel_id = peer_tunnel_id;
- /* Create session if it doesn't already exist. We handle the - * case where a session was previously created by the netlink - * interface by checking that the session doesn't already have - * a socket and its tunnel socket are what we expect. If any - * of those checks fail, return EEXIST to the caller. - */ - session = l2tp_session_find(sock_net(sk), tunnel, session_id); - if (session == NULL) { - /* Default MTU must allow space for UDP/L2TP/PPP - * headers. + session = l2tp_session_get(sock_net(sk), tunnel, session_id, false); + if (session) { + drop_refcnt = true; + ps = l2tp_session_priv(session); + + /* Using a pre-existing session is fine as long as it hasn't + * been connected yet. */ - cfg.mtu = cfg.mru = 1500 - PPPOL2TP_HEADER_OVERHEAD; + if (ps->sock) { + error = -EEXIST; + goto end; + }
- /* Allocate and initialize a new session context. */ - session = l2tp_session_create(sizeof(struct pppol2tp_session), - tunnel, session_id, - peer_session_id, &cfg); - if (session == NULL) { - error = -ENOMEM; + /* consistency checks */ + if (ps->tunnel_sock != tunnel->sock) { + error = -EEXIST; goto end; } } else { - ps = l2tp_session_priv(session); - error = -EEXIST; - if (ps->sock != NULL) - goto end; + /* Default MTU must allow space for UDP/L2TP/PPP headers */ + cfg.mtu = 1500 - PPPOL2TP_HEADER_OVERHEAD; + cfg.mru = cfg.mtu;
- /* consistency checks */ - if (ps->tunnel_sock != tunnel->sock) + session = l2tp_session_create(sizeof(struct pppol2tp_session), + tunnel, session_id, + peer_session_id, &cfg); + if (IS_ERR(session)) { + error = PTR_ERR(session); goto end; + } }
/* Associate session with its PPPoL2TP socket */ @@ -802,6 +803,8 @@ out_no_ppp: session->name);
end: + if (drop_refcnt) + l2tp_session_dec_refcount(session); release_sock(sk);
return error; @@ -829,12 +832,6 @@ static int pppol2tp_session_create(struc if (tunnel->sock == NULL) goto out;
- /* Check that this session doesn't already exist */ - error = -EEXIST; - session = l2tp_session_find(net, tunnel, session_id); - if (session != NULL) - goto out; - /* Default MTU values. */ if (cfg->mtu == 0) cfg->mtu = 1500 - PPPOL2TP_HEADER_OVERHEAD; @@ -842,12 +839,13 @@ static int pppol2tp_session_create(struc cfg->mru = cfg->mtu;
/* Allocate and initialize a new session context. */ - error = -ENOMEM; session = l2tp_session_create(sizeof(struct pppol2tp_session), tunnel, session_id, peer_session_id, cfg); - if (session == NULL) + if (IS_ERR(session)) { + error = PTR_ERR(session); goto out; + }
ps = l2tp_session_priv(session); ps->tunnel_sock = tunnel->sock;
From: Gao Feng fgao@ikuai8.com
commit 54c151d9ed1321e6e623c80ffe42cd2eb1571744 upstream.
Use PPP_ALLSTATIONS, PPP_UI, and SEND_SHUTDOWN instead of 0xff, 0x03, and 2 separately.
Signed-off-by: Gao Feng fgao@ikuai8.com Acked-by: Guillaume Nault g.nault@alphalink.fr Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Will Deacon will@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- net/l2tp/l2tp_ppp.c | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-)
--- a/net/l2tp/l2tp_ppp.c +++ b/net/l2tp/l2tp_ppp.c @@ -177,7 +177,7 @@ static int pppol2tp_recv_payload_hook(st if (!pskb_may_pull(skb, 2)) return 1;
- if ((skb->data[0] == 0xff) && (skb->data[1] == 0x03)) + if ((skb->data[0] == PPP_ALLSTATIONS) && (skb->data[1] == PPP_UI)) skb_pull(skb, 2);
return 0; @@ -297,7 +297,6 @@ static void pppol2tp_session_sock_put(st static int pppol2tp_sendmsg(struct socket *sock, struct msghdr *m, size_t total_len) { - static const unsigned char ppph[2] = { 0xff, 0x03 }; struct sock *sk = sock->sk; struct sk_buff *skb; int error; @@ -327,7 +326,7 @@ static int pppol2tp_sendmsg(struct socke error = -ENOMEM; skb = sock_wmalloc(sk, NET_SKB_PAD + sizeof(struct iphdr) + uhlen + session->hdr_len + - sizeof(ppph) + total_len, + 2 + total_len, /* 2 bytes for PPP_ALLSTATIONS & PPP_UI */ 0, GFP_KERNEL); if (!skb) goto error_put_sess_tun; @@ -340,8 +339,8 @@ static int pppol2tp_sendmsg(struct socke skb_reserve(skb, uhlen);
/* Add PPP header */ - skb->data[0] = ppph[0]; - skb->data[1] = ppph[1]; + skb->data[0] = PPP_ALLSTATIONS; + skb->data[1] = PPP_UI; skb_put(skb, 2);
/* Copy user data into skb */ @@ -384,7 +383,6 @@ error: */ static int pppol2tp_xmit(struct ppp_channel *chan, struct sk_buff *skb) { - static const u8 ppph[2] = { 0xff, 0x03 }; struct sock *sk = (struct sock *) chan->private; struct sock *sk_tun; struct l2tp_session *session; @@ -413,14 +411,14 @@ static int pppol2tp_xmit(struct ppp_chan sizeof(struct iphdr) + /* IP header */ uhlen + /* UDP header (if L2TP_ENCAPTYPE_UDP) */ session->hdr_len + /* L2TP header */ - sizeof(ppph); /* PPP header */ + 2; /* 2 bytes for PPP_ALLSTATIONS & PPP_UI */ if (skb_cow_head(skb, headroom)) goto abort_put_sess_tun;
/* Setup PPP header */ - __skb_push(skb, sizeof(ppph)); - skb->data[0] = ppph[0]; - skb->data[1] = ppph[1]; + __skb_push(skb, 2); + skb->data[0] = PPP_ALLSTATIONS; + skb->data[1] = PPP_UI;
local_bh_disable(); l2tp_xmit_skb(session, skb, session->hdr_len); @@ -455,7 +453,7 @@ static void pppol2tp_session_close(struc BUG_ON(session->magic != L2TP_SESSION_MAGIC);
if (sock) { - inet_shutdown(sock, 2); + inet_shutdown(sock, SEND_SHUTDOWN); /* Don't let the session go away before our socket does */ l2tp_session_inc_refcount(session); }
From: Guillaume Nault g.nault@alphalink.fr
commit cdd10c9627496ad25c87ce6394e29752253c69d3 upstream.
If l2tp_tunnel_delete() or l2tp_tunnel_closeall() deletes a session right after pppol2tp_release() orphaned its socket, then the 'sock' variable of the pppol2tp_session_close() callback is NULL. Yet the session is still used by pppol2tp_release().
Therefore we need to take an extra reference in any case, to prevent l2tp_tunnel_delete() or l2tp_tunnel_closeall() from freeing the session.
Since the pppol2tp_session_close() callback is only set if the session is associated to a PPPOL2TP socket and that both l2tp_tunnel_delete() and l2tp_tunnel_closeall() hold the PPPOL2TP socket before calling pppol2tp_session_close(), we're sure that pppol2tp_session_close() and pppol2tp_session_destruct() are paired and called in the right order. So the reference taken by the former will be released by the later.
Signed-off-by: Guillaume Nault g.nault@alphalink.fr Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Will Deacon will@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- net/l2tp/l2tp_ppp.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
--- a/net/l2tp/l2tp_ppp.c +++ b/net/l2tp/l2tp_ppp.c @@ -452,11 +452,11 @@ static void pppol2tp_session_close(struc
BUG_ON(session->magic != L2TP_SESSION_MAGIC);
- if (sock) { + if (sock) inet_shutdown(sock, SEND_SHUTDOWN); - /* Don't let the session go away before our socket does */ - l2tp_session_inc_refcount(session); - } + + /* Don't let the session go away before our socket does */ + l2tp_session_inc_refcount(session); }
/* Really kill the session socket. (Called from sock_put() if
From: Guillaume Nault g.nault@alphalink.fr
commit b228a94066406b6c456321d69643b0d7ce11cfa6 upstream.
There are several ways to remove L2TP sessions:
* deleting a session explicitly using the netlink interface (with L2TP_CMD_SESSION_DELETE), * deleting the session's parent tunnel (either by closing the tunnel's file descriptor or using the netlink interface), * closing the PPPOL2TP file descriptor of a PPP pseudo-wire.
In some cases, when these methods are used concurrently on the same session, the session can be removed twice, leading to use-after-free bugs.
This patch adds a 'dead' flag, used by l2tp_session_delete() and l2tp_tunnel_closeall() to prevent them from stepping on each other's toes.
The session deletion path used when closing a PPPOL2TP file descriptor doesn't need to be adapted. It already has to ensure that a session remains valid for the lifetime of its PPPOL2TP file descriptor. So it takes an extra reference on the session in the ->session_close() callback (pppol2tp_session_close()), which is eventually dropped in the ->sk_destruct() callback of the PPPOL2TP socket (pppol2tp_session_destruct()). Still, __l2tp_session_unhash() and l2tp_session_queue_purge() can be called twice and even concurrently for a given session, but thanks to proper locking and re-initialisation of list fields, this is not an issue.
Signed-off-by: Guillaume Nault g.nault@alphalink.fr Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Will Deacon will@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- net/l2tp/l2tp_core.c | 6 ++++++ net/l2tp/l2tp_core.h | 1 + 2 files changed, 7 insertions(+)
--- a/net/l2tp/l2tp_core.c +++ b/net/l2tp/l2tp_core.c @@ -1351,6 +1351,9 @@ again:
hlist_del_init(&session->hlist);
+ if (test_and_set_bit(0, &session->dead)) + goto again; + if (session->ref != NULL) (*session->ref)(session);
@@ -1799,6 +1802,9 @@ EXPORT_SYMBOL_GPL(__l2tp_session_unhash) */ int l2tp_session_delete(struct l2tp_session *session) { + if (test_and_set_bit(0, &session->dead)) + return 0; + if (session->ref) (*session->ref)(session); __l2tp_session_unhash(session); --- a/net/l2tp/l2tp_core.h +++ b/net/l2tp/l2tp_core.h @@ -85,6 +85,7 @@ struct l2tp_session_cfg { struct l2tp_session { int magic; /* should be * L2TP_SESSION_MAGIC */ + long dead;
struct l2tp_tunnel *tunnel; /* back pointer to tunnel * context */
From: Krzysztof Opasiak k.opasiak@samsung.com
commit d4529f9be1d72919f75f76f31773c4e98d03ce6b upstream.
This descriptor is never used. Currently device qualifier descriptor is generated by compossite code so no need to keep it in function file.
Signed-off-by: Krzysztof Opasiak k.opasiak@samsung.com Signed-off-by: Krzysztof Opasiak kopasiak90@gmail.com Signed-off-by: Felipe Balbi felipe.balbi@linux.intel.com Cc: Nick Desaulniers ndesaulniers@google.com Cc: Nathan Chancellor natechancellor@gmail.com Cc: kbuild test robot lkp@intel.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/usb/gadget/function/f_uac2.c | 12 ------------ 1 file changed, 12 deletions(-)
--- a/drivers/usb/gadget/function/f_uac2.c +++ b/drivers/usb/gadget/function/f_uac2.c @@ -598,18 +598,6 @@ static struct usb_gadget_strings *fn_str NULL, };
-static struct usb_qualifier_descriptor devqual_desc = { - .bLength = sizeof devqual_desc, - .bDescriptorType = USB_DT_DEVICE_QUALIFIER, - - .bcdUSB = cpu_to_le16(0x200), - .bDeviceClass = USB_CLASS_MISC, - .bDeviceSubClass = 0x02, - .bDeviceProtocol = 0x01, - .bNumConfigurations = 1, - .bRESERVED = 0, -}; - static struct usb_interface_assoc_descriptor iad_desc = { .bLength = sizeof iad_desc, .bDescriptorType = USB_DT_INTERFACE_ASSOCIATION,
From: Krzysztof Opasiak k.opasiak@samsung.com
commit e5a89162161d498170e7e39e6cfd2f71458c2b00 upstream.
This descriptor is never used. Currently device qualifier descriptor is generated by compossite code, so no need to keep it in function file.
Signed-off-by: Krzysztof Opasiak k.opasiak@samsung.com Signed-off-by: Krzysztof Opasiak kopasiak90@gmail.com Signed-off-by: Felipe Balbi felipe.balbi@linux.intel.com Cc: Nick Desaulniers ndesaulniers@google.com Cc: Nathan Chancellor natechancellor@gmail.com Cc: kbuild test robot lkp@intel.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/usb/gadget/function/f_printer.c | 8 -------- 1 file changed, 8 deletions(-)
--- a/drivers/usb/gadget/function/f_printer.c +++ b/drivers/usb/gadget/function/f_printer.c @@ -161,14 +161,6 @@ static struct usb_endpoint_descriptor hs .wMaxPacketSize = cpu_to_le16(512) };
-static struct usb_qualifier_descriptor dev_qualifier = { - .bLength = sizeof(dev_qualifier), - .bDescriptorType = USB_DT_DEVICE_QUALIFIER, - .bcdUSB = cpu_to_le16(0x0200), - .bDeviceClass = USB_CLASS_PRINTER, - .bNumConfigurations = 1 -}; - static struct usb_descriptor_header *hs_printer_function[] = { (struct usb_descriptor_header *) &intf_desc, (struct usb_descriptor_header *) &hs_ep_in_desc,
From: Daniel Jordan daniel.m.jordan@oracle.com
commit 38228e8848cd7dd86ccb90406af32de0cad24be3 upstream.
lockdep complains when padata's paths to update cpumasks via CPU hotplug and sysfs are both taken:
# echo 0 > /sys/devices/system/cpu/cpu1/online # echo ff > /sys/kernel/pcrypt/pencrypt/parallel_cpumask
====================================================== WARNING: possible circular locking dependency detected 5.4.0-rc8-padata-cpuhp-v3+ #1 Not tainted ------------------------------------------------------ bash/205 is trying to acquire lock: ffffffff8286bcd0 (cpu_hotplug_lock.rw_sem){++++}, at: padata_set_cpumask+0x2b/0x120
but task is already holding lock: ffff8880001abfa0 (&pinst->lock){+.+.}, at: padata_set_cpumask+0x26/0x120
which lock already depends on the new lock.
padata doesn't take cpu_hotplug_lock and pinst->lock in a consistent order. Which should be first? CPU hotplug calls into padata with cpu_hotplug_lock already held, so it should have priority.
Fixes: 6751fb3c0e0c ("padata: Use get_online_cpus/put_online_cpus") Signed-off-by: Daniel Jordan daniel.m.jordan@oracle.com Cc: Eric Biggers ebiggers@kernel.org Cc: Herbert Xu herbert@gondor.apana.org.au Cc: Steffen Klassert steffen.klassert@secunet.com Cc: linux-crypto@vger.kernel.org Cc: linux-kernel@vger.kernel.org Signed-off-by: Herbert Xu herbert@gondor.apana.org.au Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- kernel/padata.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
--- a/kernel/padata.c +++ b/kernel/padata.c @@ -640,8 +640,8 @@ int padata_set_cpumask(struct padata_ins struct cpumask *serial_mask, *parallel_mask; int err = -EINVAL;
- mutex_lock(&pinst->lock); get_online_cpus(); + mutex_lock(&pinst->lock);
switch (cpumask_type) { case PADATA_CPU_PARALLEL: @@ -659,8 +659,8 @@ int padata_set_cpumask(struct padata_ins err = __padata_set_cpumasks(pinst, parallel_mask, serial_mask);
out: - put_online_cpus(); mutex_unlock(&pinst->lock); + put_online_cpus();
return err; }
From: Randy Dunlap rdunlap@infradead.org
commit aa9f7d5172fac9bf1f09e678c35e287a40a7b7dd upstream.
Using an empty (malformed) nodelist that is not caught during mount option parsing leads to a stack-out-of-bounds access.
The option string that was used was: "mpol=prefer:,". However, MPOL_PREFERRED requires a single node number, which is not being provided here.
Add a check that 'nodes' is not empty after parsing for MPOL_PREFERRED's nodeid.
Fixes: 095f1fc4ebf3 ("mempolicy: rework shmem mpol parsing and display") Reported-by: Entropy Moe 3ntr0py1337@gmail.com Reported-by: syzbot+b055b1a6b2b958707a21@syzkaller.appspotmail.com Signed-off-by: Randy Dunlap rdunlap@infradead.org Signed-off-by: Andrew Morton akpm@linux-foundation.org Tested-by: syzbot+b055b1a6b2b958707a21@syzkaller.appspotmail.com Cc: Lee Schermerhorn lee.schermerhorn@hp.com Link: http://lkml.kernel.org/r/89526377-7eb6-b662-e1d8-4430928abde9@infradead.org Signed-off-by: Linus Torvalds torvalds@linux-foundation.org Cc: Guenter Roeck linux@roeck-us.net Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- mm/mempolicy.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
--- a/mm/mempolicy.c +++ b/mm/mempolicy.c @@ -2725,7 +2725,9 @@ int mpol_parse_str(char *str, struct mem switch (mode) { case MPOL_PREFERRED: /* - * Insist on a nodelist of one node only + * Insist on a nodelist of one node only, although later + * we use first_node(nodes) to grab a single node, so here + * nodelist (or nodes) cannot be empty. */ if (nodelist) { char *rest = nodelist; @@ -2733,6 +2735,8 @@ int mpol_parse_str(char *str, struct mem rest++; if (*rest) goto out; + if (nodes_empty(nodes)) + goto out; } break; case MPOL_INTERLEAVE:
From: Jisheng Zhang Jisheng.Zhang@synaptics.com
[ Upstream commit 3e1221acf6a8f8595b5ce354bab4327a69d54d18 ]
Commit 9463c4455900 ("net: stmmac: dwmac1000: Clear unused address entries") cleared the unused mac address entries, but introduced an out-of bounds mac address register programming bug -- After setting the secondary unicast mac addresses, the "reg" value has reached netdev_uc_count() + 1, thus we should only clear address entries if (addr < perfect_addr_number)
Fixes: 9463c4455900 ("net: stmmac: dwmac1000: Clear unused address entries") Signed-off-by: Jisheng Zhang Jisheng.Zhang@synaptics.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c @@ -188,7 +188,7 @@ static void dwmac1000_set_filter(struct reg++; }
- while (reg <= perfect_addr_number) { + while (reg < perfect_addr_number) { writel(0, ioaddr + GMAC_ADDR_HIGH(reg)); writel(0, ioaddr + GMAC_ADDR_LOW(reg)); reg++;
From: Richard Palethorpe rpalethorpe@suse.com
[ Upstream commit b9258a2cece4ec1f020715fe3554bc2e360f6264 ]
struct can_frame contains some padding which is not explicitly zeroed in slc_bump. This uninitialized data will then be transmitted if the stack initialization hardening feature is not enabled (CONFIG_INIT_STACK_ALL).
This commit just zeroes the whole struct including the padding.
Signed-off-by: Richard Palethorpe rpalethorpe@suse.com Fixes: a1044e36e457 ("can: add slcan driver for serial/USB-serial CAN adapters") Reviewed-by: Kees Cook keescook@chromium.org Cc: linux-can@vger.kernel.org Cc: netdev@vger.kernel.org Cc: security@kernel.org Cc: wg@grandegger.com Cc: mkl@pengutronix.de Cc: davem@davemloft.net Acked-by: Marc Kleine-Budde mkl@pengutronix.de Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/net/can/slcan.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-)
--- a/drivers/net/can/slcan.c +++ b/drivers/net/can/slcan.c @@ -147,7 +147,7 @@ static void slc_bump(struct slcan *sl) u32 tmpid; char *cmd = sl->rbuff;
- cf.can_id = 0; + memset(&cf, 0, sizeof(cf));
switch (*cmd) { case 'r': @@ -186,8 +186,6 @@ static void slc_bump(struct slcan *sl) else return;
- *(u64 *) (&cf.data) = 0; /* clear payload */ - /* RTR frames may have a dlc > 0 but they never have any data bytes */ if (!(cf.can_id & CAN_RTR_FLAG)) { for (i = 0; i < cf.can_dlc; i++) {
From: Jason A. Donenfeld Jason@zx2c4.com
commit 69efea712f5b0489e67d07565aad5c94e09a3e52 upstream.
It turns out that RDRAND is pretty slow. Comparing these two constructions:
for (i = 0; i < CHACHA_BLOCK_SIZE; i += sizeof(ret)) arch_get_random_long(&ret);
and
long buf[CHACHA_BLOCK_SIZE / sizeof(long)]; extract_crng((u8 *)buf);
it amortizes out to 352 cycles per long for the top one and 107 cycles per long for the bottom one, on Coffee Lake Refresh, Intel Core i9-9880H.
And importantly, the top one has the drawback of not benefiting from the real rng, whereas the bottom one has all the nice benefits of using our own chacha rng. As get_random_u{32,64} gets used in more places (perhaps beyond what it was originally intended for when it was introduced as get_random_{int,long} back in the md5 monstrosity era), it seems like it might be a good thing to strengthen its posture a tiny bit. Doing this should only be stronger and not any weaker because that pool is already initialized with a bunch of rdrand data (when available). This way, we get the benefits of the hardware rng as well as our own rng.
Another benefit of this is that we no longer hit pitfalls of the recent stream of AMD bugs in RDRAND. One often used code pattern for various things is:
do { val = get_random_u32(); } while (hash_table_contains_key(val));
That recent AMD bug rendered that pattern useless, whereas we're really very certain that chacha20 output will give pretty distributed numbers, no matter what.
So, this simplification seems better both from a security perspective and from a performance perspective.
Signed-off-by: Jason A. Donenfeld Jason@zx2c4.com Reviewed-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Link: https://lore.kernel.org/r/20200221201037.30231-1-Jason@zx2c4.com Signed-off-by: Theodore Ts'o tytso@mit.edu Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/char/random.c | 6 ------ 1 file changed, 6 deletions(-)
--- a/drivers/char/random.c +++ b/drivers/char/random.c @@ -1824,9 +1824,6 @@ unsigned int get_random_int(void) __u32 *hash; unsigned int ret;
- if (arch_get_random_int(&ret)) - return ret; - hash = get_cpu_var(get_random_int_hash);
hash[0] += current->pid + jiffies + random_get_entropy(); @@ -1846,9 +1843,6 @@ unsigned long get_random_long(void) __u32 *hash; unsigned long ret;
- if (arch_get_random_long(&ret)) - return ret; - hash = get_cpu_var(get_random_int_hash);
hash[0] += current->pid + jiffies + random_get_entropy();
From: David Ahern dsahern@kernel.org
commit 4054ab64e29bb05b3dfe758fff3c38a74ba753bb upstream.
A recent change to the netlink code: 6e237d099fac ("netlink: Relax attr validation for fixed length types") logs a warning when programs send messages with invalid attributes (e.g., wrong length for a u32). Yafang reported this error message for tools/accounting/getdelays.c.
send_cmd() is wrongly adding 1 to the attribute length. As noted in include/uapi/linux/netlink.h nla_len should be NLA_HDRLEN + payload length, so drop the +1.
Fixes: 9e06d3f9f6b1 ("per task delay accounting taskstats interface: documentation fix") Reported-by: Yafang Shao laoar.shao@gmail.com Signed-off-by: David Ahern dsahern@kernel.org Signed-off-by: Andrew Morton akpm@linux-foundation.org Tested-by: Yafang Shao laoar.shao@gmail.com Cc: Johannes Berg johannes@sipsolutions.net Cc: Shailabh Nagar nagar@watson.ibm.com Cc: stable@vger.kernel.org Link: http://lkml.kernel.org/r/20200327173111.63922-1-dsahern@kernel.org Signed-off-by: Linus Torvalds torvalds@linux-foundation.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- Documentation/accounting/getdelays.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/Documentation/accounting/getdelays.c +++ b/Documentation/accounting/getdelays.c @@ -135,7 +135,7 @@ static int send_cmd(int sd, __u16 nlmsg_ msg.g.version = 0x1; na = (struct nlattr *) GENLMSG_DATA(&msg); na->nla_type = nla_type; - na->nla_len = nla_len + 1 + NLA_HDRLEN; + na->nla_len = nla_len + NLA_HDRLEN; memcpy(NLA_DATA(na), nla_data, nla_len); msg.n.nlmsg_len += NLMSG_ALIGN(na->nla_len);
From: Gustavo A. R. Silva gustavo@embeddedor.com
commit c3422ad5f84a66739ec6a37251ca27638c85b6be upstream.
Currently there is no check on platform_get_irq() return value in case it fails, hence never actually reporting any errors and causing unexpected behavior when using such value as argument for function regmap_irq_get_virq().
Fix this by adding a proper check, a message reporting any errors and returning *pirq*
Addresses-Coverity-ID: 1443940 ("Improper use of negative value") Fixes: 843735b788a4 ("power: axp288_charger: axp288 charger driver") Cc: stable@vger.kernel.org Signed-off-by: Gustavo A. R. Silva gustavo@embeddedor.com Reviewed-by: Hans de Goede hdegoede@redhat.com Signed-off-by: Sebastian Reichel sebastian.reichel@collabora.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Nobuhiro Iwamatsu (CIP) nobuhiro1.iwamatsu@toshiba.co.jp
--- drivers/power/axp288_charger.c | 4 ++++ 1 file changed, 4 insertions(+)
--- a/drivers/power/axp288_charger.c +++ b/drivers/power/axp288_charger.c @@ -883,6 +883,10 @@ static int axp288_charger_probe(struct p /* Register charger interrupts */ for (i = 0; i < CHRG_INTR_END; i++) { pirq = platform_get_irq(info->pdev, i); + if (pirq < 0) { + dev_err(&pdev->dev, "Failed to get IRQ: %d\n", pirq); + return pirq; + } info->irq[i] = regmap_irq_get_virq(info->regmap_irqc, pirq); if (info->irq[i] < 0) { dev_warn(&info->pdev->dev,
From: Ross Lagerwall ross.lagerwall@citrix.com
commit cb257783c2927b73614b20f915a91ff78aa6f3e8 upstream.
Fixes: f599c64fdf7d ("xen-netfront: Fix race between device setup and open") Reported-by: Ben Hutchings ben.hutchings@codethink.co.uk Signed-off-by: Ross Lagerwall ross.lagerwall@citrix.com Reviewed-by: Juergen Gross jgross@suse.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Nobuhiro Iwamatsu (CIP) nobuhiro1.iwamatsu@toshiba.co.jp Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/net/xen-netfront.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
--- a/drivers/net/xen-netfront.c +++ b/drivers/net/xen-netfront.c @@ -1835,7 +1835,7 @@ static int talk_to_netback(struct xenbus err = xen_net_read_mac(dev, info->netdev->dev_addr); if (err) { xenbus_dev_fatal(dev, err, "parsing %s/mac", dev->nodename); - goto out; + goto out_unlocked; }
rtnl_lock(); @@ -1950,6 +1950,7 @@ abort_transaction_no_dev_fatal: xennet_destroy_queues(info); out: rtnl_unlock(); +out_unlocked: device_unregister(&dev->dev); return err; }
From: Ross Lagerwall ross.lagerwall@citrix.com
commit 45c8184c1bed1ca8a7f02918552063a00b909bf5 upstream.
Update the features after calling register_netdev() otherwise the device features are not set up correctly and it not possible to change the MTU of the device. After this change, the features reported by ethtool match the device's features before the commit which introduced the issue and it is possible to change the device's MTU.
Fixes: f599c64fdf7d ("xen-netfront: Fix race between device setup and open") Reported-by: Liam Shepherd liam@dancer.es Signed-off-by: Ross Lagerwall ross.lagerwall@citrix.com Reviewed-by: Juergen Gross jgross@suse.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Nobuhiro Iwamatsu (CIP) nobuhiro1.iwamatsu@toshiba.co.jp Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/net/xen-netfront.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
--- a/drivers/net/xen-netfront.c +++ b/drivers/net/xen-netfront.c @@ -1982,10 +1982,6 @@ static int xennet_connect(struct net_dev /* talk_to_netback() sets the correct number of queues */ num_queues = dev->real_num_tx_queues;
- rtnl_lock(); - netdev_update_features(dev); - rtnl_unlock(); - if (dev->reg_state == NETREG_UNINITIALIZED) { err = register_netdev(dev); if (err) { @@ -1995,6 +1991,10 @@ static int xennet_connect(struct net_dev } }
+ rtnl_lock(); + netdev_update_features(dev); + rtnl_unlock(); + /* * All public and private state should now be sane. Get * ready to start sending and receiving packets and give the driver
From: Paul Cercueil paul@crapouillou.net
commit 9401d5aa328e64617d87abd59af1c91cace4c3e4 upstream.
The 4-bit divider value was written at offset 8, while the jz4740 programming manual locates it at offset 0.
Fixes: 26b0aad80a86 ("ASoC: jz4740: Add dynamic sampling rate support to jz4740-i2s") Signed-off-by: Paul Cercueil paul@crapouillou.net Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/20200306222931.39664-2-paul@crapouillou.net Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- sound/soc/jz4740/jz4740-i2s.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/sound/soc/jz4740/jz4740-i2s.c +++ b/sound/soc/jz4740/jz4740-i2s.c @@ -92,7 +92,7 @@ #define JZ_AIC_I2S_STATUS_BUSY BIT(2)
#define JZ_AIC_CLK_DIV_MASK 0xf -#define I2SDIV_DV_SHIFT 8 +#define I2SDIV_DV_SHIFT 0 #define I2SDIV_DV_MASK (0xf << I2SDIV_DV_SHIFT) #define I2SDIV_IDV_SHIFT 8 #define I2SDIV_IDV_MASK (0xf << I2SDIV_IDV_SHIFT)
From: Kaike Wan kaike.wan@intel.com
commit dfb5394f804ed4fcea1fc925be275a38d66712ab upstream.
When kobject_init_and_add() returns an error in the function hfi1_create_port_files(), the function kobject_put() is not called for the corresponding kobject, which potentially leads to memory leak.
This patch fixes the issue by calling kobject_put() even if kobject_init_and_add() fails.
Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/20200326163813.21129.44280.stgit@awfm-01.aw.intel.... Reviewed-by: Mike Marciniszyn mike.marciniszyn@intel.com Signed-off-by: Kaike Wan kaike.wan@intel.com Signed-off-by: Dennis Dalessandro dennis.dalessandro@intel.com Signed-off-by: Jason Gunthorpe jgg@mellanox.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/staging/rdma/hfi1/sysfs.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-)
--- a/drivers/staging/rdma/hfi1/sysfs.c +++ b/drivers/staging/rdma/hfi1/sysfs.c @@ -620,7 +620,11 @@ int hfi1_create_port_files(struct ib_dev dd_dev_err(dd, "Skipping sc2vl sysfs info, (err %d) port %u\n", ret, port_num); - goto bail; + /* + * Based on the documentation for kobject_init_and_add(), the + * caller should call kobject_put even if this call fails. + */ + goto bail_sc2vl; } kobject_uevent(&ppd->sc2vl_kobj, KOBJ_ADD);
@@ -630,7 +634,7 @@ int hfi1_create_port_files(struct ib_dev dd_dev_err(dd, "Skipping sl2sc sysfs info, (err %d) port %u\n", ret, port_num); - goto bail_sc2vl; + goto bail_sl2sc; } kobject_uevent(&ppd->sl2sc_kobj, KOBJ_ADD);
@@ -640,7 +644,7 @@ int hfi1_create_port_files(struct ib_dev dd_dev_err(dd, "Skipping vl2mtu sysfs info, (err %d) port %u\n", ret, port_num); - goto bail_sl2sc; + goto bail_vl2mtu; } kobject_uevent(&ppd->vl2mtu_kobj, KOBJ_ADD);
@@ -651,7 +655,7 @@ int hfi1_create_port_files(struct ib_dev dd_dev_err(dd, "Skipping Congestion Control sysfs info, (err %d) port %u\n", ret, port_num); - goto bail_vl2mtu; + goto bail_cc; }
kobject_uevent(&ppd->pport_cc_kobj, KOBJ_ADD); @@ -691,7 +695,6 @@ bail_sl2sc: kobject_put(&ppd->sl2sc_kobj); bail_sc2vl: kobject_put(&ppd->sc2vl_kobj); -bail: return ret; }
From: Qiujun Huang hqjagain@gmail.com
commit 71811cac8532b2387b3414f7cd8fe9e497482864 upstream.
Needn't call 'rfcomm_dlc_put' here, because 'rfcomm_dlc_exists' didn't increase dlc->refcnt.
Reported-by: syzbot+4496e82090657320efc6@syzkaller.appspotmail.com Signed-off-by: Qiujun Huang hqjagain@gmail.com Suggested-by: Hillf Danton hdanton@sina.com Signed-off-by: Marcel Holtmann marcel@holtmann.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- net/bluetooth/rfcomm/tty.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-)
--- a/net/bluetooth/rfcomm/tty.c +++ b/net/bluetooth/rfcomm/tty.c @@ -413,10 +413,8 @@ static int __rfcomm_create_dev(struct so dlc = rfcomm_dlc_exists(&req.src, &req.dst, req.channel); if (IS_ERR(dlc)) return PTR_ERR(dlc); - else if (dlc) { - rfcomm_dlc_put(dlc); + if (dlc) return -EBUSY; - } dlc = rfcomm_dlc_alloc(GFP_KERNEL); if (!dlc) return -ENOMEM;
From: Avihai Horon avihaih@mellanox.com
commit 987914ab841e2ec281a35b54348ab109b4c0bb4e upstream.
After a successful allocation of path_rec, num_paths is set to 1, but any error after such allocation will leave num_paths uncleared.
This causes to de-referencing a NULL pointer later on. Hence, num_paths needs to be set back to 0 if such an error occurs.
The following crash from syzkaller revealed it.
kasan: CONFIG_KASAN_INLINE enabled kasan: GPF could be caused by NULL-ptr deref or user memory access general protection fault: 0000 [#1] SMP DEBUG_PAGEALLOC KASAN PTI CPU: 0 PID: 357 Comm: syz-executor060 Not tainted 4.18.0+ #311 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.11.0-0-g63451fca13-prebuilt.qemu-project.org 04/01/2014 RIP: 0010:ib_copy_path_rec_to_user+0x94/0x3e0 Code: f1 f1 f1 f1 c7 40 0c 00 00 f4 f4 65 48 8b 04 25 28 00 00 00 48 89 45 c8 31 c0 e8 d7 60 24 ff 48 8d 7b 4c 48 89 f8 48 c1 e8 03 <42> 0f b6 14 30 48 89 f8 83 e0 07 83 c0 03 38 d0 7c 08 84 d2 0f 85 RSP: 0018:ffff88006586f980 EFLAGS: 00010207 RAX: 0000000000000009 RBX: 0000000000000000 RCX: 1ffff1000d5fe475 RDX: ffff8800621e17c0 RSI: ffffffff820d45f9 RDI: 000000000000004c RBP: ffff88006586fa50 R08: ffffed000cb0df73 R09: ffffed000cb0df72 R10: ffff88006586fa70 R11: ffffed000cb0df73 R12: 1ffff1000cb0df30 R13: ffff88006586fae8 R14: dffffc0000000000 R15: ffff88006aff2200 FS: 00000000016fc880(0000) GS:ffff88006d000000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 0000000020000040 CR3: 0000000063fec000 CR4: 00000000000006b0 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 Call Trace: ? ib_copy_path_rec_from_user+0xcc0/0xcc0 ? __mutex_unlock_slowpath+0xfc/0x670 ? wait_for_completion+0x3b0/0x3b0 ? ucma_query_route+0x818/0xc60 ucma_query_route+0x818/0xc60 ? ucma_listen+0x1b0/0x1b0 ? sched_clock_cpu+0x18/0x1d0 ? sched_clock_cpu+0x18/0x1d0 ? ucma_listen+0x1b0/0x1b0 ? ucma_write+0x292/0x460 ucma_write+0x292/0x460 ? ucma_close_id+0x60/0x60 ? sched_clock_cpu+0x18/0x1d0 ? sched_clock_cpu+0x18/0x1d0 __vfs_write+0xf7/0x620 ? ucma_close_id+0x60/0x60 ? kernel_read+0x110/0x110 ? time_hardirqs_on+0x19/0x580 ? lock_acquire+0x18b/0x3a0 ? finish_task_switch+0xf3/0x5d0 ? _raw_spin_unlock_irq+0x29/0x40 ? _raw_spin_unlock_irq+0x29/0x40 ? finish_task_switch+0x1be/0x5d0 ? __switch_to_asm+0x34/0x70 ? __switch_to_asm+0x40/0x70 ? security_file_permission+0x172/0x1e0 vfs_write+0x192/0x460 ksys_write+0xc6/0x1a0 ? __ia32_sys_read+0xb0/0xb0 ? entry_SYSCALL_64_after_hwframe+0x3e/0xbe ? do_syscall_64+0x1d/0x470 do_syscall_64+0x9e/0x470 entry_SYSCALL_64_after_hwframe+0x49/0xbe
Fixes: 3c86aa70bf67 ("RDMA/cm: Add RDMA CM support for IBoE devices") Link: https://lore.kernel.org/r/20200318101741.47211-1-leon@kernel.org Signed-off-by: Avihai Horon avihaih@mellanox.com Reviewed-by: Maor Gottlieb maorg@mellanox.com Signed-off-by: Leon Romanovsky leonro@mellanox.com Signed-off-by: Jason Gunthorpe jgg@mellanox.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/infiniband/core/cma.c | 1 + 1 file changed, 1 insertion(+)
--- a/drivers/infiniband/core/cma.c +++ b/drivers/infiniband/core/cma.c @@ -2378,6 +2378,7 @@ static int cma_resolve_iboe_route(struct err2: kfree(route->path_rec); route->path_rec = NULL; + route->num_paths = 0; err1: kfree(work); return ret;
From: Taniya Das tdas@codeaurora.org
commit 21ea4b62e1f3dc258001a68da98c9663a9dbd6c7 upstream.
In case of update config failure, return -EBUSY, so that consumers could handle the failure gracefully.
Signed-off-by: Taniya Das tdas@codeaurora.org Link: https://lkml.kernel.org/r/1557339895-21952-2-git-send-email-tdas@codeaurora.... Signed-off-by: Stephen Boyd sboyd@kernel.org Signed-off-by: Lee Jones lee.jones@linaro.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/clk/qcom/clk-rcg2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/clk/qcom/clk-rcg2.c +++ b/drivers/clk/qcom/clk-rcg2.c @@ -107,7 +107,7 @@ static int update_config(struct clk_rcg2 }
WARN(1, "%s: rcg didn't update its configuration.", name); - return 0; + return -EBUSY; }
static int clk_rcg2_set_parent(struct clk_hw *hw, u8 index)
From: Hans Verkuil hans.verkuil@cisco.com
commit a4c30a4861c54af78c4eb8b7855524c1a96d9f80 upstream.
When parsing the reply of a DP_REMOTE_DPCD_READ DPCD command the result is wrong due to a missing idx increment.
This was never noticed since DP_REMOTE_DPCD_READ is currently not used, but if you enable it, then it is all wrong.
Signed-off-by: Hans Verkuil hans.verkuil@cisco.com Reviewed-by: Lyude Paul lyude@redhat.com Acked-by: Alex Deucher alexander.deucher@amd.com Link: https://patchwork.freedesktop.org/patch/msgid/e72ddac2-1dc0-100a-d816-9ac98a... Signed-off-by: Lee Jones lee.jones@linaro.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/gpu/drm/drm_dp_mst_topology.c | 1 + 1 file changed, 1 insertion(+)
--- a/drivers/gpu/drm/drm_dp_mst_topology.c +++ b/drivers/gpu/drm/drm_dp_mst_topology.c @@ -431,6 +431,7 @@ static bool drm_dp_sideband_parse_remote if (idx > raw->curlen) goto fail_len; repmsg->u.remote_dpcd_read_ack.num_bytes = raw->msg[idx]; + idx++; if (idx > raw->curlen) goto fail_len;
On 4/11/20 5:08 AM, Greg Kroah-Hartman wrote:
This is the start of the stable review cycle for the 4.4.219 release. There are 29 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Mon, 13 Apr 2020 11:51:28 +0000. Anything received after that time might be too late.
Build results: total: 169 pass: 169 fail: 0 Qemu test results: total: 335 pass: 335 fail: 0
Guenter
On Sat, 11 Apr 2020 at 17:41, Greg Kroah-Hartman gregkh@linuxfoundation.org wrote:
This is the start of the stable review cycle for the 4.4.219 release. There are 29 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Mon, 13 Apr 2020 11:51:28 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at: https://www.kernel.org/pub/linux/kernel/v4.x/stable-review/patch-4.4.219-rc1... or in the git tree and branch at: git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git linux-4.4.y and the diffstat can be found below.
thanks,
greg k-h
Results from Linaro’s test farm. No regressions on arm64, arm, x86_64, and i386.
Summary ------------------------------------------------------------------------
kernel: 4.4.219-rc1 git repo: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git git branch: linux-4.4.y git commit: 8cd74c57ff4a364d0a753e448ce5eab18cc5bb75 git describe: v4.4.218-30-g8cd74c57ff4a Test details: https://qa-reports.linaro.org/lkft/linux-stable-rc-4.4-oe/build/v4.4.218-30-...
No regressions (compared to build v4.4.218)
No fixes (compared to build v4.4.218)
Ran 27015 total tests in the following environments and test suites.
Environments -------------- - i386 - juno-r2 - arm64 - juno-r2-compat - juno-r2-kasan - qemu_arm - qemu_arm64 - qemu_i386 - qemu_x86_64 - x15 - arm - x86_64 - x86-kasan
Test Suites ----------- * build * kselftest * kvm-unit-tests * libhugetlbfs * linux-log-parser * ltp-cap_bounds-tests * ltp-commands-tests * ltp-containers-tests * ltp-cpuhotplug-tests * ltp-crypto-tests * ltp-cve-tests * ltp-dio-tests * ltp-fcntl-locktests-tests * ltp-filecaps-tests * ltp-fs-tests * ltp-fs_bind-tests * ltp-fs_perms_simple-tests * ltp-fsx-tests * ltp-hugetlb-tests * ltp-io-tests * ltp-ipc-tests * ltp-math-tests * ltp-mm-tests * ltp-nptl-tests * ltp-open-posix-tests * ltp-pty-tests * ltp-sched-tests * ltp-securebits-tests * ltp-syscalls-tests * network-basic-tests * perf * v4l2-compliance * spectre-meltdown-checker-test * install-android-platform-tools-r2600 * kselftest-vsyscall-mode-native
Summary ------------------------------------------------------------------------
kernel: 4.4.219-rc1 git repo: https://git.linaro.org/lkft/arm64-stable-rc.git git branch: 4.4.219-rc1-hikey-20200411-691 git commit: 9b98182ae4842aa200b9878be74c2fa565a1ab29 git describe: 4.4.219-rc1-hikey-20200411-691 Test details: https://qa-reports.linaro.org/lkft/linaro-hikey-stable-rc-4.4-oe/build/4.4.2...
No regressions (compared to build 4.4.219-rc1-hikey-20200409-690)
No fixes (compared to build 4.4.219-rc1-hikey-20200409-690)
Ran 1726 total tests in the following environments and test suites.
Environments -------------- - hi6220-hikey - arm64
Test Suites ----------- * build * install-android-platform-tools-r2600 * kselftest * libhugetlbfs * linux-log-parser * ltp-cap_bounds-tests * ltp-commands-tests * ltp-containers-tests * ltp-cpuhotplug-tests * ltp-cve-tests * ltp-dio-tests * ltp-fcntl-locktests-tests * ltp-filecaps-tests * ltp-fs-tests * ltp-fs_bind-tests * ltp-fs_perms_simple-tests * ltp-fsx-tests * ltp-hugetlb-tests * ltp-io-tests * ltp-ipc-tests * ltp-math-tests * ltp-mm-tests * ltp-nptl-tests * ltp-pty-tests * ltp-sched-tests * ltp-securebits-tests * ltp-syscalls-tests * perf * spectre-meltdown-checker-test * v4l2-compliance
Hello Greg,
From: stable-owner@vger.kernel.org stable-owner@vger.kernel.org On Behalf Of Greg Kroah-Hartman Sent: 11 April 2020 13:09
This is the start of the stable review cycle for the 4.4.219 release. There are 29 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Mon, 13 Apr 2020 11:51:28 +0000. Anything received after that time might be too late.
No build issues seen for CIP configs for Linux 4.4.219-rc1 (8cd74c57ff4a).
Build logs: https://gitlab.com/cip-project/cip-testing/linux-stable-rc-ci/pipelines/1349... GitLab CI Pipeline: https://gitlab.com/cip-project/cip-testing/linux-cip-pipelines/-/blob/master...
Kind regards, Chris
The whole patch series can be found in one patch at: https://www.kernel.org/pub/linux/kernel/v4.x/stable-review/patch- 4.4.219-rc1.gz or in the git tree and branch at: git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git linux-4.4.y and the diffstat can be found below.
thanks,
greg k-h
Pseudo-Shortlog of commits:
Greg Kroah-Hartman gregkh@linuxfoundation.org Linux 4.4.219-rc1
Hans Verkuil hans.verkuil@cisco.com drm_dp_mst_topology: fix broken drm_dp_sideband_parse_remote_dpcd_read()
Taniya Das tdas@codeaurora.org clk: qcom: rcg: Return failure for RCG update
Avihai Horon avihaih@mellanox.com RDMA/cm: Update num_paths in cma_resolve_iboe_route error flow
Qiujun Huang hqjagain@gmail.com Bluetooth: RFCOMM: fix ODEBUG bug in rfcomm_dev_ioctl
Kaike Wan kaike.wan@intel.com IB/hfi1: Call kobject_put() when kobject_init_and_add() fails
Paul Cercueil paul@crapouillou.net ASoC: jz4740-i2s: Fix divider written at incorrect offset in register
Ross Lagerwall ross.lagerwall@citrix.com xen-netfront: Update features after registering netdev
Ross Lagerwall ross.lagerwall@citrix.com xen-netfront: Fix mismatched rtnl_unlock
Gustavo A. R. Silva gustavo@embeddedor.com power: supply: axp288_charger: Fix unchecked return value
David Ahern dsahern@kernel.org tools/accounting/getdelays.c: fix netlink attribute length
Jason A. Donenfeld Jason@zx2c4.com random: always use batched entropy for get_random_u{32,64}
Richard Palethorpe rpalethorpe@suse.com slcan: Don't transmit uninitialized stack data in padding
Jisheng Zhang Jisheng.Zhang@synaptics.com net: stmmac: dwmac1000: fix out-of-bounds mac address reg setting
Randy Dunlap rdunlap@infradead.org mm: mempolicy: require at least one nodeid for MPOL_PREFERRED
Daniel Jordan daniel.m.jordan@oracle.com padata: always acquire cpu_hotplug_lock before pinst->lock
Krzysztof Opasiak k.opasiak@samsung.com usb: gadget: printer: Drop unused device qualifier descriptor
Krzysztof Opasiak k.opasiak@samsung.com usb: gadget: uac2: Drop unused device qualifier descriptor
Guillaume Nault g.nault@alphalink.fr l2tp: fix race between l2tp_session_delete() and l2tp_tunnel_closeall()
Guillaume Nault g.nault@alphalink.fr l2tp: ensure sessions are freed after their PPPOL2TP socket
Gao Feng fgao@ikuai8.com l2tp: Refactor the codes with existing macros instead of literal number
Guillaume Nault g.nault@alphalink.fr l2tp: fix duplicate session creation
Guillaume Nault g.nault@alphalink.fr l2tp: ensure session can't get removed during pppol2tp_session_ioctl()
Guillaume Nault g.nault@alphalink.fr l2tp: fix race in l2tp_recv_common()
Shmulik Ladkani shmulik.ladkani@gmail.com net: l2tp: Make l2tp_ip6 namespace aware
phil.turnbull@oracle.com phil.turnbull@oracle.com l2tp: Correctly return -EBADF from pppol2tp_getname.
Marcelo Ricardo Leitner marcelo.leitner@gmail.com sctp: fix possibly using a bad saddr with a given dst
William Dauchy w.dauchy@criteo.com net, ip_tunnel: fix interface lookup with no key
Qian Cai cai@lca.pw ipv4: fix a RCU-list lock in fib_triestat_seq_show
Gerd Hoffmann kraxel@redhat.com drm/bochs: downgrade pci_request_region failure from error to warning
Diffstat:
Documentation/accounting/getdelays.c | 2 +- Makefile | 4 +- drivers/char/random.c | 6 - drivers/clk/qcom/clk-rcg2.c | 2 +- drivers/gpu/drm/bochs/bochs_hw.c | 6 +- drivers/gpu/drm/drm_dp_mst_topology.c | 1 + drivers/infiniband/core/cma.c | 1 + drivers/net/can/slcan.c | 4 +- .../net/ethernet/stmicro/stmmac/dwmac1000_core.c | 2 +- drivers/net/xen-netfront.c | 11 +- drivers/power/axp288_charger.c | 4 + drivers/staging/rdma/hfi1/sysfs.c | 13 +- drivers/usb/gadget/function/f_printer.c | 8 -- drivers/usb/gadget/function/f_uac2.c | 12 -- kernel/padata.c | 4 +- mm/mempolicy.c | 6 +- net/bluetooth/rfcomm/tty.c | 4 +- net/ipv4/fib_trie.c | 3 + net/ipv4/ip_tunnel.c | 6 +- net/l2tp/l2tp_core.c | 149 ++++++++++++++++----- net/l2tp/l2tp_core.h | 4 + net/l2tp/l2tp_eth.c | 10 +- net/l2tp/l2tp_ip.c | 17 ++- net/l2tp/l2tp_ip6.c | 28 ++-- net/l2tp/l2tp_ppp.c | 110 +++++++-------- net/sctp/ipv6.c | 20 ++- net/sctp/protocol.c | 28 ++-- sound/soc/jz4740/jz4740-i2s.c | 2 +- 28 files changed, 285 insertions(+), 182 deletions(-)
On 11/04/2020 13:08, Greg Kroah-Hartman wrote:
This is the start of the stable review cycle for the 4.4.219 release. There are 29 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Mon, 13 Apr 2020 11:51:28 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at: https://www.kernel.org/pub/linux/kernel/v4.x/stable-review/patch-4.4.219-rc1... or in the git tree and branch at: git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git linux-4.4.y and the diffstat can be found below.
thanks,
greg k-h
Sorry this is late, but all tests are passing for Tegra ...
Test results for stable-v4.4: 6 builds: 6 pass, 0 fail 12 boots: 12 pass, 0 fail 19 tests: 19 pass, 0 fail
Linux version: 4.4.219-rc1-g8cd74c57ff4a Boards tested: tegra124-jetson-tk1, tegra20-ventana, tegra30-cardhu-a04
Cheers Jon
On Tue, Apr 14, 2020 at 11:35:53AM +0100, Jon Hunter wrote:
On 11/04/2020 13:08, Greg Kroah-Hartman wrote:
This is the start of the stable review cycle for the 4.4.219 release. There are 29 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Mon, 13 Apr 2020 11:51:28 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at: https://www.kernel.org/pub/linux/kernel/v4.x/stable-review/patch-4.4.219-rc1... or in the git tree and branch at: git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git linux-4.4.y and the diffstat can be found below.
thanks,
greg k-h
Sorry this is late, but all tests are passing for Tegra ...
Test results for stable-v4.4: 6 builds: 6 pass, 0 fail 12 boots: 12 pass, 0 fail 19 tests: 19 pass, 0 fail
Linux version: 4.4.219-rc1-g8cd74c57ff4a Boards tested: tegra124-jetson-tk1, tegra20-ventana, tegra30-cardhu-a04
No problems, thanks for testing all of these and letting me know.
greg k-h
linux-stable-mirror@lists.linaro.org