-
Notifications
You must be signed in to change notification settings - Fork 4.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
[Android] Fix app crash when using non-native HttpClientHandler #69565
[Android] Fix app crash when using non-native HttpClientHandler #69565
Conversation
Tagging subscribers to 'arch-android': @steveisok, @akoeplinger Issue DetailsHTTP requests done with System.Net.Http.HttpRequestException: The SSL connection could not be established, see inner exception.
---> System.NullReferenceException: Object reference not set to an instance of an object
at System.Net.CertificateValidationPal.GetRemoteCertificate(SafeDeleteContext securityContext, Boolean retrieveChainCertificates, X509Chain& chain)
at System.Net.CertificateValidationPal.GetRemoteCertificate(SafeDeleteContext securityContext)
at System.Net.Security.SslStream.SelectClientCertificate(Boolean& sessionRestartAttempt)
at System.Net.Security.SslStream.AcquireClientCredentials(Byte[]& thumbPrint)
at System.Net.Security.SslStream.GenerateToken(ReadOnlySpan`1 inputBuffer, Byte[]& output)
at System.Net.Security.SslStream.NextMessage(ReadOnlySpan`1 incomingBuffer)
at System.Net.Security.SslStream.<ForceAuthenticationAsync>d__144`1[[System.Net.Security.AsyncReadWriteAdapter, System.Net.Security, Version=7.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a]].MoveNext()
at System.Net.Http.ConnectHelper.EstablishSslConnectionAsync(SslClientAuthenticationOptions sslOptions, HttpRequestMessage request, Boolean async, Stream stream, CancellationToken cancellationToken)
--- End of inner exception stack trace ---
at System.Net.Http.ConnectHelper.EstablishSslConnectionAsync(SslClientAuthenticationOptions sslOptions, HttpRequestMessage request, Boolean async, Stream stream, CancellationToken cancellationToken)
at System.Net.Http.HttpConnectionPool.ConnectAsync(HttpRequestMessage request, Boolean async, CancellationToken cancellationToken)
at System.Net.Http.HttpConnectionPool.CreateHttp11ConnectionAsync(HttpRequestMessage request, Boolean async, CancellationToken cancellationToken)
at System.Net.Http.HttpConnectionPool.AddHttp11ConnectionAsync(QueueItem queueItem)
at System.Threading.Tasks.TaskCompletionSourceWithCancellation`1.<WaitWithCancellationAsync>d__1[[System.Net.Http.HttpConnection, System.Net.Http, Version=7.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a]].MoveNext()
at System.Net.Http.HttpConnectionPool.GetHttp11ConnectionAsync(HttpRequestMessage request, Boolean async, CancellationToken cancellationToken)
at System.Net.Http.HttpConnectionPool.SendWithVersionDetectionAndRetryAsync(HttpRequestMessage request, Boolean async, Boolean doRequestAuth, CancellationToken cancellationToken)
at System.Net.Http.RedirectHandler.SendAsync(HttpRequestMessage request, Boolean async, CancellationToken cancellationToken)
at System.Net.Http.HttpClient.<SendAsync>g__Core|83_0(HttpRequestMessage request, HttpCompletionOption completionOption, CancellationTokenSource cts, Boolean disposeCts, CancellationTokenSource pendingRequestsCts, CancellationToken originalCancellationToken)
at Program.<Main>$(String[] args) in /home/simon/dotnet/runtime/src/mono/sample/Android/Program.cs:line 12 There is a missing null check in Possibly also related to #69557
|
/azp run runtime-extra-platforms |
Azure Pipelines successfully started running 1 pipeline(s). |
@@ -46,7 +46,7 @@ internal static partial class CertificateValidationPal | |||
bool retrieveChainCertificates, | |||
ref X509Chain? chain) | |||
{ | |||
SafeSslHandle sslContext = ((SafeDeleteSslContext)securityContext).SslContext; | |||
SafeSslHandle? sslContext = ((SafeDeleteSslContext)securityContext)?.SslContext; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this shouldn't happen given that securityContext
isn't marked as nullable, which suggests to me something higher up the call chain is doing something unexpected.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The underlaying handle is nullable.
private SafeFreeCredentials? _credentialsHandle;
private SafeDeleteSslContext? _securityContext;
But is seems like it is like this for long time
runtime/src/libraries/System.Net.Security/src/System/Net/Security/SslStream.Protocol.cs
Line 254 in 3e5517b
remoteCert = CertificateValidationPal.GetRemoteCertificate(_securityContext!); |
Making the parameter nullable make sense to me. I think it will be null when we try to select client certificate before the handshake. cc: @rzikm
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The nullability annotations seem to be inconsistent across platforms:
- in the OSX version there's no
?
but there's a null check: https://github.com/dotnet/runtime/blob/main/src/libraries/System.Net.Security/src/System/Net/CertificateValidationPal.OSX.cs#L55 - in the Unix version there's a
?
and there's a null check: https://github.com/dotnet/runtime/blob/main/src/libraries/System.Net.Security/src/System/Net/CertificateValidationPal.Unix.cs#L31 - in the Windows version there's a
?
and there's a null check: https://github.com/dotnet/runtime/blob/main/src/libraries/System.Net.Security/src/System/Net/CertificateValidationPal.Windows.cs#L34
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok thanks, that sounds like indeed we're expecting a null securityContext
here and should make it consistent across platforms.
On a side note, #69527 removes the dual SafeHandle wrapping for Linux. We could do something similar for Android in future. |
/azp run runtime-extra-platforms |
Azure Pipelines successfully started running 1 pipeline(s). |
/azp run runtime-extra-platforms |
Azure Pipelines successfully started running 1 pipeline(s). |
…roid-certificate-validation-pal-null-reference-exception
/azp run outerloop-mono |
No pipelines are associated with this pull request. |
/azp run runtime-extra-platforms |
Azure Pipelines successfully started running 1 pipeline(s). |
/azp run runtime-libraries-mono outerloop |
Azure Pipelines successfully started running 1 pipeline(s). |
I re-enabled the functional tests for |
src/libraries/System.Net.Security/src/System/Net/CertificateValidationPal.Android.cs
Outdated
Show resolved
Hide resolved
/azp run runtime-libraries-mono outerloop |
Azure Pipelines successfully started running 1 pipeline(s). |
/azp run runtime-extra-platforms |
Azure Pipelines successfully started running 1 pipeline(s). |
I think this PR is now ready:
|
HTTP requests done with
HttpClient
+HttpClientHandler
caused Android apps to crash.For example, a simple HTTP request using the default
HttpClient
will throw an exception with the following stack trace:There is a missing null check in
CertificateValidationpal.Android.cs
which was removed recently (https://github.com/dotnet/runtime/pull/68188/files#diff-5f4278661dbb1331a13f14f1bf94b3a67e7474e8e4c32a21a99860f966ab02aeL66-L68).Possibly also related to #69557