* [PATCH 0/8] [backports] l2tp use-after-free fixes for 4.4 stable
@ 2020-04-02 17:32 Will Deacon
2020-04-02 17:32 ` [PATCH 1/8] l2tp: Correctly return -EBADF from pppol2tp_getname Will Deacon
` (8 more replies)
0 siblings, 9 replies; 11+ messages in thread
From: Will Deacon @ 2020-04-02 17:32 UTC (permalink / raw)
To: gregkh; +Cc: stable, linux-kernel, kernel-team, g.nault, Will Deacon
Hi Greg,
Syzbot has been complaining about KASAN splats due to use-after-free
issues in the l2tp code on 4.4 Android kernels (although I reproduced
with latest 4.4 stable on my laptop):
https://syzkaller.appspot.com/bug?id=de316389db0fa0cd7ced6e564601ea8e56625ebc
These have been fixed upstream, but for some reason didn't get picked up
for stable. This series applies to 4.4.y and I've sent patches for 4.9
separately.
Thanks,
Will
--->8
Gao Feng (1):
l2tp: Refactor the codes with existing macros instead of literal
number
Guillaume Nault (5):
l2tp: fix race in l2tp_recv_common()
l2tp: ensure session can't get removed during pppol2tp_session_ioctl()
l2tp: fix duplicate session creation
l2tp: ensure sessions are freed after their PPPOL2TP socket
l2tp: fix race between l2tp_session_delete() and
l2tp_tunnel_closeall()
Shmulik Ladkani (1):
net: l2tp: Make l2tp_ip6 namespace aware
phil.turnbull@oracle.com (1):
l2tp: Correctly return -EBADF from pppol2tp_getname.
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 ++++++++++++++++----------------
6 files changed, 211 insertions(+), 107 deletions(-)
--
2.26.0.rc2.310.g2932bb562d-goog
^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH 1/8] l2tp: Correctly return -EBADF from pppol2tp_getname.
2020-04-02 17:32 [PATCH 0/8] [backports] l2tp use-after-free fixes for 4.4 stable Will Deacon
@ 2020-04-02 17:32 ` Will Deacon
2020-04-02 17:32 ` [PATCH 2/8] net: l2tp: Make l2tp_ip6 namespace aware Will Deacon
` (7 subsequent siblings)
8 siblings, 0 replies; 11+ messages in thread
From: Will Deacon @ 2020-04-02 17:32 UTC (permalink / raw)
To: gregkh
Cc: stable, linux-kernel, kernel-team, g.nault, phil.turnbull,
David S . Miller, Will Deacon
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>
---
net/l2tp/l2tp_ppp.c | 7 ++-----
1 file changed, 2 insertions(+), 5 deletions(-)
diff --git a/net/l2tp/l2tp_ppp.c b/net/l2tp/l2tp_ppp.c
index d3f1222c1a8c..bc5fca07d2ee 100644
--- a/net/l2tp/l2tp_ppp.c
+++ b/net/l2tp/l2tp_ppp.c
@@ -889,10 +889,8 @@ static int pppol2tp_getname(struct socket *sock, struct sockaddr *uaddr,
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 socket *sock, struct sockaddr *uaddr,
}
*usockaddr_len = len;
+ error = 0;
sock_put(pls->tunnel_sock);
end_put_sess:
sock_put(sk);
- error = 0;
-
end:
return error;
}
--
2.26.0.rc2.310.g2932bb562d-goog
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH 2/8] net: l2tp: Make l2tp_ip6 namespace aware
2020-04-02 17:32 [PATCH 0/8] [backports] l2tp use-after-free fixes for 4.4 stable Will Deacon
2020-04-02 17:32 ` [PATCH 1/8] l2tp: Correctly return -EBADF from pppol2tp_getname Will Deacon
@ 2020-04-02 17:32 ` Will Deacon
2020-04-02 17:32 ` [PATCH 3/8] l2tp: fix race in l2tp_recv_common() Will Deacon
` (6 subsequent siblings)
8 siblings, 0 replies; 11+ messages in thread
From: Will Deacon @ 2020-04-02 17:32 UTC (permalink / raw)
To: gregkh
Cc: stable, linux-kernel, kernel-team, g.nault, Shmulik Ladkani,
David S . Miller, Will Deacon
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>
---
net/l2tp/l2tp_ip6.c | 12 +++++++-----
1 file changed, 7 insertions(+), 5 deletions(-)
diff --git a/net/l2tp/l2tp_ip6.c b/net/l2tp/l2tp_ip6.c
index a88649c5d26c..391dd9d8144f 100644
--- a/net/l2tp/l2tp_ip6.c
+++ b/net/l2tp/l2tp_ip6.c
@@ -127,6 +127,7 @@ static inline struct sock *l2tp_ip6_bind_lookup(struct net *net,
*/
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 *skb)
}
/* 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 sockaddr *uaddr, int addr_len)
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, struct sockaddr *uaddr, int addr_len)
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 sock *sk, struct sk_buff *skb)
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;
}
--
2.26.0.rc2.310.g2932bb562d-goog
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH 3/8] l2tp: fix race in l2tp_recv_common()
2020-04-02 17:32 [PATCH 0/8] [backports] l2tp use-after-free fixes for 4.4 stable Will Deacon
2020-04-02 17:32 ` [PATCH 1/8] l2tp: Correctly return -EBADF from pppol2tp_getname Will Deacon
2020-04-02 17:32 ` [PATCH 2/8] net: l2tp: Make l2tp_ip6 namespace aware Will Deacon
@ 2020-04-02 17:32 ` Will Deacon
2020-04-02 17:32 ` [PATCH 4/8] l2tp: ensure session can't get removed during pppol2tp_session_ioctl() Will Deacon
` (5 subsequent siblings)
8 siblings, 0 replies; 11+ messages in thread
From: Will Deacon @ 2020-04-02 17:32 UTC (permalink / raw)
To: gregkh
Cc: stable, linux-kernel, kernel-team, g.nault, David S . Miller,
Will Deacon
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>
---
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(-)
diff --git a/net/l2tp/l2tp_core.c b/net/l2tp/l2tp_core.c
index 429dbb064240..4d41fe40723d 100644
--- a/net/l2tp/l2tp_core.c
+++ b/net/l2tp/l2tp_core.c
@@ -277,6 +277,55 @@ struct l2tp_session *l2tp_session_find(struct net *net, struct l2tp_tunnel *tunn
}
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_session *session, struct sk_buff *skb,
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_session *session, struct sk_buff *skb,
/* 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 l2tp_tunnel *tunnel, struct sk_buff *skb,
}
/* 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 l2tp_tunnel *tunnel, struct sk_buff *skb,
goto error;
l2tp_recv_common(session, skb, ptr, optr, hdrflags, length, payload_hook);
+ l2tp_session_dec_refcount(session);
return 0;
diff --git a/net/l2tp/l2tp_core.h b/net/l2tp/l2tp_core.h
index fad47e9d74bc..705fbc63ddc2 100644
--- 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);
diff --git a/net/l2tp/l2tp_ip.c b/net/l2tp/l2tp_ip.c
index 7efb3cadc152..58f87bdd12c7 100644
--- a/net/l2tp/l2tp_ip.c
+++ b/net/l2tp/l2tp_ip.c
@@ -142,19 +142,19 @@ static int l2tp_ip_recv(struct sk_buff *skb)
}
/* 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 *skb)
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);
diff --git a/net/l2tp/l2tp_ip6.c b/net/l2tp/l2tp_ip6.c
index 391dd9d8144f..af04a8a68269 100644
--- a/net/l2tp/l2tp_ip6.c
+++ b/net/l2tp/l2tp_ip6.c
@@ -154,19 +154,19 @@ static int l2tp_ip6_recv(struct sk_buff *skb)
}
/* 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 *skb)
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);
--
2.26.0.rc2.310.g2932bb562d-goog
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH 4/8] l2tp: ensure session can't get removed during pppol2tp_session_ioctl()
2020-04-02 17:32 [PATCH 0/8] [backports] l2tp use-after-free fixes for 4.4 stable Will Deacon
` (2 preceding siblings ...)
2020-04-02 17:32 ` [PATCH 3/8] l2tp: fix race in l2tp_recv_common() Will Deacon
@ 2020-04-02 17:32 ` Will Deacon
2020-04-02 17:32 ` [PATCH 5/8] l2tp: fix duplicate session creation Will Deacon
` (4 subsequent siblings)
8 siblings, 0 replies; 11+ messages in thread
From: Will Deacon @ 2020-04-02 17:32 UTC (permalink / raw)
To: gregkh
Cc: stable, linux-kernel, kernel-team, g.nault, David S . Miller,
Will Deacon
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>
---
net/l2tp/l2tp_ppp.c | 15 +++++++++++----
1 file changed, 11 insertions(+), 4 deletions(-)
diff --git a/net/l2tp/l2tp_ppp.c b/net/l2tp/l2tp_ppp.c
index bc5fca07d2ee..74b211312d4d 100644
--- a/net/l2tp/l2tp_ppp.c
+++ b/net/l2tp/l2tp_ppp.c
@@ -1168,11 +1168,18 @@ static int pppol2tp_tunnel_ioctl(struct l2tp_tunnel *tunnel,
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
--
2.26.0.rc2.310.g2932bb562d-goog
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH 5/8] l2tp: fix duplicate session creation
2020-04-02 17:32 [PATCH 0/8] [backports] l2tp use-after-free fixes for 4.4 stable Will Deacon
` (3 preceding siblings ...)
2020-04-02 17:32 ` [PATCH 4/8] l2tp: ensure session can't get removed during pppol2tp_session_ioctl() Will Deacon
@ 2020-04-02 17:32 ` Will Deacon
2020-04-02 17:32 ` [PATCH 6/8] l2tp: Refactor the codes with existing macros instead of literal number Will Deacon
` (3 subsequent siblings)
8 siblings, 0 replies; 11+ messages in thread
From: Will Deacon @ 2020-04-02 17:32 UTC (permalink / raw)
To: gregkh
Cc: stable, linux-kernel, kernel-team, g.nault, David S . Miller,
Will Deacon
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>
---
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(-)
diff --git a/net/l2tp/l2tp_core.c b/net/l2tp/l2tp_core.c
index 4d41fe40723d..03475b124841 100644
--- a/net/l2tp/l2tp_core.c
+++ b/net/l2tp/l2tp_core.c
@@ -377,6 +377,48 @@ struct l2tp_session *l2tp_session_find_by_ifname(struct net *net, char *ifname)
}
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_header_len);
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(int priv_size, struct l2tp_tunnel *tunn
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(int priv_size, struct l2tp_tunnel *tunn
/* 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);
diff --git a/net/l2tp/l2tp_eth.c b/net/l2tp/l2tp_eth.c
index e253c26f31ac..c94160df71af 100644
--- a/net/l2tp/l2tp_eth.c
+++ b/net/l2tp/l2tp_eth.c
@@ -223,12 +223,6 @@ static int l2tp_eth_create(struct net *net, u32 tunnel_id, u32 session_id, u32 p
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 *net, u32 tunnel_id, u32 session_id, u32 p
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;
}
diff --git a/net/l2tp/l2tp_ppp.c b/net/l2tp/l2tp_ppp.c
index 74b211312d4d..97155145c0c5 100644
--- a/net/l2tp/l2tp_ppp.c
+++ b/net/l2tp/l2tp_ppp.c
@@ -600,6 +600,7 @@ static int pppol2tp_connect(struct socket *sock, struct sockaddr *uservaddr,
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 socket *sock, struct sockaddr *uservaddr,
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(struct net *net, u32 tunnel_id, u32 session_i
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(struct net *net, u32 tunnel_id, u32 session_i
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;
--
2.26.0.rc2.310.g2932bb562d-goog
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH 6/8] l2tp: Refactor the codes with existing macros instead of literal number
2020-04-02 17:32 [PATCH 0/8] [backports] l2tp use-after-free fixes for 4.4 stable Will Deacon
` (4 preceding siblings ...)
2020-04-02 17:32 ` [PATCH 5/8] l2tp: fix duplicate session creation Will Deacon
@ 2020-04-02 17:32 ` Will Deacon
2020-04-02 17:32 ` [PATCH 7/8] l2tp: ensure sessions are freed after their PPPOL2TP socket Will Deacon
` (2 subsequent siblings)
8 siblings, 0 replies; 11+ messages in thread
From: Will Deacon @ 2020-04-02 17:32 UTC (permalink / raw)
To: gregkh
Cc: stable, linux-kernel, kernel-team, g.nault, Gao Feng,
David S . Miller, Will Deacon
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>
---
net/l2tp/l2tp_ppp.c | 20 +++++++++-----------
1 file changed, 9 insertions(+), 11 deletions(-)
diff --git a/net/l2tp/l2tp_ppp.c b/net/l2tp/l2tp_ppp.c
index 97155145c0c5..98d4fa47b6a5 100644
--- a/net/l2tp/l2tp_ppp.c
+++ b/net/l2tp/l2tp_ppp.c
@@ -177,7 +177,7 @@ static int pppol2tp_recv_payload_hook(struct sk_buff *skb)
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(struct l2tp_session *session)
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 socket *sock, struct msghdr *m,
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 socket *sock, struct msghdr *m,
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_channel *chan, struct sk_buff *skb)
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(struct l2tp_session *session)
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);
}
--
2.26.0.rc2.310.g2932bb562d-goog
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH 7/8] l2tp: ensure sessions are freed after their PPPOL2TP socket
2020-04-02 17:32 [PATCH 0/8] [backports] l2tp use-after-free fixes for 4.4 stable Will Deacon
` (5 preceding siblings ...)
2020-04-02 17:32 ` [PATCH 6/8] l2tp: Refactor the codes with existing macros instead of literal number Will Deacon
@ 2020-04-02 17:32 ` Will Deacon
2020-04-02 17:32 ` [PATCH 8/8] l2tp: fix race between l2tp_session_delete() and l2tp_tunnel_closeall() Will Deacon
2020-04-03 12:45 ` [PATCH 0/8] [backports] l2tp use-after-free fixes for 4.4 stable Greg KH
8 siblings, 0 replies; 11+ messages in thread
From: Will Deacon @ 2020-04-02 17:32 UTC (permalink / raw)
To: gregkh
Cc: stable, linux-kernel, kernel-team, g.nault, David S . Miller,
Will Deacon
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>
---
net/l2tp/l2tp_ppp.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/net/l2tp/l2tp_ppp.c b/net/l2tp/l2tp_ppp.c
index 98d4fa47b6a5..bc5d6b8f8ede 100644
--- a/net/l2tp/l2tp_ppp.c
+++ b/net/l2tp/l2tp_ppp.c
@@ -452,11 +452,11 @@ static void pppol2tp_session_close(struct l2tp_session *session)
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
--
2.26.0.rc2.310.g2932bb562d-goog
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH 8/8] l2tp: fix race between l2tp_session_delete() and l2tp_tunnel_closeall()
2020-04-02 17:32 [PATCH 0/8] [backports] l2tp use-after-free fixes for 4.4 stable Will Deacon
` (6 preceding siblings ...)
2020-04-02 17:32 ` [PATCH 7/8] l2tp: ensure sessions are freed after their PPPOL2TP socket Will Deacon
@ 2020-04-02 17:32 ` Will Deacon
2020-04-03 12:45 ` [PATCH 0/8] [backports] l2tp use-after-free fixes for 4.4 stable Greg KH
8 siblings, 0 replies; 11+ messages in thread
From: Will Deacon @ 2020-04-02 17:32 UTC (permalink / raw)
To: gregkh
Cc: stable, linux-kernel, kernel-team, g.nault, David S . Miller,
Will Deacon
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>
---
net/l2tp/l2tp_core.c | 6 ++++++
net/l2tp/l2tp_core.h | 1 +
2 files changed, 7 insertions(+)
diff --git a/net/l2tp/l2tp_core.c b/net/l2tp/l2tp_core.c
index 03475b124841..2b8b5c57c7f0 100644
--- 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);
diff --git a/net/l2tp/l2tp_core.h b/net/l2tp/l2tp_core.h
index 705fbc63ddc2..06323a12d62c 100644
--- 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 */
--
2.26.0.rc2.310.g2932bb562d-goog
^ permalink raw reply related [flat|nested] 11+ messages in thread
* Re: [PATCH 0/8] [backports] l2tp use-after-free fixes for 4.4 stable
2020-04-02 17:32 [PATCH 0/8] [backports] l2tp use-after-free fixes for 4.4 stable Will Deacon
` (7 preceding siblings ...)
2020-04-02 17:32 ` [PATCH 8/8] l2tp: fix race between l2tp_session_delete() and l2tp_tunnel_closeall() Will Deacon
@ 2020-04-03 12:45 ` Greg KH
2020-04-03 13:22 ` Will Deacon
8 siblings, 1 reply; 11+ messages in thread
From: Greg KH @ 2020-04-03 12:45 UTC (permalink / raw)
To: Will Deacon; +Cc: stable, linux-kernel, kernel-team, g.nault
On Thu, Apr 02, 2020 at 06:32:42PM +0100, Will Deacon wrote:
> Hi Greg,
>
> Syzbot has been complaining about KASAN splats due to use-after-free
> issues in the l2tp code on 4.4 Android kernels (although I reproduced
> with latest 4.4 stable on my laptop):
>
> https://syzkaller.appspot.com/bug?id=de316389db0fa0cd7ced6e564601ea8e56625ebc
>
> These have been fixed upstream, but for some reason didn't get picked up
> for stable. This series applies to 4.4.y and I've sent patches for 4.9
> separately.
All now queued up, thanks.
greg k-h
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH 0/8] [backports] l2tp use-after-free fixes for 4.4 stable
2020-04-03 12:45 ` [PATCH 0/8] [backports] l2tp use-after-free fixes for 4.4 stable Greg KH
@ 2020-04-03 13:22 ` Will Deacon
0 siblings, 0 replies; 11+ messages in thread
From: Will Deacon @ 2020-04-03 13:22 UTC (permalink / raw)
To: Greg KH; +Cc: stable, linux-kernel, kernel-team, g.nault
On Fri, Apr 03, 2020 at 02:45:57PM +0200, Greg KH wrote:
> On Thu, Apr 02, 2020 at 06:32:42PM +0100, Will Deacon wrote:
> > Hi Greg,
> >
> > Syzbot has been complaining about KASAN splats due to use-after-free
> > issues in the l2tp code on 4.4 Android kernels (although I reproduced
> > with latest 4.4 stable on my laptop):
> >
> > https://syzkaller.appspot.com/bug?id=de316389db0fa0cd7ced6e564601ea8e56625ebc
> >
> > These have been fixed upstream, but for some reason didn't get picked up
> > for stable. This series applies to 4.4.y and I've sent patches for 4.9
> > separately.
>
> All now queued up, thanks.
Thanks, Greg.
Will
^ permalink raw reply [flat|nested] 11+ messages in thread
end of thread, other threads:[~2020-04-03 13:22 UTC | newest]
Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-04-02 17:32 [PATCH 0/8] [backports] l2tp use-after-free fixes for 4.4 stable Will Deacon
2020-04-02 17:32 ` [PATCH 1/8] l2tp: Correctly return -EBADF from pppol2tp_getname Will Deacon
2020-04-02 17:32 ` [PATCH 2/8] net: l2tp: Make l2tp_ip6 namespace aware Will Deacon
2020-04-02 17:32 ` [PATCH 3/8] l2tp: fix race in l2tp_recv_common() Will Deacon
2020-04-02 17:32 ` [PATCH 4/8] l2tp: ensure session can't get removed during pppol2tp_session_ioctl() Will Deacon
2020-04-02 17:32 ` [PATCH 5/8] l2tp: fix duplicate session creation Will Deacon
2020-04-02 17:32 ` [PATCH 6/8] l2tp: Refactor the codes with existing macros instead of literal number Will Deacon
2020-04-02 17:32 ` [PATCH 7/8] l2tp: ensure sessions are freed after their PPPOL2TP socket Will Deacon
2020-04-02 17:32 ` [PATCH 8/8] l2tp: fix race between l2tp_session_delete() and l2tp_tunnel_closeall() Will Deacon
2020-04-03 12:45 ` [PATCH 0/8] [backports] l2tp use-after-free fixes for 4.4 stable Greg KH
2020-04-03 13:22 ` Will Deacon
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).