[lkml]   [2009]   [Feb]   [10]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
Messages in this thread
    Patch in this message
    Subject[patch 55/56] sctp: Fix another socket race during accept/peeloff
    2.6.27-stable review patch.  If anyone has any objections, please let us know.

    From: Vlad Yasevich <>

    commit ae53b5bd77719fed58086c5be60ce4f22bffe1c6 upstream.

    There is a race between sctp_rcv() and sctp_accept() where we
    have moved the association from the listening socket to the
    accepted socket, but sctp_rcv() processing cached the old
    socket and continues to use it.

    The easy solution is to check for the socket mismatch once we've
    grabed the socket lock. If we hit a mis-match, that means
    that were are currently holding the lock on the listening socket,
    but the association is refrencing a newly accepted socket. We need
    to drop the lock on the old socket and grab the lock on the new one.

    A more proper solution might be to create accepted sockets when
    the new association is established, similar to TCP. That would
    eliminate the race for 1-to-1 style sockets, but it would still
    existing for 1-to-many sockets where a user wished to peeloff an
    association. For now, we'll live with this easy solution as
    it addresses the problem.

    Reported-by: Michal Hocko <>
    Reported-by: Karsten Keil <>
    Signed-off-by: Vlad Yasevich <>
    Signed-off-by: David S. Miller <>
    Signed-off-by: Greg Kroah-Hartman <>

    net/sctp/input.c | 13 +++++++++++++
    1 file changed, 13 insertions(+)

    --- a/net/sctp/input.c
    +++ b/net/sctp/input.c
    @@ -249,6 +249,19 @@ int sctp_rcv(struct sk_buff *skb)

    + if (sk != rcvr->sk) {
    + /* Our cached sk is different from the rcvr->sk. This is
    + * because migrate()/accept() may have moved the association
    + * to a new socket and released all the sockets. So now we
    + * are holding a lock on the old socket while the user may
    + * be doing something with the new socket. Switch our veiw
    + * of the current sk.
    + */
    + sctp_bh_unlock_sock(sk);
    + sk = rcvr->sk;
    + sctp_bh_lock_sock(sk);
    + }
    if (sock_owned_by_user(sk)) {
    sctp_add_backlog(sk, skb);

     \ /
      Last update: 2009-02-11 01:51    [W:0.043 / U:16.104 seconds]
    ©2003-2017 Jasper Spaans. hosted at Digital OceanAdvertise on this site