Skip to content
This repository was archived by the owner on Nov 20, 2018. It is now read-only.

LOH fragmentation when user post form with section content more than 85KB #597

Closed
yuwaMSFT opened this issue Mar 25, 2016 · 11 comments
Closed

Comments

@yuwaMSFT
Copy link

yuwaMSFT commented Mar 25, 2016

Post a multipart form with content more than 85KB in each section would cause heavy LOH fragmentation in MVC app.

Post a multipart form with 100 sections, each containing random sized content with an average of 120KB.

After the first request:

_         segment             begin         allocated              size
0000021c56c50000  0000021c56c51000  0000021c582fa2a0  0x16a92a0(23761568)
Total Size:              Size: 0x1f0bcb8 (32554168) bytes.
Statistics:
              MT    Count    TotalSize Class Name
0000021c46a5d8e0      **107         3204      **Free
00007ffbbe854418        9       146136 System.Object[]
00007ffbbe84e210       16      2097536 System.Byte[]
00007ffbbe862498      ** 81     21514154 **System.String
_

After the 2nd request:

_Large object heap starts at 0x0000021c56c51000
         segment             begin         allocated              size
0000021c56c50000  0000021c56c51000  0000021c5983f700  0x2bee700(46065408)
Statistics:
              MT    Count    TotalSize Class Name
0000021c46a5d8e0      **194         5814      **Free
00007ffbbe854418        9       146136 System.Object[]
00007ffbbe84e210       22      2884112 System.Byte[]
00007ffbbe862498      **162     43028308 **System.String
_

After the 3rd request:

_Large object heap starts at 0x0000021c56c51000
         segment             begin         allocated              size
0000021c56c50000  0000021c56c51000  0000021c5983f700  0x2bee700(46065408)
Total Size:              Size: 0x362f488 (56816776) bytes.
Statistics:
              MT    Count    TotalSize Class Name
0000021c46a5d8e0     ** 276         8274      **Free
00007ffbbe854418        9       146136 System.Object[]
00007ffbbe84e210       23      3015208 System.Byte[]
00007ffbbe862498     ** 243     64542462 **System.String_

So for each request we are adding the large string in LOH for each section (field) of the form. Also, look at the "Free" type. They are mostly 30 bytes in LOH accompany each large string. It may be some string interning.

For the string object, basically we are reading each section (field) into a string:

_                        else if (HasFormDataContentDisposition(contentDisposition))
                        {
                            // Content-Disposition: form-data; name="key"
                            //
                            // value

                            var key = HeaderUtilities.RemoveQuotes(contentDisposition.Name);
                            MediaTypeHeaderValue mediaType;
                            MediaTypeHeaderValue.TryParse(section.ContentType, out mediaType);
                            var encoding = FilterEncoding(mediaType?.Encoding);
                            using (var reader = new StreamReader(section.Body, encoding, detectEncodingFromByteOrderMarks: true, bufferSize: 1024, leaveOpen: true))
                            {
                                **var value = await reader.ReadToEndAsync**();
                                formAccumulator.Append(key, value);
                            }
                        }_

This can be easily explored to cause the server to run OOM. Security concern as well.

@yuwaMSFT
Copy link
Author

@sajayantony
Copy link
Member

@yuwaMSFT Does the LOH fragmentation cause OOM or crash?

@Tratcher
Copy link
Member

Related: #583

@yuwaMSFT
Copy link
Author

yuwaMSFT commented Mar 25, 2016

It causes the memory to accumulate. At some point it will cause OOM (and the app would crash on exception of memory allocation or killed by OOM killer before that happens).

The LOH looks like below:
0000021c5a90d830 0000021c46a5d8e0       30 Free
0000021c5a90d850 00007ffbbe862498   353606     
0000021c5a963d98 0000021c46a5d8e0       30 Free
0000021c5a963db8 00007ffbbe862498   289318     
0000021c5a9aa7e0 0000021c46a5d8e0       30 Free
0000021c5a9aa800 00007ffbbe862498   474146     
0000021c5aa1e428 0000021c46a5d8e0       30 Free
0000021c5aa1e448 00007ffbbe862498   345570     
0000021c5aa72a30 0000021c46a5d8e0       30 Free
0000021c5aa72a50 00007ffbbe862498   297354     
0000021c5aabb3e0 0000021c46a5d8e0       30 Free
0000021c5aabb400 00007ffbbe862498   208958     
0000021c5aaee440 0000021c46a5d8e0       30 Free
0000021c5aaee460 00007ffbbe862498   112526     
0000021c5ab09bf0 0000021c46a5d8e0       30 Free
0000021c5ab09c10 00007ffbbe862498   305390     
0000021c5ab54500 0000021c46a5d8e0       30 Free
0000021c5ab54520 00007ffbbe862498   249138     
0000021c5ab91258 0000021c46a5d8e0       30 Free
0000021c5ab91278 00007ffbbe862498   241102     
0000021c5abcc048 0000021c46a5d8e0       30 Free
0000021c5abcc068 00007ffbbe862498   305390     
0000021c5ac16958 0000021c46a5d8e0       30 Free
0000021c5ac16978 00007ffbbe862498   216994     
0000021c5ac4b920 0000021c46a5d8e0       30 Free
0000021c5ac4b940 00007ffbbe862498   233066     
0000021c5ac847b0 0000021c46a5d8e0       30 Free
0000021c5ac847d0 00007ffbbe862498   136634     
0000021c5aca5d90 0000021c46a5d8e0       30 Free
0000021c5aca5db0 00007ffbbe862498   257174  

@yuwaMSFT
Copy link
Author

Related to #583 but different issue. This is easier to be explored as a security concern.

@blowdart
Copy link
Member

Ouchie :( And I think you're right, this is certainly a potential DoS concern (as is 583)

@muratg muratg added this to the 1.0.0 milestone Apr 5, 2016
@muratg
Copy link

muratg commented Apr 5, 2016

@blowdart need to fix this?

@blowdart
Copy link
Member

blowdart commented Apr 5, 2016

Yes. If it's spiking memory so badly the app pool will recycle then it's a DoS

@muratg muratg added the bug label Apr 6, 2016
@muratg muratg modified the milestones: 1.0.1, 1.0.0 May 25, 2016
@muratg
Copy link

muratg commented Jul 6, 2016

@yuwaMSFT Do you know if this is still an issue?

@yuwaMSFT
Copy link
Author

yuwaMSFT commented Jul 6, 2016

I checked the latest code. It seems to still have the same issue for multipart form data content.
We seems to only apply KeyLengthLimit and ValueLengthLimit (which is 4MB anyway) to urlencodedform but not multipart-form. The only guard for multipart-form is the MultipartBodyLengthLimit which is by default 128MB. So I believe the same issue still exists.

@aspnet-hello
Copy link

This issue was moved to dotnet/aspnetcore#2720

@aspnet aspnet locked and limited conversation to collaborators Jan 2, 2018
@aspnet-hello aspnet-hello removed this from the Backlog milestone Jan 2, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

8 participants