Skip to content

Commit 0aa4557

Browse files
j-c-hdavem330
authored andcommitted
l2tp: add idr consistency check in session_register
l2tp_session_register uses an idr_alloc then idr_replace pattern to insert sessions into the session IDR. To catch invalid locking, add a WARN_ON_ONCE if the IDR entry is modified by another thread between alloc and replace steps. Also add comments to make expectations clear. Signed-off-by: James Chapman <[email protected]> Signed-off-by: Tom Parkin <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 89b768e commit 0aa4557

File tree

1 file changed

+9
-2
lines changed

1 file changed

+9
-2
lines changed

net/l2tp/l2tp_core.c

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -474,6 +474,7 @@ int l2tp_session_register(struct l2tp_session *session,
474474
{
475475
struct l2tp_net *pn = l2tp_pernet(tunnel->l2tp_net);
476476
struct l2tp_session *other_session = NULL;
477+
void *old = NULL;
477478
u32 session_key;
478479
int err;
479480

@@ -517,13 +518,19 @@ int l2tp_session_register(struct l2tp_session *session,
517518
WRITE_ONCE(session->tunnel, tunnel);
518519
list_add_rcu(&session->list, &tunnel->session_list);
519520

521+
/* this makes session available to lockless getters */
520522
if (tunnel->version == L2TP_HDR_VER_3) {
521523
if (!other_session)
522-
idr_replace(&pn->l2tp_v3_session_idr, session, session_key);
524+
old = idr_replace(&pn->l2tp_v3_session_idr, session, session_key);
523525
} else {
524-
idr_replace(&pn->l2tp_v2_session_idr, session, session_key);
526+
old = idr_replace(&pn->l2tp_v2_session_idr, session, session_key);
525527
}
526528

529+
/* old should be NULL, unless something removed or modified
530+
* the IDR entry after our idr_alloc_32 above (which shouldn't
531+
* happen).
532+
*/
533+
WARN_ON_ONCE(old);
527534
out:
528535
spin_unlock_bh(&pn->l2tp_session_idr_lock);
529536
spin_unlock_bh(&tunnel->list_lock);

0 commit comments

Comments
 (0)