Skip to content
This repository
Browse code

Check the Content-Length before reading the request's content

Some browsers, like Firefox, do not support files that are larger than 2GB.
Uploading a >2GB file causes an integer overflow and the Content-Length
header is set to a negative value.

To prevent any crash in this case, we check the Content-Length value before
reading the request's content. When the value is negative, an error 400 is
returned.

A bug about this problem is openned for Firefox:
    - https://bugzilla.mozilla.org/show_bug.cgi?id=215450
  • Loading branch information...
commit 02e9baf30bad679ffa6b649add06d97999a223bf 1 parent c74a92e
Christopher Faulet authored April 26, 2012

Showing 1 changed file with 14 additions and 4 deletions. Show diff stats Hide diff stats

  1. 18  src/yaws_server.erl
18  src/yaws_server.erl
@@ -1513,7 +1513,7 @@ body_method(CliSock, IPPort, Req, Head) ->
1513 1513
     SC=get(sc),
1514 1514
     ok = yaws:setopts(CliSock, [{packet, raw}, binary], yaws:is_ssl(SC)),
1515 1515
     PPS = SC#sconf.partial_post_size,
1516  
-    Bin = case Head#headers.content_length of
  1516
+    Res = case Head#headers.content_length of
1517 1517
               undefined ->
1518 1518
                   case Head#headers.transfer_encoding of
1519 1519
                       "chunked" ->
@@ -1524,6 +1524,8 @@ body_method(CliSock, IPPort, Req, Head) ->
1524 1524
               Len when is_integer(PPS) ->
1525 1525
                   Int_len = list_to_integer(Len),
1526 1526
                   if
  1527
+                      Int_len < 0 ->
  1528
+                          {error, content_length_overflow};
1527 1529
                       Int_len == 0 ->
1528 1530
                           <<>>;
1529 1531
                       PPS < Int_len ->
@@ -1536,6 +1538,8 @@ body_method(CliSock, IPPort, Req, Head) ->
1536 1538
               Len when PPS == nolimit ->
1537 1539
                   Int_len = list_to_integer(Len),
1538 1540
                   if
  1541
+                      Int_len < 0 ->
  1542
+                          {error, content_length_overflow};
1539 1543
                       Int_len == 0 ->
1540 1544
                           <<>>;
1541 1545
                       true ->
@@ -1543,9 +1547,15 @@ body_method(CliSock, IPPort, Req, Head) ->
1543 1547
                                           yaws:is_ssl(SC))
1544 1548
                   end
1545 1549
           end,
1546  
-    ?Debug("Request data = ~s~n", [binary_to_list(un_partial(Bin))]),
1547  
-    ARG = make_arg(CliSock, IPPort, Head, Req, Bin),
1548  
-    handle_request(CliSock, ARG, size(un_partial(Bin))).
  1550
+    case Res of
  1551
+        {error, Reason} ->
  1552
+            error_logger:format("Invalid Request: ~p~n", [Reason]),
  1553
+            deliver_400(CliSock, Req);
  1554
+        Bin ->
  1555
+            ?Debug("Request data = ~s~n", [binary_to_list(un_partial(Bin))]),
  1556
+            ARG = make_arg(CliSock, IPPort, Head, Req, Bin),
  1557
+            handle_request(CliSock, ARG, size(un_partial(Bin)))
  1558
+    end.
1549 1559
 
1550 1560
 
1551 1561
 'MKCOL'(CliSock, IPPort, Req, Head) ->

0 notes on commit 02e9baf

Please sign in to comment.
Something went wrong with that request. Please try again.