Subject: [Tsvwg] SCTP Partial delivery vulnerability example / solutions

From: Mark Butler <[email-masked]>
Date: Thu, 01 Dec 2005 22:25:26 -0700

Here is an example that demonstrates the vulnerability of SCTP partial 
delivery on a one-to-many socket (as in LKSCTP, no stream 
interleaving).  Suppose you decided to adapt SMTP to SCTP.  SMTP is a 
message oriented protocol where reasonably sized messages predominate, 
so you decide to do a one-to-one SMTP messages to SCTP message mapping 
with a few other control messages.

Then you have an implementation choice - you can either do  a 
connect/accept/fork style server using one-to-one sockets or a simpler 
design that uses one or more worker threads to read messages from a 
shared one-to-many socket.  You choose the latter, set a large socket 
buffer size, and start processing messages.

Occasionally, a much longer than usual message overflows the buffer, 
causing a partial delivery of the first portion of the message. This 
causes the stack to lock the socket against further reads from any other 
association (pd_mode = 1 in lksctp).  Normally the rest of the message 
arrives in a fraction of a second, and no one notices.  However, on 
occasion the SMTP sender crashes or has its network connection fail 
while a partial delivery is pending.  In that situation, other clients 
can establish new associations with the server, but no messages can be 
delivered until the stack times out the failed association, and aborts 
the partial delivery, a process that probably takes about thirty 
seconds.   Thirty second delays may be fine for MTA - MTA transfers, but 
are not acceptable for MUA - MTA transfers.  Most mail user agents time 
out after about five seconds.

One solution might be to use smaller abort timeouts.  However, anything 
reasonable will either abort slow clients unnecessarily (wasting 
resources and multiplying the number of in-doubt message transactions) 
or greatly increase delivery latency and multiply buffer space 
requirements on a busy MTA.    And creating a number of associations 
that stall mid message on purpose would make for a very effective denial 
of service attack on a public MTA with a shared socket.

Of course SMTP is an extraordinarily relaxed environment compared to 
something like an LDAP server.  A typical LDAP server might have 
thousands of clients and low millisecond reponse time requirements.  
With a single one-to-many server socket the stalling problem becomes 
much more serious.

LDAP has relatively low request lengths, and so SOCK_DGRAM code over a 
reliable transport like SCTP would be trivial.  Even UDP with client 
retransmission timers (e.g. DNS) is easier to support than the 
extraneous code required to operate a one-to-many socket server reliably 
with the api as it stands.

Granted, the SOCK_DGRAM style only works with ULPs that allow restricted 
message lengths, an in addition the stack has to truncate or discard 
messages beyond some specified threshold, but the atomic message 
operations make things much easier where those requirements are 
acceptable, a domain that covers a very broad span of upper layer protocols.

Latency sensitive applications that need to support very large messages 
from multiple clients must use listen()/accept() and some form of thread 
dispatch.  sctp_peeloff() almost works, but would do nothing to prevent 
DoS attacks without message length limitations on the primary socket. 

Here are four ways to avoid the problem with one-to-many sockets:

 1) An option (or socket type) to allow applications to get SOCK_DGRAM 
semantics where restricted message lengths are acceptable. (A new socket 
type might be required to get different semantics on BSD kernels.)

 2) An option to allow applications to reassemble stream fragments 
(where necessary) at the application layer, instead of blocking across 
associations. (SCTP_STREAM_FRAGMENT).

 3) Write server code to use one-to-one sockets instead.

 4)  Set the association abort timeouts low enough to mitigate the 
stalling problem, and doing the necessary event handling in the 
application to avoid silently gluing unrelated messages together. 
(Perhaps a final zero length fragment tagged with MSG_TRUNC and MSG_EOR 
would solve the latter problem).

I believe SCTP has greater potential as a next generation UDP than a 
next generation TCP, and supporting the SOCK_DGRAM programming model 
would go a great distance toward achieving that goal.

 - Mark

_______________________________________________
tsvwg mailing list
[email-masked]
https://www1.ietf.org/mailman/listinfo/tsvwg