Commit 4814326b authored by Vlad Yasevich's avatar Vlad Yasevich

sctp: prevent too-fast association id reuse

We use the idr subsystem and always ask for an id
at or above 1.  This results in a id reuse when one
association is terminated while another is created.

To prevent re-use, we keep track of the last id returned
and ask for that id + 1 as a base for each query.  We let
the idr spin lock protect this base id as well.
Signed-off-by: default avatarVlad Yasevich <vladislav.yasevich@hp.com>
parent da85b739
...@@ -63,6 +63,12 @@ ...@@ -63,6 +63,12 @@
static void sctp_assoc_bh_rcv(struct work_struct *work); static void sctp_assoc_bh_rcv(struct work_struct *work);
static void sctp_assoc_free_asconf_acks(struct sctp_association *asoc); static void sctp_assoc_free_asconf_acks(struct sctp_association *asoc);
/* Keep track of the new idr low so that we don't re-use association id
* numbers too fast. It is protected by they idr spin lock is in the
* range of 1 - INT_MAX.
*/
static u32 idr_low = 1;
/* 1st Level Abstractions. */ /* 1st Level Abstractions. */
...@@ -1553,7 +1559,12 @@ int sctp_assoc_set_id(struct sctp_association *asoc, gfp_t gfp) ...@@ -1553,7 +1559,12 @@ int sctp_assoc_set_id(struct sctp_association *asoc, gfp_t gfp)
spin_lock_bh(&sctp_assocs_id_lock); spin_lock_bh(&sctp_assocs_id_lock);
error = idr_get_new_above(&sctp_assocs_id, (void *)asoc, error = idr_get_new_above(&sctp_assocs_id, (void *)asoc,
1, &assoc_id); idr_low, &assoc_id);
if (!error) {
idr_low = assoc_id + 1;
if (idr_low == INT_MAX)
idr_low = 1;
}
spin_unlock_bh(&sctp_assocs_id_lock); spin_unlock_bh(&sctp_assocs_id_lock);
if (error == -EAGAIN) if (error == -EAGAIN)
goto retry; goto retry;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment