-
Notifications
You must be signed in to change notification settings - Fork 3.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Mono.Net.Security.MonoTlsStream: Crash when stream appears to have already been disposed #15805
Comments
/cc @steveisok |
Sounds suspiciously similar to #10488. If that is the case then updating to newer version should resolve the issue. |
Yeah, it does. @baulig, please confirm. |
I reviewed the code and it turns out that we're actually lacking a Apart from that, I don't see how we could possibly throw here. Do you have any test case or some way to reproduce this? |
Unfortunately, I don't have a reproducible test at the moment. We've been running for the past couple of weeks with a custom build of Mono in our Xamarin apps that uses a simple null check, which has eliminated this particular crash. Naturally I'd prefer not to have to resort to that permanently. :) |
I am also having the same crash. I don't know about how we can do it in our solution. As mono is the part of .net framework. Is it open source and we can modify directly? Hope solution will come in next release of mono. |
Also experiencing the same crash here. It look's like we'll have to wait until the next release of Xamarin.iOS to use the latest mono and see if this fixes this crash. |
We too are experiencing this issue. Crashyltics is reporting that it has affected over 1000 users over the past week, so it seems to be a pretty significant issue for us. @tdiehl, can you elaborate regarding how you were able to use your patched version of Mono in your Xamarin.iOS app? |
We just upgraded to the latest and greatest versions of Xamarin iOS and Mono but are still seeing this issue. Any idea on when this fix might get included in a new build of Mono? |
@baulig The dispose fix should be in stable. Can you please do another pass on this issue. |
@steveisok, thanks for the update. Does @tdiehl 's workaround of adding the null check need to be included in the next build in addition to the dispose fix that @baulig worked on in order to fully resolve this issue? |
@pachecosoftware according to the PR @baulig merged, the null check is unnecessary. https://github.com/mono/mono/pull/16233/files#r314017987 If I'm understanding your comments correctly, you're seeing otherwise? |
@steveisok, Thanks for providing the link to the PR. I'm admittedly not familiar with the code in question, but after reading through the comments and looking through the before and after versions of the code, I'm still a bit confused on how adding the missing sslStream.Dispose() (on line 145 in the latest version of the code) solves the underlying issue that @tdiehl was addressing with his patch to work around the situation where somehow the sslStream is null inside the finally block (now refactored to be part of the catch block). One way I could see that the sslStream variable could potentially be null is if the call to provider.CreateSslStream (networkStream, false, settings) on line 107 ever returns null. That scenario would set the sslStream variable to null on 107, presumably causing a NullReferenceException to be thrown on line 117, which would be caught by the catch block on line 125, but the sslStream variable would remain null and throw another NullReferenceException on line 135. I'm not sure if it's possible for any implementation of the MonoTlsProvider to return null, but if it is, then it would seem that we would still need a null check at line 135 to guard against that scenario? |
Adds a null check around the sslStream before trying to dispose.
We updated to the latest stable in Visual Studio 8.3 and still see the issue, though the NRE is now thrown at line 135. I'm in the process of building a custom version of xamarin-macios and applying the same null check on the Applying this patch does however appear to cause another slightly different crash, one appears to maybe be here. Finally, we still don't have a consistent repro of the issue. However, we have occasionally seen the problem happen while debugging within Xcode (we have a hybrid app). I'm attaching some screenshots as they show the complete stack trace as well as some additional logs. The problem appears to possibly be related to timed out requests. |
I've looked at that code over and over again and while @steveisok's #17270 certainly doesn't hurt, it is also completely unnecessary - as to whether or not might potentially be damaging, I'm not sure about that. That And then in the entire body of that method, However, we are seeing people complain about NRE's in that method, so we need to think outside the box here. And in fact, there is one scenario where this actually could happen - but unfortunately we don't have enough information about it at the moment. So instead of landing @steveisok's PR, I would suggest to test a theory instead - it won't make the problem go away, but it will make the crashes more verbose and also confirm my theory. The only scenario in which This function is clearly designed to be called only once and it's especially not reentrant. Hypothetically if one thread is in that To protect against this scenario - and to confirm my hypothesis - I suggest that we add some What do you think? |
@baulig, were you able to make your proposed change? If this truly is a multi-threading issue, do we have any idea how this particular scenario could be happening? @tdiehl has suggested that perhaps it's related to requests timing out? In our app, we are reusing a single instance of HttpClient throughout the app and there are undoubtedly multiple threads making requests simultaneously. We have the timeout value set to 20 seconds. We are also using the Xamarin.FFImageLoading for image loading/caching, which is itself making HTTPS requests to load images, and I believe its default timeout value is 15 seconds. |
This hits our apps every so often. After reading the code it does seem like a race condition between one thread creating the stream and another thread disposing the stream. That is, For us, this can happen if there are comms issues and there is a forced cleanup of objects to cancel a pending request. In this particular case though it appears to happen either internally to mono or from a 3rd party library. @steveisok Had the right idea, but the fix only reduces the likelihood of the occurrence thanks to the null check, there is still the slight possibility of instruction pointers on two threads lining up such that both null checks pass and then one thread disposes and assigns null, and then the other thread tries to dispose and crashes. I think that fix plus some locking would fix the issue. |
@jahmai Thanks for your thoughts and I agree that seems like what is happening. I suspect mono/mcs/class/System/System.Net/WebConnection.cs Lines 419 to 446 in 450d474
|
The tricky thing about NullReferenceExceptions is that exception trapping libraries like Crashlytics actually treat them as fatal signals so you can't even catch them in managed code. |
@jahmai, as you noted, this issue has been especially frustrating because despite adding all kinds of exception handling to our app around network interactions, the app crashes rather than propagating the exception so that our code can handle it. @steveisok, are there plans to modify your fix (#17270) to add locking? Beyond that, is there an ETA on getting this released? We continue to get complaints from our users who keep running into this issue. |
Yes, we will address this soon. I don't have an ETA at this time. |
Thanks, @steveisok! |
Adds a null check around the sslStream before trying to dispose.
@baulig and @steveisok, I checked out the commit for this fix but didn't see any additional locking added as @jahmai suggested above to avoid any potential race conditions involving two threads entering the null check at the same time. Did you just think the likelihood of this occurring was so small that it didn't justify the potential performance hit locking could introduce? |
@pachecosoftware I asked @baulig to have a quick follow up PR as I think it's pretty cheap to get in even though the likelihood is small |
@steveisok Sounds great! Thanks! Is there any kind of ETA for when Mono 6.6.0 will be ready for release? |
Changes: mono/api-snapshot@fc50bc4...45a61d9 $ git diff --shortstat fc50bc4f...45a61d93 22 files changed, 775 insertions(+), 474 deletions(-) Changes: dotnet/cecil@a6c8f5e...a6a7f5c $ git diff --shortstat a6c8f5e1...a6a7f5c0 55 files changed, 818 insertions(+), 530 deletions(-) Changes: mono/corefx@1f87de3...49f1c45 $ git diff --shortstat e4f7102b...49f1c453 38 files changed, 1171 insertions(+), 419 deletions(-) Changes: dotnet/linker@ebe2a1f...e8d054b $ git diff --shortstat ebe2a1f4...e8d054bf 137 files changed, 5360 insertions(+), 1781 deletions(-) Changes: mono/mono@8946e49...18920a8 $ git diff --shortstat 8946e49a...18920a83 1811 files changed, 47240 insertions(+), 48331 deletions(-) Changes: xamarin/xamarin-android-api-compatibility@a61271e...50a3c52 $ git diff --shortstat a61271e0...50a3c52d 1 file changed, 2 insertions(+), 791 deletions(-) Fixes: #3619 Context: https://dev.azure.com/devdiv/DevDiv/_workitems/edit/1005448 Context: https://devdiv.visualstudio.com/DefaultCollection/DevDiv/_workitems/edit/967582 Context: https://github.com/dotnet/coreclr/issues/26370 Context: https://github.com/dotnet/coreclr/issues/26479 Context: https://github.com/dotnet/corefx/issues/40455 Context: https://github.com/dotnet/corefx/issues/40578 Context: mono/mono#7377 Context: mono/mono#12421 Context: mono/mono#12586 Context: mono/mono#14080 Context: mono/mono#14725 Context: mono/mono#14772 Context: mono/mono#15261 Context: mono/mono#15262 Context: mono/mono#15263 Context: mono/mono#15307 Context: mono/mono#15308 Context: mono/mono#15310 Context: mono/mono#15646 Context: mono/mono#15687 Context: mono/mono#15805 Context: mono/mono#15992 Context: mono/mono#15994 Context: mono/mono#15999 Context: mono/mono#16032 Context: mono/mono#16034 Context: mono/mono#16046 Context: mono/mono#16192 Context: mono/mono#16308 Context: mono/mono#16310 Context: mono/mono#16369 Context: mono/mono#16380 Context: mono/mono#16381 Context: mono/mono#16395 Context: mono/mono#16411 Context: mono/mono#16415 Context: mono/mono#16486 Context: mono/mono#16570 Context: mono/mono#16605 Context: mono/mono#16616 Context: mono/mono#16689 Context: mono/mono#16701 Context: mono/mono#16712 Context: mono/mono#16742 Context: mono/mono#16759 Context: mono/mono#16803 Context: mono/mono#16808 Context: mono/mono#16824 Context: mono/mono#16876 Context: mono/mono#16879 Context: mono/mono#16918 Context: mono/mono#16943 Context: mono/mono#16950 Context: mono/mono#16974 Context: mono/mono#17004 Context: mono/mono#17017 Context: mono/mono#17038 Context: mono/mono#17040 Context: mono/mono#17083 Context: mono/mono#17084 Context: mono/mono#17133 Context: mono/mono#17139 Context: mono/mono#17151 Context: mono/mono#17180 Context: mono/mono#17278 Context: mono/mono#17549 Context: mono/mono#17569 Context: mono/mono#17665 Context: mono/mono#17687 Context: mono/mono#17737 Context: mono/mono#17790 Context: mono/mono#17924 Context: mono/mono#17931 Context: https://github.com/mono/mono/issues/26758 Context: https://github.com/mono/mono/issues/37913 Context: dotnet/macios#7005
Changes: mono/api-snapshot@fc50bc4...45a61d9 $ git diff --shortstat fc50bc4f...45a61d93 22 files changed, 775 insertions(+), 474 deletions(-) Changes: dotnet/cecil@a6c8f5e...a6a7f5c $ git diff --shortstat a6c8f5e1...a6a7f5c0 55 files changed, 818 insertions(+), 530 deletions(-) Changes: mono/corefx@1f87de3...49f1c45 $ git diff --shortstat e4f7102b...49f1c453 38 files changed, 1171 insertions(+), 419 deletions(-) Changes: dotnet/linker@ebe2a1f...e8d054b $ git diff --shortstat ebe2a1f4...e8d054bf 137 files changed, 5360 insertions(+), 1781 deletions(-) Changes: mono/mono@8946e49...18920a8 $ git diff --shortstat 8946e49a...18920a83 1811 files changed, 47240 insertions(+), 48331 deletions(-) Changes: xamarin/xamarin-android-api-compatibility@a61271e...50a3c52 $ git diff --shortstat a61271e0...50a3c52d 1 file changed, 2 insertions(+), 791 deletions(-) Fixes: #3619 Context: https://dev.azure.com/devdiv/DevDiv/_workitems/edit/1005448 Context: https://devdiv.visualstudio.com/DefaultCollection/DevDiv/_workitems/edit/967582 Context: https://github.com/dotnet/coreclr/issues/26370 Context: https://github.com/dotnet/coreclr/issues/26479 Context: https://github.com/dotnet/corefx/issues/40455 Context: https://github.com/dotnet/corefx/issues/40578 Context: mono/mono#7377 Context: mono/mono#12421 Context: mono/mono#12586 Context: mono/mono#14080 Context: mono/mono#14725 Context: mono/mono#14772 Context: mono/mono#15261 Context: mono/mono#15262 Context: mono/mono#15263 Context: mono/mono#15307 Context: mono/mono#15308 Context: mono/mono#15310 Context: mono/mono#15646 Context: mono/mono#15687 Context: mono/mono#15805 Context: mono/mono#15992 Context: mono/mono#15994 Context: mono/mono#15999 Context: mono/mono#16032 Context: mono/mono#16034 Context: mono/mono#16046 Context: mono/mono#16192 Context: mono/mono#16308 Context: mono/mono#16310 Context: mono/mono#16369 Context: mono/mono#16380 Context: mono/mono#16381 Context: mono/mono#16395 Context: mono/mono#16411 Context: mono/mono#16415 Context: mono/mono#16486 Context: mono/mono#16570 Context: mono/mono#16605 Context: mono/mono#16616 Context: mono/mono#16689 Context: mono/mono#16701 Context: mono/mono#16712 Context: mono/mono#16742 Context: mono/mono#16759 Context: mono/mono#16803 Context: mono/mono#16808 Context: mono/mono#16824 Context: mono/mono#16876 Context: mono/mono#16879 Context: mono/mono#16918 Context: mono/mono#16943 Context: mono/mono#16950 Context: mono/mono#16974 Context: mono/mono#17004 Context: mono/mono#17017 Context: mono/mono#17038 Context: mono/mono#17040 Context: mono/mono#17083 Context: mono/mono#17084 Context: mono/mono#17133 Context: mono/mono#17139 Context: mono/mono#17151 Context: mono/mono#17180 Context: mono/mono#17278 Context: mono/mono#17549 Context: mono/mono#17569 Context: mono/mono#17665 Context: mono/mono#17687 Context: mono/mono#17737 Context: mono/mono#17790 Context: mono/mono#17924 Context: mono/mono#17931 Context: https://github.com/mono/mono/issues/26758 Context: https://github.com/mono/mono/issues/37913 Context: dotnet/macios#7005
Seems this has been closed without any defense against race conditions? |
Speaking of Mono 6.6.0 this issue isn't listed as being resolved in the mono 6.6.0 release https://www.mono-project.com/docs/about-mono/releases/6.6.0/. Was it included in that release or are we looking at a later release to include the fix? |
@ppvictory We merged this into 2019-10, which is mono 6.8.0. When that version is released, we will include the fix in the release notes. |
@baulig there's still a potential race condition in mono/mcs/class/System/Mono.Net.Security/MonoTlsStream.cs Lines 159 to 163 in 56f397b
If two threads call |
Calling Yes, one could add some |
@baulig That's not the problem. The problem is one thread calling |
Which is not something you'd ever encounter in real life at all. But if it's so important to you, feel free to make a PR. |
Explain. This issue is predicated on a thread race condition between two threads attempting to destroy the sslStream concurrently. The fix narrows the chances but doesn’t eliminate it. |
I opened a PR adding some locking: #18250 |
@akoeplinger Thanks so much for adding this. This bug was wreaking havoc in our app, so I ended up building a custom version of Mono adding in what is essentially identical code to what you have in your PR and it has eliminated the incidence of this issue for us. |
Thank you so much for this and my apologies for being so rude to both of you earlier on. |
See #15805 (comment) (cherry picked from commit c8e19be)
See #15805 (comment) (cherry picked from commit c8e19be)
@pachecosoftware thanks for the confirmation, good to hear that the PR should fix the issue. I merged it and backported to our 2019-10 branch (== Mono 6.8) so it should get into that release. Xamarin.iOS is also currently tracking that branch for the VS 16.5 release. |
Changes: mono/api-snapshot@6f14e43...8ea1d66 $ git diff --shortstat 6f14e433...8ea1d663 21 files changed, 719 insertions(+), 444 deletions(-) Changes: mono/boringssl@4ca62c5...d7b108e $ git diff --shortstat 4ca62c57...d7b108ee 1 file changed, 1 insertion(+) Changes: dotnet/cecil@cb6c1ca...a6a7f5c $ git diff --shortstat cb6c1ca9...a6a7f5c0 47 files changed, 587 insertions(+), 444 deletions(-) Changes: mono/corefx@10a41e9...5940515 $ git diff --shortstat 10a41e9f...59405155 55 files changed, 1382 insertions(+), 369 deletions(-) Changes: mono/mono@18920a8...2edccc5 $ git diff --shortstat 18920a83...2edccc52 1393 files changed, 44742 insertions(+), 90381 deletions(-) Context: https://dev.azure.com/devdiv/DevDiv/_workitems/edit/1005448 Context: https://dev.azure.com/devdiv/DevDiv/_workitems/edit/1005448 Context: KSP-CKAN/CKAN#2881 Context: mono/mono#10559 Context: mono/mono#12249 Context: mono/mono#12337 Context: mono/mono#12995 Context: mono/mono#13777 Context: mono/mono#15006 Context: mono/mono#15010 Context: mono/mono#15181 Context: mono/mono#15805 Context: mono/mono#15845 Context: mono/mono#16026 Context: mono/mono#16206 Context: mono/mono#16410 Context: mono/mono#16513 Context: mono/mono#16557 Context: mono/mono#16588 Context: mono/mono#16632 Context: mono/mono#16701 Context: mono/mono#16778 Context: mono/mono#17053 Context: mono/mono#17084 Context: mono/mono#17133 Context: mono/mono#17151 Context: mono/mono#17161 Context: mono/mono#17190 Context: mono/mono#17278 Context: mono/mono#17278 Context: mono/mono#17317 Context: mono/mono#17367 Context: mono/mono#17389 Context: mono/mono#17546 Context: mono/mono#17549 Context: mono/mono#17569 Context: mono/mono#17601 Context: mono/mono#17665 Context: mono/mono#17687 Context: mono/mono#17737 Context: mono/mono#17790 Context: mono/mono#17869 Context: mono/mono#17878 Context: mono/mono#17916 Context: mono/mono#17924 Context: mono/mono#17926 Context: mono/mono#17931 Context: mono/mono#18213 Context: mono/mono#18221 Context: mono/mono#18273 Context: mono/mono#18276 Context: mono/mono#18317 Context: mono/mono#18388 Context: mono/mono#18455
Steps to Reproduce
Unfortunately I don't yet have a reproducible case, we are observing this crash in production release of an Xamarin iOS app.
Current Behavior
We are getting crashes
MonoTlsStream
when the stream is being disposed here.I suspect the behavior may be because of a timeout or some work being cancelled, perhaps causing the stream to be disposed here first.
Expected Behavior
No crash.
On which platforms did you notice this
[x] iOS
[ ] macOS
[ ] Linux
[ ] Windows
Version Used:
Mono JIT compiler version 5.18.1.28 (2018-08/223ea7ef92e Tue May 21 12:03:39 EDT 2019)
Copyright (C) 2002-2014 Novell, Inc, Xamarin Inc and Contributors. www.mono-project.com
TLS:
SIGSEGV: altstack
Notification: kqueue
Architecture: amd64
Disabled: none
Misc: softdebug
Interpreter: yes
LLVM: yes(600)
Suspend: preemptive
GC: sgen (concurrent by default)
Stacktrace
The text was updated successfully, but these errors were encountered: