dotnet / android

.NET for Android provides open-source bindings of the Android SDK for use with .NET managed languages such as C#
MIT License
1.91k stars 526 forks source link

Custom AndroidMessageHandler.ServerCertificateCustomValidationCallback that returns false may cause application crash while debugging. #8608

Open anton-yashin opened 8 months ago

anton-yashin commented 8 months ago

Android application type

.NET Android (net7.0-android, net8.0-android, etc.)

Affected platform version

VS2022 18.3 with .net 34.0.43/8.0.100

Description

When you using AndroidMessageHandler with ServerCertificateCustomValidationCallback that returns false while debugging you may get application crash.

Steps to Reproduce

  1. Create new android app with code like this Sample code:
    try
    {
    using (var ch = new AndroidMessageHandler())
    {
        ch.ServerCertificateCustomValidationCallback += (a, b, c, d) => false;
        using (var hc = new HttpClient(ch))
        {
            var result = await hc.GetAsync("https://github.com");
            // never get here
        }
    }
    }
    catch (Exception ex)
    {
    // may be get here
    XDebug.WriteLine($"exception handled {ex.Message}");
    }
  2. Run it several times. Two times in my case.
  3. Observe application crash. See sample project in attachment: UnhandledCertificateException.zip

Did you find any workaround?

No response

Relevant log output

No response

anton-yashin commented 8 months ago

You may run sample code more than one time to crash application. Debugger is required.

jpobst commented 8 months ago

To be clear, the issue is that the exception isn't caught, correct?

The exception is expected, but the catch handler isn't functioning.

anton-yashin commented 8 months ago

With VS2022 17.8.3 debugger it's going to crash application, after second time running sample code. Without debugger seems works fine. There something strange happens.

anton-yashin commented 8 months ago

With a debugger, it looks like a crash from an uncaught exception.

grendello commented 7 months ago

Please provide more information about the crash. We would need the following:

Any messages VS shows in either its output/debug/etc panes and screenshots of popup boxes (if any) it produces.

Full logcat of the application from the device/emulator. To record it, please follow the steps below:

  1. Open the VS Developer prompt. Do not start the application yet.
  2. Type the following commands one by one:
    1. adb shell setprop debug.mono.log default,assembly,mono_log_level=debug,mono_log_mask=all
    2. adb logcat -G 16M
    3. adb logcat -c
  3. Start the application from within VS and trigger the crash
  4. Back in the VS Developer prompt type: adb logcat -d > logcat.txt

Please attach logcat.txt and the requested VS messages/screenshots. Thanks!

anton-yashin commented 7 months ago

Here requested addtional info logcat.txt

grendello commented 7 months ago

Your sample uses an async void method which is invoked from an event handler - this is usually a bad idea (even though event handlers is the reason why async void unfortunately exists), because any exceptions thrown from the async void method may be unobserved, which may explain what you see. However, the real problem here appears to be what's happening behind the scenes, in Java.

AndroidMessageHandler uses the Java's HTTPUrlConnection class to do (almost) all the work, and something in that Java code crashes hard (with Unix signal 11, SEGFAULT, which usually means a null pointer is dereferenced). From the log you provided:

