]> git.itanic.dy.fi Git - linux-stable/commit
libceph: avoid truncation due to racing banners
authorJim Schutt <jaschut@sandia.gov>
Fri, 10 Aug 2012 17:37:38 +0000 (10:37 -0700)
committerSage Weil <sage@inktank.com>
Tue, 21 Aug 2012 22:55:27 +0000 (15:55 -0700)
commit6d4221b53707486dfad3f5bfe568d2ce7f4c9863
tree9c7bf7471219c98fb47faa3dbb68b8f31fedf3c3
parent6c5e50fa614fea5325a2973be06f7ec6f1055316
libceph: avoid truncation due to racing banners

Because the Ceph client messenger uses a non-blocking connect, it is
possible for the sending of the client banner to race with the
arrival of the banner sent by the peer.

When ceph_sock_state_change() notices the connect has completed, it
schedules work to process the socket via con_work().  During this
time the peer is writing its banner, and arrival of the peer banner
races with con_work().

If con_work() calls try_read() before the peer banner arrives, there
is nothing for it to do, after which con_work() calls try_write() to
send the client's banner.  In this case Ceph's protocol negotiation
can complete succesfully.

The server-side messenger immediately sends its banner and addresses
after accepting a connect request, *before* actually attempting to
read or verify the banner from the client.  As a result, it is
possible for the banner from the server to arrive before con_work()
calls try_read().  If that happens, try_read() will read the banner
and prepare protocol negotiation info via prepare_write_connect().
prepare_write_connect() calls con_out_kvec_reset(), which discards
the as-yet-unsent client banner.  Next, con_work() calls
try_write(), which sends the protocol negotiation info rather than
the banner that the peer is expecting.

The result is that the peer sees an invalid banner, and the client
reports "negotiation failed".

Fix this by moving con_out_kvec_reset() out of
prepare_write_connect() to its callers at all locations except the
one where the banner might still need to be sent.

[elder@inktak.com: added note about server-side behavior]

Signed-off-by: Jim Schutt <jaschut@sandia.gov>
Reviewed-by: Alex Elder <elder@inktank.com>
net/ceph/messenger.c