Skip to content

Commit 016576d

Browse files
committed
Merge branch 'l2tp-fix-some-races-in-session-deletion'
Guillaume Nault says: ==================== l2tp: fix some races in session deletion L2TP provides several interfaces for deleting sessions. Using two of them concurrently can lead to use-after-free bugs. Patch #2 uses a flag to prevent double removal of L2TP sessions. Patch #1 fixes a bug found in the way. Fixing this bug is also necessary for patch #2 to handle all cases. This issue is similar to the tunnel deletion bug being worked on by Sabrina: https://patchwork.ozlabs.org/patch/814173/ ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
2 parents 5c34652 + b228a94 commit 016576d

File tree

3 files changed

+11
-4
lines changed

3 files changed

+11
-4
lines changed

net/l2tp/l2tp_core.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1314,6 +1314,9 @@ void l2tp_tunnel_closeall(struct l2tp_tunnel *tunnel)
13141314

13151315
hlist_del_init(&session->hlist);
13161316

1317+
if (test_and_set_bit(0, &session->dead))
1318+
goto again;
1319+
13171320
if (session->ref != NULL)
13181321
(*session->ref)(session);
13191322

@@ -1750,6 +1753,9 @@ EXPORT_SYMBOL_GPL(__l2tp_session_unhash);
17501753
*/
17511754
int l2tp_session_delete(struct l2tp_session *session)
17521755
{
1756+
if (test_and_set_bit(0, &session->dead))
1757+
return 0;
1758+
17531759
if (session->ref)
17541760
(*session->ref)(session);
17551761
__l2tp_session_unhash(session);

net/l2tp/l2tp_core.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ struct l2tp_session_cfg {
7676
struct l2tp_session {
7777
int magic; /* should be
7878
* L2TP_SESSION_MAGIC */
79+
long dead;
7980

8081
struct l2tp_tunnel *tunnel; /* back pointer to tunnel
8182
* context */

net/l2tp/l2tp_ppp.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -437,11 +437,11 @@ static void pppol2tp_session_close(struct l2tp_session *session)
437437

438438
BUG_ON(session->magic != L2TP_SESSION_MAGIC);
439439

440-
if (sock) {
440+
if (sock)
441441
inet_shutdown(sock, SEND_SHUTDOWN);
442-
/* Don't let the session go away before our socket does */
443-
l2tp_session_inc_refcount(session);
444-
}
442+
443+
/* Don't let the session go away before our socket does */
444+
l2tp_session_inc_refcount(session);
445445
}
446446

447447
/* Really kill the session socket. (Called from sock_put() if

0 commit comments

Comments
 (0)