01-08 20:39:43.988  7336  7385 F libc    : Fatal signal 11 (SIGSEGV), code 128 (SI_KERNEL), fault addr 0x0 in tid 7385 (.NET TP Worker), pid 7336 (ficateException)
01-08 20:39:44.581  7419  7419 F DEBUG   : *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
01-08 20:39:44.581  7419  7419 F DEBUG   : Build fingerprint: 'google/sdk_gphone64_x86_64/emu64x:13/TE1A.220922.010/9219351:user/release-keys'
01-08 20:39:44.581  7419  7419 F DEBUG   : Revision: '0'
01-08 20:39:44.581  7419  7419 F DEBUG   : ABI: 'x86_64'
01-08 20:39:44.581  7419  7419 F DEBUG   : Timestamp: 2024-01-08 20:39:44.026116600+0400
01-08 20:39:44.581  7419  7419 F DEBUG   : Process uptime: 11s
01-08 20:39:44.581  7419  7419 F DEBUG   : Cmdline: com.companyname.UnhandledCertificateException
01-08 20:39:44.581  7419  7419 F DEBUG   : pid: 7336, tid: 7385, name: .NET TP Worker  >>> com.companyname.UnhandledCertificateException <<<
01-08 20:39:44.581  7419  7419 F DEBUG   : uid: 10163
01-08 20:39:44.581  7419  7419 F DEBUG   : signal 11 (SIGSEGV), code 128 (SI_KERNEL), fault addr 0x0000000000000000
01-08 20:39:44.581  7419  7419 F DEBUG   :     rax f4eddab62123c5c1  rbx 0000000000000000  rcx 00000000000000d0  rdx 00007a32cd5f8d70
01-08 20:39:44.581  7419  7419 F DEBUG   :     r8  000000000000f000  r9  0000000000000003  r10 0000000000000000  r11 0000000000000044
01-08 20:39:44.581  7419  7419 F DEBUG   :     r12 00007a32cd5f8ae8  r13 00007a32cd5f8ae8  r14 0000000000000000  r15 00007a32cd5f8a78
01-08 20:39:44.581  7419  7419 F DEBUG   :     rdi 131f78b870372728  rsi 131f78b870372728
01-08 20:39:44.581  7419  7419 F DEBUG   :     rbp 131f78b870372728  rsp 00007a32cd5f85b0  rip 00007a3342ff275c
01-08 20:39:44.581  7419  7419 F DEBUG   : backtrace:
01-08 20:39:44.581  7419  7419 F DEBUG   :       #00 pc 00000000003f275c  /apex/com.android.art/lib64/libart.so (art::ArtMethod::GetOatQuickMethodHeader(unsigned long)+28) (BuildId: 44bc52550248fc712a381bef164b75c7)
01-08 20:39:44.581  7419  7419 F DEBUG   :       #01 pc 00000000008177f1  /apex/com.android.art/lib64/libart.so (void art::StackVisitor::WalkStack<(art::StackVisitor::CountTransitions)0>(bool)+1761) (BuildId: 44bc52550248fc712a381bef164b75c7)
01-08 20:39:44.581  7419  7419 F DEBUG   :       #02 pc 000000000084ca59  /apex/com.android.art/lib64/libart.so (art::Thread::CreateInternalStackTrace(art::ScopedObjectAccessAlreadyRunnable const&) const+217) (BuildId: 44bc52550248fc712a381bef164b75c7)
01-08 20:39:44.581  7419  7419 F DEBUG   :       #03 pc 00000000007454b5  /apex/com.android.art/lib64/libart.so (art::Throwable_nativeFillInStackTrace(_JNIEnv*, _jclass*)+53) (BuildId: 44bc52550248fc712a381bef164b75c7)
01-08 20:39:44.582  7419  7419 F DEBUG   :       #04 pc 000000000009a712  /system/framework/x86_64/boot.oat (art_jni_trampoline+98) (BuildId: f2108335ca6c802e561cdde35cfac810207631cc)
01-08 20:39:44.582  7419  7419 F DEBUG   :       #05 pc 0000000000368c95  /apex/com.android.art/lib64/libart.so (nterp_helper+165) (BuildId: 44bc52550248fc712a381bef164b75c7)
01-08 20:39:44.582  7419  7419 F DEBUG   :       #06 pc 00000000000f6eb6  /apex/com.android.art/javalib/core-oj.jar (java.lang.Throwable.fillInStackTrace+18)
01-08 20:39:44.582  7419  7419 F DEBUG   :       #07 pc 0000000000369a88  /apex/com.android.art/lib64/libart.so (nterp_helper+3736) (BuildId: 44bc52550248fc712a381bef164b75c7)
01-08 20:39:44.582  7419  7419 F DEBUG   :       #08 pc 00000000000f7046  /apex/com.android.art/javalib/core-oj.jar (java.lang.Throwable.<init>+30)
01-08 20:39:44.582  7419  7419 F DEBUG   :       #09 pc 0000000000369a88  /apex/com.android.art/lib64/libart.so (nterp_helper+3736) (BuildId: 44bc52550248fc712a381bef164b75c7)
01-08 20:39:44.582  7419  7419 F DEBUG   :       #10 pc 00000000000e5f00  /apex/com.android.art/javalib/core-oj.jar (java.lang.Exception.<init>+0)
01-08 20:39:44.582  7419  7419 F DEBUG   :       #11 pc 0000000000369a88  /apex/com.android.art/lib64/libart.so (nterp_helper+3736) (BuildId: 44bc52550248fc712a381bef164b75c7)
01-08 20:39:44.582  7419  7419 F DEBUG   :       #12 pc 00000000000ed5b8  /apex/com.android.art/javalib/core-oj.jar (java.lang.RuntimeException.<init>+0)
01-08 20:39:44.583  7419  7419 F DEBUG   :       #13 pc 0000000000369a88  /apex/com.android.art/lib64/libart.so (nterp_helper+3736) (BuildId: 44bc52550248fc712a381bef164b75c7)
01-08 20:39:44.583  7419  7419 F DEBUG   :       #14 pc 000000000001cf98  /apex/com.android.art/javalib/core-libart.jar (android.system.GaiException.<init>+0)
01-08 20:39:44.583  7419  7419 F DEBUG   :       #15 pc 00000000003725c4  /apex/com.android.art/lib64/libart.so (art_quick_invoke_stub+756) (BuildId: 44bc52550248fc712a381bef164b75c7)
01-08 20:39:44.583  7419  7419 F DEBUG   :       #16 pc 00000000003f21a6  /apex/com.android.art/lib64/libart.so (art::ArtMethod::Invoke(art::Thread*, unsigned int*, unsigned int, art::JValue*, char const*)+214) (BuildId: 44bc52550248fc712a381bef164b75c7)
01-08 20:39:44.583  7419  7419 F DEBUG   :       #17 pc 00000000007e5531  /apex/com.android.art/lib64/libart.so (art::JValue art::InvokeWithVarArgs<art::ArtMethod*>(art::ScopedObjectAccessAlreadyRunnable const&, _jobject*, art::ArtMethod*, __va_list_tag*)+465) (BuildId: 44bc52550248fc712a381bef164b75c7)
01-08 20:39:44.583  7419  7419 F DEBUG   :       #18 pc 00000000006982ce  /apex/com.android.art/lib64/libart.so (art::JNI<true>::CallNonvirtualVoidMethodV(_JNIEnv*, _jobject*, _jclass*, _jmethodID*, __va_list_tag*)+686) (BuildId: 44bc52550248fc712a381bef164b75c7)
01-08 20:39:44.583  7419  7419 F DEBUG   :       #19 pc 000000000067affd  /apex/com.android.art/lib64/libart.so (art::JNI<true>::NewObjectV(_JNIEnv*, _jclass*, _jmethodID*, __va_list_tag*)+765) (BuildId: 44bc52550248fc712a381bef164b75c7)
01-08 20:39:44.583  7419  7419 F DEBUG   :       #20 pc 00000000005d937e  /apex/com.android.art/lib64/libart.so (art::(anonymous namespace)::CheckJNI::NewObjectV(_JNIEnv*, _jclass*, _jmethodID*, __va_list_tag*) (.llvm.10455603497705050653)+1710) (BuildId: 44bc52550248fc712a381bef164b75c7)
01-08 20:39:44.583  7419  7419 F DEBUG   :       #21 pc 0000000000016294  /apex/com.android.art/lib64/libjavacore.so (_JNIEnv::NewObject(_jclass*, _jmethodID*, ...)+164) (BuildId: c35ec8837201af12447a1dc5d0afe7bf)
01-08 20:39:44.583  7419  7419 F DEBUG   :       #22 pc 0000000000030cfc  /apex/com.android.art/lib64/libjavacore.so (throwGaiException(_JNIEnv*, char const*, int)+332) (BuildId: c35ec8837201af12447a1dc5d0afe7bf)
01-08 20:39:44.583  7419  7419 F DEBUG   :       #23 pc 00000000000240b3  /apex/com.android.art/lib64/libjavacore.so (Linux_android_getaddrinfo(_JNIEnv*, _jobject*, _jstring*, _jobject*, int)+339) (BuildId: c35ec8837201af12447a1dc5d0afe7bf)
01-08 20:39:44.583  7419  7419 F DEBUG   :       #24 pc 00000000000135b6  /system/framework/x86_64/boot-core-libart.oat (art_jni_trampoline+166) (BuildId: 46f5f6ae0a40c7a1a01db626bd31379ffa487d80)
01-08 20:39:44.583  7419  7419 F DEBUG   :       #25 pc 000000000036af7d  /apex/com.android.art/lib64/libart.so (nterp_helper+9101) (BuildId: 44bc52550248fc712a381bef164b75c7)
01-08 20:39:44.583  7419  7419 F DEBUG   :       #26 pc 0000000000036c10  /apex/com.android.art/javalib/core-libart.jar (libcore.io.ForwardingOs.android_getaddrinfo+4)
01-08 20:39:44.583  7419  7419 F DEBUG   :       #27 pc 0000000000369a88  /apex/com.android.art/lib64/libart.so (nterp_helper+3736) (BuildId: 44bc52550248fc712a381bef164b75c7)
01-08 20:39:44.583  7419  7419 F DEBUG   :       #28 pc 00000000000357de  /apex/com.android.art/javalib/core-libart.jar (libcore.io.BlockGuardOs.android_getaddrinfo+38)
01-08 20:39:44.583  7419  7419 F DEBUG   :       #29 pc 000000000036af7d  /apex/com.android.art/lib64/libart.so (nterp_helper+9101) (BuildId: 44bc52550248fc712a381bef164b75c7)
01-08 20:39:44.583  7419  7419 F DEBUG   :       #30 pc 0000000000036c10  /apex/com.android.art/javalib/core-libart.jar (libcore.io.ForwardingOs.android_getaddrinfo+4)
01-08 20:39:44.583  7419  7419 F DEBUG   :       #31 pc 000000000036af7d  /apex/com.android.art/lib64/libart.so (nterp_helper+9101) (BuildId: 44bc52550248fc712a381bef164b75c7)
01-08 20:39:44.583  7419  7419 F DEBUG   :       #32 pc 000000000003a2c2  /apex/com.android.art/javalib/core-libart.jar (libcore.net.InetAddressUtils.parseNumericAddressNoThrow+26)
01-08 20:39:44.583  7419  7419 F DEBUG   :       #33 pc 0000000000368c28  /apex/com.android.art/lib64/libart.so (nterp_helper+56) (BuildId: 44bc52550248fc712a381bef164b75c7)
01-08 20:39:44.583  7419  7419 F DEBUG   :       #34 pc 000000000003a342  /apex/com.android.art/javalib/core-libart.jar (libcore.net.InetAddressUtils.parseNumericAddressNoThrowStripOptionalBrackets+70)
01-08 20:39:44.583  7419  7419 F DEBUG   :       #35 pc 0000000000368c28  /apex/com.android.art/lib64/libart.so (nterp_helper+56) (BuildId: 44bc52550248fc712a381bef164b75c7)
01-08 20:39:44.583  7419  7419 F DEBUG   :       #36 pc 0000000000121c26  /apex/com.android.art/javalib/core-oj.jar (java.net.Inet6AddressImpl.lookupAllHostAddr+18)
01-08 20:39:44.583  7419  7419 F DEBUG   :       #37 pc 000000000036a7e5  /apex/com.android.art/lib64/libart.so (nterp_helper+7157) (BuildId: 44bc52550248fc712a381bef164b75c7)
01-08 20:39:44.583  7419  7419 F DEBUG   :       #38 pc 00000000001230a2  /apex/com.android.art/javalib/core-oj.jar (java.net.InetAddress.getAllByName+6)
01-08 20:39:44.583  7419  7419 F DEBUG   :       #39 pc 0000000000368c28  /apex/com.android.art/lib64/libart.so (nterp_helper+56) (BuildId: 44bc52550248fc712a381bef164b75c7)
01-08 20:39:44.583  7419  7419 F DEBUG   :       #40 pc 0000000000016944  /apex/com.android.art/javalib/okhttp.jar (com.android.okhttp.Dns$1.lookup+4)
01-08 20:39:44.583  7419  7419 F DEBUG   :       #41 pc 000000000036a7e5  /apex/com.android.art/lib64/libart.so (nterp_helper+7157) (BuildId: 44bc52550248fc712a381bef164b75c7)
01-08 20:39:44.583  7419  7419 F DEBUG   :       #42 pc 000000000002e3fa  /apex/com.android.art/javalib/okhttp.jar (com.android.okhttp.internal.http.RouteSelector.resetNextInetSocketAddress+234)
01-08 20:39:44.583  7419  7419 F DEBUG   :       #43 pc 0000000000369a88  /apex/com.android.art/lib64/libart.so (nterp_helper+3736) (BuildId: 44bc52550248fc712a381bef164b75c7)
01-08 20:39:44.583  7419  7419 F DEBUG   :       #44 pc 000000000002e1c8  /apex/com.android.art/javalib/okhttp.jar (com.android.okhttp.internal.http.RouteSelector.nextProxy+40)
01-08 20:39:44.583  7419  7419 F DEBUG   :       #45 pc 0000000000369a88  /apex/com.android.art/lib64/libart.so (nterp_helper+3736) (BuildId: 44bc52550248fc712a381bef164b75c7)
01-08 20:39:44.583  7419  7419 F DEBUG   :       #46 pc 000000000002e05a  /apex/com.android.art/javalib/okhttp.jar (com.android.okhttp.internal.http.RouteSelector.next+58)
01-08 20:39:44.583  7419  7419 F DEBUG   :       #47 pc 0000000000369a88  /apex/com.android.art/lib64/libart.so (nterp_helper+3736) (BuildId: 44bc52550248fc712a381bef164b75c7)
01-08 20:39:44.583  7419  7419 F DEBUG   :       #48 pc 000000000002eb16  /apex/com.android.art/javalib/okhttp.jar (com.android.okhttp.internal.http.StreamAllocation.findConnection+122)
01-08 20:39:44.583  7419  7419 F DEBUG   :       #49 pc 0000000000369a88  /apex/com.android.art/lib64/libart.so (nterp_helper+3736) (BuildId: 44bc52550248fc712a381bef164b75c7)
01-08 20:39:44.583  7419  7419 F DEBUG   :       #50 pc 000000000002ec0c  /apex/com.android.art/javalib/okhttp.jar (com.android.okhttp.internal.http.StreamAllocation.findHealthyConnection+0)
01-08 20:39:44.583  7419  7419 F DEBUG   :       #51 pc 000000000036a23e  /apex/com.android.art/lib64/libart.so (nterp_helper+5710) (BuildId: 44bc52550248fc712a381bef164b75c7)
01-08 20:39:44.583  7419  7419 F DEBUG   :       #52 pc 000000000002e970  /apex/com.android.art/javalib/okhttp.jar (com.android.okhttp.internal.http.StreamAllocation.newStream+0)
01-08 20:39:44.583  7419  7419 F DEBUG   :       #53 pc 000000000036a23e  /apex/com.android.art/lib64/libart.so (nterp_helper+5710) (BuildId: 44bc52550248fc712a381bef164b75c7)
01-08 20:39:44.583  7419  7419 F DEBUG   :       #54 pc 000000000002c95c  /apex/com.android.art/javalib/okhttp.jar (com.android.okhttp.internal.http.HttpEngine.connect+80)
01-08 20:39:44.584  7419  7419 F DEBUG   :       #55 pc 0000000000369a88  /apex/com.android.art/lib64/libart.so (nterp_helper+3736) (BuildId: 44bc52550248fc712a381bef164b75c7)
01-08 20:39:44.584  7419  7419 F DEBUG   :       #56 pc 000000000002cf52  /apex/com.android.art/javalib/okhttp.jar (com.android.okhttp.internal.http.HttpEngine.sendRequest+162)
01-08 20:39:44.584  7419  7419 F DEBUG   :       #57 pc 0000000000369a88  /apex/com.android.art/lib64/libart.so (nterp_helper+3736) (BuildId: 44bc52550248fc712a381bef164b75c7)
01-08 20:39:44.584  7419  7419 F DEBUG   :       #58 pc 000000000002f8fa  /apex/com.android.art/javalib/okhttp.jar (com.android.okhttp.internal.huc.HttpURLConnectionImpl.execute+42)
01-08 20:39:44.584  7419  7419 F DEBUG   :       #59 pc 0000000000369a88  /apex/com.android.art/lib64/libart.so (nterp_helper+3736) (BuildId: 44bc52550248fc712a381bef164b75c7)
01-08 20:39:44.584  7419  7419 F DEBUG   :       #60 pc 00000000000304ec  /apex/com.android.art/javalib/okhttp.jar (com.android.okhttp.internal.huc.HttpURLConnectionImpl.connect+8)
01-08 20:39:44.584  7419  7419 F DEBUG   :       #61 pc 0000000000369a88  /apex/com.android.art/lib64/libart.so (nterp_helper+3736) (BuildId: 44bc52550248fc712a381bef164b75c7)
01-08 20:39:44.584  7419  7419 F DEBUG   :       #62 pc 000000000002f72e  /apex/com.android.art/javalib/okhttp.jar (com.android.okhttp.internal.huc.DelegatingHttpsURLConnection.connect+10)
01-08 20:39:44.584  7419  7419 F DEBUG   :       #63 pc 0000000000369a88  /apex/com.android.art/lib64/libart.so (nterp_helper+3736) (BuildId: 44bc52550248fc712a381bef164b75c7)
01-08 20:39:44.584  7419  7419 F DEBUG   :       #64 pc 0000000000030ec4  /apex/com.android.art/javalib/okhttp.jar (com.android.okhttp.internal.huc.HttpsURLConnectionImpl.connect+0)
01-08 20:39:44.584  7419  7419 F DEBUG   :       #65 pc 00000000003725c4  /apex/com.android.art/lib64/libart.so (art_quick_invoke_stub+756) (BuildId: 44bc52550248fc712a381bef164b75c7)
01-08 20:39:44.584  7419  7419 F DEBUG   :       #66 pc 00000000003f21a6  /apex/com.android.art/lib64/libart.so (art::ArtMethod::Invoke(art::Thread*, unsigned int*, unsigned int, art::JValue*, char const*)+214) (BuildId: 44bc52550248fc712a381bef164b75c7)
01-08 20:39:44.584  7419  7419 F DEBUG   :       #67 pc 00000000007e617e  /apex/com.android.art/lib64/libart.so (art::JValue art::InvokeVirtualOrInterfaceWithJValues<art::ArtMethod*>(art::ScopedObjectAccessAlreadyRunnable const&, _jobject*, art::ArtMethod*, jvalue const*)+478) (BuildId: 44bc52550248fc712a381bef164b75c7)
01-08 20:39:44.584  7419  7419 F DEBUG   :       #68 pc 000000000068ad0e  /apex/com.android.art/lib64/libart.so (art::JNI<true>::CallVoidMethodA(_JNIEnv*, _jobject*, _jmethodID*, jvalue const*)+686) (BuildId: 44bc52550248fc712a381bef164b75c7)
01-08 20:39:44.584  7419  7419 F DEBUG   :       #69 pc 00000000005eecc9  /apex/com.android.art/lib64/libart.so (art::(anonymous namespace)::CheckJNI::CallMethodA(char const*, _JNIEnv*, _jobject*, _jclass*, _jmethodID*, jvalue const*, art::Primitive::Type, art::InvokeType)+1113) (BuildId: 44bc52550248fc712a381bef164b75c7)
01-08 20:39:44.584  7419  7419 F DEBUG   :       #70 pc 00000000005db86e  /apex/com.android.art/lib64/libart.so (art::(anonymous namespace)::CheckJNI::CallVoidMethodA(_JNIEnv*, _jobject*, _jmethodID*, jvalue const*) (.llvm.10455603497705050653)+30) (BuildId: 44bc52550248fc712a381bef164b75c7)
01-08 20:39:44.584  7419  7419 F DEBUG   :       #71 pc 00000000001e9357  /data/app/~~NIO25ksNdK7gH8lwr9Fr_g==/com.companyname.UnhandledCertificateException-6V7Yp8NDnBKxyUtFcTvvOQ==/lib/x86_64/libmonosgen-2.0.so (BuildId: a633b3f7182399187aa4927ab67e7bde259ed3cf)
01-08 20:39:44.584  7419  7419 F DEBUG   :       #72 pc 00000000001e7d60  /data/app/~~NIO25ksNdK7gH8lwr9Fr_g==/com.companyname.UnhandledCertificateException-6V7Yp8NDnBKxyUtFcTvvOQ==/lib/x86_64/libmonosgen-2.0.so (BuildId: a633b3f7182399187aa4927ab67e7bde259ed3cf)
01-08 20:39:44.584  7419  7419 F DEBUG   :       #73 pc 00000000001d9154  /data/app/~~NIO25ksNdK7gH8lwr9Fr_g==/com.companyname.UnhandledCertificateException-6V7Yp8NDnBKxyUtFcTvvOQ==/lib/x86_64/libmonosgen-2.0.so (BuildId: a633b3f7182399187aa4927ab67e7bde259ed3cf)
01-08 20:39:44.584  7419  7419 F DEBUG   :       #74 pc 00000000001d6a81  /data/app/~~NIO25ksNdK7gH8lwr9Fr_g==/com.companyname.UnhandledCertificateException-6V7Yp8NDnBKxyUtFcTvvOQ==/lib/x86_64/libmonosgen-2.0.so (BuildId: a633b3f7182399187aa4927ab67e7bde259ed3cf)
01-08 20:39:44.584  7419  7419 F DEBUG   :       #75 pc 00000000000e589f  /data/app/~~NIO25ksNdK7gH8lwr9Fr_g==/com.companyname.UnhandledCertificateException-6V7Yp8NDnBKxyUtFcTvvOQ==/lib/x86_64/libmonosgen-2.0.so (BuildId: a633b3f7182399187aa4927ab67e7bde259ed3cf)
01-08 20:39:44.584  7419  7419 F DEBUG   :       #76 pc 00000000002a8b87  /data/app/~~NIO25ksNdK7gH8lwr9Fr_g==/com.companyname.UnhandledCertificateException-6V7Yp8NDnBKxyUtFcTvvOQ==/lib/x86_64/libmonosgen-2.0.so (mono_runtime_invoke_checked+135) (BuildId: a633b3f7182399187aa4927ab67e7bde259ed3cf)
01-08 20:39:44.584  7419  7419 F DEBUG   :       #77 pc 00000000002c0263  /data/app/~~NIO25ksNdK7gH8lwr9Fr_g==/com.companyname.UnhandledCertificateException-6V7Yp8NDnBKxyUtFcTvvOQ==/lib/x86_64/libmonosgen-2.0.so (BuildId: a633b3f7182399187aa4927ab67e7bde259ed3cf)
01-08 20:39:44.584  7419  7419 F DEBUG   :       #78 pc 00000000000ccd2a  /apex/com.android.runtime/lib64/bionic/libc.so (__pthread_start(void*)+58) (BuildId: 007cb2313464df63debf8020e631c990)

