<html>
  <head>
    <meta content="text/html; charset=ISO-8859-1"
      http-equiv="Content-Type">
  </head>
  <body bgcolor="#FFFFFF" text="#000000">
    Hello Christopher,<br>
    <br>
    The reason behind favoring the async threads is that non-blocking
    sendfile calls on some OSs sometimes behave incorrectly.
    Unfortunately at the moment I cannot remember which OS it was, but
    it is none of the majorly used ones. <br>
    <br>
    It is of course not good that this feature opens up the VM for that
    kind of attack. <br>
    <br>
    My suggestion of a fix would be to add an option to sendfile/5 that
    specifies whether async threads should be used or not, and default
    this to false. This leaves the choice up to the user of sendfile/5
    and defaults to be safe from attacks. <br>
    <br>
    Thanks for reporting this quite serious flaw in the sendfile
    implementation!<br>
    <br>
    Lukas<br>
    <br>
    <div class="moz-cite-prefix">On 21/10/13 15:02, Christopher Faulet
      wrote:<br>
    </div>
    <blockquote cite="mid:526525CF.5020202@capflam.org" type="cite">
      <pre wrap="">Hi,

This summer, at my company, we encountered a problem that leads to the
VM hanging. After some painful investigation, we found that the problem
came from the <a class="moz-txt-link-freetext" href="file:sendfile/5">file:sendfile/5</a> function.

When async threads are enabled, during a call to <a class="moz-txt-link-freetext" href="file:sendfile/5">file:sendfile/5</a> the
efile driver sets the TCP socket in blocking mode. So an unresponsive
client can block the sendfile() syscall, thus blocking an async thread.
With few unresponsive clients, all async threads can be blocked and the
VM hangs (no more I/O are possible).

I attached 2 escripts to reproduce the bug:

* server - listen on a socket and wait a client connection to send a
large file using gen_tcp:send or <a class="moz-txt-link-freetext" href="file:sendfile">file:sendfile</a>:

  $> ./server 1234 /path/to/bigfile send
or
  $> ./server 1234 /path/to/bigfile sendfile

* slow_client - open a connection on the server and read incoming data
with a sleep of 10 seconds between each read:

  $> ./slow_client 127.0.0.1 1234

The server is started with 1 async thread. Every 2 seconds the server
tries to read the file info. When "sendfile" method is used, the call to
<a class="moz-txt-link-freetext" href="file:read_file_info/1">file:read_file_info/1</a> is blocked; all I/O are blocked, the VM is out.
When async threads are disabled or when the "send" method is used, there
is no problem. The file is sent (slowly) and the VM is still responsive.

So it is very easy to do a DOS attack on systems that use
<a class="moz-txt-link-freetext" href="file:sendfile/5">file:sendfile/5</a> with async threads enabled. The problem comes from a
design choice of the efile driver. I have no solution to propose, but it
could be a good idea to add a warning in the documentation of
<a class="moz-txt-link-freetext" href="file:sendfile/5">file:sendfile/5</a> (especially that the documentation encourages the use of
async threads).

Regards,
</pre>
      <br>
      <fieldset class="mimeAttachmentHeader"></fieldset>
      <br>
      <pre wrap="">_______________________________________________
erlang-bugs mailing list
<a class="moz-txt-link-abbreviated" href="mailto:erlang-bugs@erlang.org">erlang-bugs@erlang.org</a>
<a class="moz-txt-link-freetext" href="http://erlang.org/mailman/listinfo/erlang-bugs">http://erlang.org/mailman/listinfo/erlang-bugs</a>
</pre>
    </blockquote>
    <br>
  </body>
</html>