Skip to content

Commit

Permalink
Use function pointers for interop (Unix) (#43793)
Browse files Browse the repository at this point in the history
  • Loading branch information
jkotas authored Oct 25, 2020
1 parent 0e402bc commit f93c0e6
Show file tree
Hide file tree
Showing 14 changed files with 43 additions and 89 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,6 @@ internal struct SCDynamicStoreContext
public CFStringRef CopyDescriptionFunc;
}

internal delegate void SCDynamicStoreCallBack(
SCDynamicStoreRef store,
CFArrayRef changedKeys,
IntPtr info);

/// <summary>
/// Creates a new session used to interact with the dynamic store maintained by the System Configuration server.
/// Follows the "Create Rule" where if you create it, you delete it.
Expand All @@ -43,7 +38,7 @@ internal delegate void SCDynamicStoreCallBack(
private static extern unsafe SafeCreateHandle SCDynamicStoreCreate(
IntPtr allocator,
CFStringRef name,
SCDynamicStoreCallBack callout,
delegate* unmanaged<SCDynamicStoreRef, CFArrayRef, IntPtr, void> callout,
SCDynamicStoreContext* context);

/// <summary>
Expand All @@ -55,7 +50,10 @@ private static extern unsafe SafeCreateHandle SCDynamicStoreCreate(
/// Pass null if no callouts are desired.</param>
/// <param name="context">The context associated with the callout.</param>
/// <returns>A reference to the new dynamic store session.</returns>
internal static unsafe SafeCreateHandle SCDynamicStoreCreate(CFStringRef name, SCDynamicStoreCallBack callout, SCDynamicStoreContext* context)
internal static unsafe SafeCreateHandle SCDynamicStoreCreate(
CFStringRef name,
delegate* unmanaged<SCDynamicStoreRef, CFArrayRef, IntPtr, void> callout,
SCDynamicStoreContext* context)
{
return SCDynamicStoreCreate(IntPtr.Zero, name, callout, context);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,9 @@ internal enum CtrlCode
Break = 1
}

internal delegate void CtrlCallback(CtrlCode ctrlCode);

[DllImport(Libraries.SystemNative, EntryPoint = "SystemNative_RegisterForCtrl")]
[SuppressGCTransition]
internal static extern void RegisterForCtrl(CtrlCallback handler);
internal static extern unsafe void RegisterForCtrl(delegate* unmanaged<CtrlCode, void> handler);

[DllImport(Libraries.SystemNative, EntryPoint = "SystemNative_UnregisterForCtrl")]
[SuppressGCTransition]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,7 @@ internal partial class Interop
{
internal partial class Sys
{
internal delegate void SigChldCallback(bool reapAll);

[DllImport(Libraries.SystemNative, EntryPoint = "SystemNative_RegisterForSigChld")]
internal static extern void RegisterForSigChld(SigChldCallback handler);
internal static extern unsafe void RegisterForSigChld(delegate* unmanaged<int, void> handler);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,8 @@ internal partial class Interop
{
internal partial class Sys
{
internal delegate void TerminalInvalidationCallback();

[DllImport(Libraries.SystemNative, EntryPoint = "SystemNative_SetTerminalInvalidationHandler")]
[SuppressGCTransition]
internal static extern void SetTerminalInvalidationHandler(TerminalInvalidationCallback handler);
internal static extern unsafe void SetTerminalInvalidationHandler(delegate* unmanaged<void> handler);
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

#nullable enable
using System;
using System.Buffers;
using System.Collections.Generic;
Expand All @@ -22,8 +21,6 @@ internal static partial class Interop
{
internal static partial class OpenSsl
{
private static readonly Ssl.SslCtxSetVerifyCallback s_verifyClientCertificate = VerifyClientCertificate;
private static readonly unsafe Ssl.SslCtxSetAlpnCallback s_alpnServerCallback = AlpnServerSelectCallback;
private static readonly IdnMapping s_idnMapping = new IdnMapping();

#region internal methods
Expand Down Expand Up @@ -156,7 +153,10 @@ internal static SafeSslHandle AllocateSslContext(SslProtocols protocols, SafeX50

if (sslAuthenticationOptions.IsServer && sslAuthenticationOptions.RemoteCertRequired)
{
Ssl.SslCtxSetVerify(innerContext, s_verifyClientCertificate);
unsafe
{
Ssl.SslCtxSetVerify(innerContext, &VerifyClientCertificate);
}
}

GCHandle alpnHandle = default;
Expand All @@ -167,7 +167,11 @@ internal static SafeSslHandle AllocateSslContext(SslProtocols protocols, SafeX50
if (sslAuthenticationOptions.IsServer)
{
alpnHandle = GCHandle.Alloc(sslAuthenticationOptions.ApplicationProtocols);
Interop.Ssl.SslCtxSetAlpnSelectCb(innerContext, s_alpnServerCallback, GCHandle.ToIntPtr(alpnHandle));

unsafe
{
Interop.Ssl.SslCtxSetAlpnSelectCb(innerContext, &AlpnServerSelectCallback, GCHandle.ToIntPtr(alpnHandle));
}
}
else
{
Expand Down Expand Up @@ -430,6 +434,7 @@ private static void QueryUniqueChannelBinding(SafeSslHandle context, SafeChannel
bindingHandle.SetCertHashLength(certHashLength);
}

[UnmanagedCallersOnly]
private static int VerifyClientCertificate(int preverify_ok, IntPtr x509_ctx_ptr)
{
// Full validation is handled after the handshake in VerifyCertificateProperties and the
Expand All @@ -440,10 +445,11 @@ private static int VerifyClientCertificate(int preverify_ok, IntPtr x509_ctx_ptr
return OpenSslSuccess;
}

private static unsafe int AlpnServerSelectCallback(IntPtr ssl, out byte* outp, out byte outlen, byte* inp, uint inlen, IntPtr arg)
[UnmanagedCallersOnly]
private static unsafe int AlpnServerSelectCallback(IntPtr ssl, byte** outp, byte* outlen, byte* inp, uint inlen, IntPtr arg)
{
outp = null;
outlen = 0;
*outp = null;
*outlen = 0;

GCHandle protocolHandle = GCHandle.FromIntPtr(arg);
if (!(protocolHandle.Target is List<SslApplicationProtocol> protocolList))
Expand All @@ -462,8 +468,8 @@ private static unsafe int AlpnServerSelectCallback(IntPtr ssl, out byte* outp, o
Span<byte> clientProto = clientList.Slice(1, length);
if (clientProto.SequenceEqual(protocolList[i].Protocol.Span))
{
fixed (byte* p = &MemoryMarshal.GetReference(clientProto)) outp = p;
outlen = length;
fixed (byte* p = &MemoryMarshal.GetReference(clientProto)) *outp = p;
*outlen = length;
return Ssl.SSL_TLSEXT_ERR_OK;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,6 @@ internal static partial class Ssl
internal const int SSL_TLSEXT_ERR_ALERT_FATAL = 2;
internal const int SSL_TLSEXT_ERR_NOACK = 3;

internal delegate int SslCtxSetVerifyCallback(int preverify_ok, IntPtr x509_ctx);

[DllImport(Libraries.CryptoNative, EntryPoint = "CryptoNative_EnsureLibSslInitialized")]
internal static extern void EnsureLibSslInitialized();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,27 +12,17 @@ internal static partial class Interop
{
internal static partial class Ssl
{
internal delegate int AppVerifyCallback(IntPtr storeCtx, IntPtr arg);
internal delegate int ClientCertCallback(IntPtr ssl, out IntPtr x509, out IntPtr pkey);
internal unsafe delegate int SslCtxSetAlpnCallback(IntPtr ssl, out byte* outp, out byte outlen, byte* inp, uint inlen, IntPtr arg);

[DllImport(Libraries.CryptoNative, EntryPoint = "CryptoNative_SslCtxCreate")]
internal static extern SafeSslContextHandle SslCtxCreate(IntPtr method);

[DllImport(Libraries.CryptoNative, EntryPoint = "CryptoNative_SslCtxDestroy")]
internal static extern void SslCtxDestroy(IntPtr ctx);

[DllImport(Libraries.CryptoNative, EntryPoint = "CryptoNative_SslCtxSetCertVerifyCallback")]
internal static extern void SslCtxSetCertVerifyCallback(IntPtr ctx, AppVerifyCallback cb, IntPtr arg);

[DllImport(Libraries.CryptoNative, EntryPoint = "CryptoNative_SslCtxSetClientCertCallback")]
internal static extern void SslCtxSetClientCertCallback(IntPtr ctx, ClientCertCallback callback);

[DllImport(Libraries.CryptoNative, EntryPoint = "CryptoNative_SslCtxSetAlpnProtos")]
internal static extern int SslCtxSetAlpnProtos(SafeSslContextHandle ctx, IntPtr protos, int len);

[DllImport(Libraries.CryptoNative, EntryPoint = "CryptoNative_SslCtxSetAlpnSelectCb")]
internal static extern void SslCtxSetAlpnSelectCb(SafeSslContextHandle ctx, SslCtxSetAlpnCallback callback, IntPtr arg);
internal static extern unsafe void SslCtxSetAlpnSelectCb(SafeSslContextHandle ctx, delegate* unmanaged<IntPtr, byte**, byte*, byte*, uint, IntPtr, int> callback, IntPtr arg);

internal static unsafe int SslCtxSetAlpnProtos(SafeSslContextHandle ctx, List<SslApplicationProtocol> protocols)
{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System;
using System.Net.Security;
using System.Runtime.InteropServices;
using System.Security.Cryptography;
Expand All @@ -23,7 +24,7 @@ internal static partial class Ssl
internal static extern void SslCtxSetQuietShutdown(SafeSslContextHandle ctx);

[DllImport(Libraries.CryptoNative, EntryPoint = "CryptoNative_SslCtxSetVerify")]
internal static extern void SslCtxSetVerify(SafeSslContextHandle ctx, SslCtxSetVerifyCallback callback);
internal static extern unsafe void SslCtxSetVerify(SafeSslContextHandle ctx, delegate* unmanaged<int, IntPtr, int> callback);

[DllImport(Libraries.CryptoNative, EntryPoint = "CryptoNative_SetCiphers")]
internal static extern unsafe bool SetCiphers(SafeSslContextHandle ctx, byte* cipherList, byte* cipherSuites);
Expand Down
7 changes: 1 addition & 6 deletions src/libraries/Native/Unix/System.Native/pal_mount.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
#endif
#endif

static int32_t GetMountInfo(MountPointFound onFound)
int32_t SystemNative_GetAllMountPoints(MountPointFound onFound)
{
#if HAVE_MNTINFO
// getmntinfo returns pointers to OS-internal structs, so we don't need to worry about free'ing the object
Expand Down Expand Up @@ -93,11 +93,6 @@ static int32_t GetMountInfo(MountPointFound onFound)

#endif

int32_t SystemNative_GetAllMountPoints(MountPointFound onFound)
{
return GetMountInfo(onFound);
}

int32_t SystemNative_GetSpaceInfoForMountPoint(const char* name, MountPointInformation* mpi)
{
assert(name != NULL);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -428,12 +428,6 @@ void CryptoNative_SslCtxSetVerify(SSL_CTX* ctx, SslCtxSetVerifyCallback callback
SSL_CTX_set_verify(ctx, mode, callback);
}

void
CryptoNative_SslCtxSetCertVerifyCallback(SSL_CTX* ctx, SslCtxSetCertVerifyCallbackCallback callback, void* arg)
{
SSL_CTX_set_cert_verify_callback(ctx, callback, arg);
}

int32_t CryptoNative_SetEncryptionPolicy(SSL_CTX* ctx, EncryptionPolicy policy)
{
switch (policy)
Expand Down Expand Up @@ -547,11 +541,6 @@ int32_t CryptoNative_Tls13Supported()
#endif
}

void CryptoNative_SslCtxSetClientCertCallback(SSL_CTX* ctx, SslClientCertCallback callback)
{
SSL_CTX_set_client_cert_cb(ctx, callback);
}

int32_t CryptoNative_SslAddExtraChainCert(SSL* ssl, X509* x509)
{
if (!x509 || !ssl)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -113,12 +113,6 @@ typedef enum
// the function pointer definition for the callback used in SslCtxSetVerify
typedef int32_t (*SslCtxSetVerifyCallback)(int32_t, X509_STORE_CTX*);

// the function pointer definition for the callback used in SslCtxSetCertVerifyCallback
typedef int32_t (*SslCtxSetCertVerifyCallbackCallback)(X509_STORE_CTX*, void* arg);

// the function pointer definition for the callback used in SslCtxSetClientCertCallback
typedef int32_t (*SslClientCertCallback)(SSL* ssl, X509** x509, EVP_PKEY** pkey);

// the function pointer definition for the callback used in SslCtxSetAlpnSelectCb
typedef int32_t (*SslCtxSetAlpnCallback)(SSL* ssl,
const uint8_t** out,
Expand Down Expand Up @@ -316,12 +310,6 @@ Shims the SSL_CTX_set_verify method.
*/
PALEXPORT void CryptoNative_SslCtxSetVerify(SSL_CTX* ctx, SslCtxSetVerifyCallback callback);

/*
Shims the SSL_CTX_set_cert_verify_callback method.
*/
PALEXPORT void
CryptoNative_SslCtxSetCertVerifyCallback(SSL_CTX* ctx, SslCtxSetCertVerifyCallbackCallback callback, void* arg);

/*
Sets the specified encryption policy on the SSL_CTX.
*/
Expand All @@ -337,11 +325,6 @@ Determines if TLS 1.3 is supported by this OpenSSL implementation
*/
PALEXPORT int32_t CryptoNative_Tls13Supported(void);

/*
Shims the SSL_CTX_set_client_cert_cb method
*/
PALEXPORT void CryptoNative_SslCtxSetClientCertCallback(SSL_CTX* ctx, SslClientCertCallback callback);

/*
Shims the SSL_get_finished method.
*/
Expand Down
12 changes: 6 additions & 6 deletions src/libraries/System.Console/src/System/ConsolePal.Unix.cs
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,6 @@ internal static class ConsolePal
private static int s_windowHeight; // Cached WindowHeight, invalid when s_windowWidth == -1.
private static int s_invalidateCachedSettings = 1; // Tracks whether we should invalidate the cached settings.

private static readonly Interop.Sys.TerminalInvalidationCallback s_invalidateTerminalSettings = InvalidateTerminalSettings;

public static Stream OpenStandardInput()
{
return new UnixConsoleStream(SafeFileHandleHelper.Open(() => Interop.Sys.Dup(Interop.Sys.FileDescriptors.STDIN_FILENO)), FileAccess.Read,
Expand Down Expand Up @@ -919,7 +917,7 @@ internal static void EnsureConsoleInitialized()
}

/// <summary>Ensures that the console has been initialized for use.</summary>
private static void EnsureInitializedCore()
private static unsafe void EnsureInitializedCore()
{
// Initialization is only needed when input isn't redirected.
if (Console.IsInputRedirected)
Expand All @@ -939,7 +937,7 @@ private static void EnsureInitializedCore()

// Register a callback for signals that may invalidate our cached terminal settings.
// This includes: SIGCONT, SIGCHLD, SIGWINCH.
Interop.Sys.SetTerminalInvalidationHandler(s_invalidateTerminalSettings);
Interop.Sys.SetTerminalInvalidationHandler(&InvalidateTerminalSettings);

// Provide the native lib with the correct code from the terminfo to transition us into
// "application mode". This will both transition it immediately, as well as allow
Expand Down Expand Up @@ -1364,6 +1362,7 @@ private static void CheckTerminalSettingsInvalidated()
}
}

[UnmanagedCallersOnly]
private static void InvalidateTerminalSettings()
{
Volatile.Write(ref s_invalidateCachedSettings, 1);
Expand Down Expand Up @@ -1460,12 +1459,12 @@ internal sealed class ControlCHandlerRegistrar
{
private bool _handlerRegistered;

internal void Register()
internal unsafe void Register()
{
EnsureConsoleInitialized();

Debug.Assert(!_handlerRegistered);
Interop.Sys.RegisterForCtrl(c => OnBreakEvent(c));
Interop.Sys.RegisterForCtrl(&OnBreakEvent);
_handlerRegistered = true;
}

Expand All @@ -1476,6 +1475,7 @@ internal void Unregister()
Interop.Sys.UnregisterForCtrl();
}

[UnmanagedCallersOnly]
private static void OnBreakEvent(Interop.Sys.CtrlCode ctrlCode)
{
// This is called on the native signal handling thread. We need to move to another thread so
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
using System.Security;
using System.Text;
using System.Threading;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;

namespace System.Diagnostics
Expand All @@ -19,7 +20,6 @@ public partial class Process : IDisposable
new UTF8Encoding(encoderShouldEmitUTF8Identifier: false);
private static volatile bool s_initialized;
private static readonly object s_initializedGate = new object();
private static readonly Interop.Sys.SigChldCallback s_sigChildHandler = OnSigChild;
private static readonly ReaderWriterLockSlim s_processStartLock = new ReaderWriterLockSlim();
private static int s_childrenUsingTerminalCount;

Expand Down Expand Up @@ -1000,7 +1000,7 @@ private static unsafe bool TryGetPasswd(string name, byte* buf, int bufLen, out

private bool WaitForInputIdleCore(int milliseconds) => throw new InvalidOperationException(SR.InputIdleUnkownError);

private static void EnsureInitialized()
private static unsafe void EnsureInitialized()
{
if (s_initialized)
{
Expand All @@ -1017,20 +1017,21 @@ private static void EnsureInitialized()
}

// Register our callback.
Interop.Sys.RegisterForSigChld(s_sigChildHandler);
Interop.Sys.RegisterForSigChld(&OnSigChild);

s_initialized = true;
}
}
}

private static void OnSigChild(bool reapAll)
[UnmanagedCallersOnly]
private static void OnSigChild(int reapAll)
{
// Lock to avoid races with Process.Start
s_processStartLock.EnterWriteLock();
try
{
ProcessWaitState.CheckChildren(reapAll);
ProcessWaitState.CheckChildren(reapAll != 0);
}
finally
{
Expand Down
Loading

0 comments on commit f93c0e6

Please sign in to comment.