It might be a bug on the Java side for this particular scenario, or something we don't handle well in our use of the certificate manager.

@simonrozsival you have more experience and knowledge about this topic than I do, would you be able to look at this issue? Thanks!

simonrozsival commented 7 months ago

@grendello I'll have a look

simonrozsival commented 7 months ago

My observations:

  1. I tap on the button that triggers DoWork
  2. The debugger shows that a threadpool thread is paused because of an unhandled exception - the top of the stack trace is monodroid_debugger_unhandled_exception image
  3. After continuing execution, my breakpoint is triggered (correctly shows the caught exception)
  4. After tapping the button again, or even just waiting for ~10 seconds, the app crashes

It seems to me that the exception thrown in the TrustManager (https://github.com/xamarin/xamarin-android/blob/main/src/Mono.Android/Xamarin.Android.Net/ServerCertificateCustomValidator.cs#L73) leaves the thread pool thread in an invalid state when debugging and when we try to run some other Task on the thread, the app crashes.

If I understand how the Java interop layer works correctly, the exception is transformed from .NET exception to a matching Java exception when transitioning to Java (https://learn.microsoft.com/en-us/dotnet/api/javax.security.cert.certificateexception?view=xamarin-android-sdk-13). Is it possible that this transition from .NET to Java context breaks when debugging?

jonpryor commented 7 months ago

@anton-yashin: does it crash in a Release configuration app or when not debugging the app?

Cross-VM exception handling in Debug builds is potentially brittle; see also:

From https://github.com/xamarin/xamarin-android/issues/4548#issuecomment-614376712, if you have a managed method M1() invoke a Java method j1() which invokes a managed method M2(), and M2() throws, then:

…when a debugger isn't attached … then at every managed-to-Java invocation boundary we catch every exception, then set a "pending exception" … which wraps the caught exception, then return to Java. This allows Java to raise the exception on its side, and allow any Java-side catch blocks to work. When a debugger is attached, we never handle exceptions at the VM boundaries, so that there can be an "unhandled exception" for the IDE to report.

Emphasis added.

The abort you're seeing could be explaind by the JVM callstack being correupted when M1() catches an exception, unwinding j1() without Java being involved, which is Bad™.

Your app still fails when not debugging, that would suggest something else is going on, but right now, I believe it's because of our altered exception handling behavior when the debugger is attached.

anton-yashin commented 7 months ago

@jonpryor: This only happens if the debugger is attached. In release and without debugger seems fine.

jonpryor commented 7 months ago

@anton-yashin wrote:

This only happens if the debugger is attached. In release and without debugger seems fine.

Then as I feared, the only "fix" for now is to not have an unhandled first-chance C# exception, and your having ch.ServerCertificateCustomValidationCallback return false forces a C# exception.

Unfortunately, as per @simonrozsival's image, the exception is being thrown from X509TrustManager.checkServerTrusted(), which is supposed to throw an exception when the server isn't trusted, which happens when (among other reasons) ch.ServerCertificateCustomValidationCallback returns false:

https://github.com/xamarin/xamarin-android/blob/5c29ee4c575f0285670cf793b1f35d9fef603f4c/src/Mono.Android/Xamarin.Android.Net/ServerCertificateCustomValidator.cs#L72-L74

This can't be easily fixed without additional runtime support.

anton-yashin commented 7 months ago

Thanks for your time.

gkarabin commented 2 months ago

My team seems to be running into this. Are there any other related tickets open?

We are just getting organized to look into this. Is there anything we could do to help move things along?

simonrozsival commented 2 months ago

This can't be easily fixed without additional runtime support.

Would it be possible to raise the Java exception directly through some JNI helper in ServerCertificateCustomValidator without throwing it in C# first? Would we be able to avoid hitting the uncaught exception handler code?