diff --git a/eng/Versions.props b/eng/Versions.props
index 6f3cccb6531250..d8ed30224f6967 100644
--- a/eng/Versions.props
+++ b/eng/Versions.props
@@ -126,7 +126,7 @@
1.0.0-prerelease.21416.5
1.0.0-prerelease.21416.5
- 16.11.23-beta1.23063.1
+ 16.11.27-beta1.23180.1
2.0.0-beta1.20253.1
2.0.65
2.2.0
diff --git a/eng/native/functions.cmake b/eng/native/functions.cmake
index d8dae167d3afe9..2b97b1f0fa46f3 100644
--- a/eng/native/functions.cmake
+++ b/eng/native/functions.cmake
@@ -118,7 +118,8 @@ endfunction(find_unwind_libs)
function(convert_to_absolute_path RetSources)
set(Sources ${ARGN})
foreach(Source IN LISTS Sources)
- list(APPEND AbsolutePathSources ${CMAKE_CURRENT_SOURCE_DIR}/${Source})
+ get_filename_component(AbsolutePathSource ${Source} ABSOLUTE BASE_DIR ${CMAKE_CURRENT_SOURCE_DIR})
+ list(APPEND AbsolutePathSources ${AbsolutePathSource})
endforeach()
set(${RetSources} ${AbsolutePathSources} PARENT_SCOPE)
endfunction(convert_to_absolute_path)
diff --git a/src/coreclr/dlls/mscoree/CMakeLists.txt b/src/coreclr/dlls/mscoree/CMakeLists.txt
index 4571b196aaa942..3979c42245295d 100644
--- a/src/coreclr/dlls/mscoree/CMakeLists.txt
+++ b/src/coreclr/dlls/mscoree/CMakeLists.txt
@@ -11,7 +11,7 @@ set(CLR_SOURCES
if(CLR_CMAKE_TARGET_WIN32)
list(APPEND CLR_SOURCES
- delayloadhook.cpp
+ ${CLR_SRC_NATIVE_DIR}/common/delayloadhook_windows.cpp
Native.rc
)
diff --git a/src/coreclr/vm/ceeload.cpp b/src/coreclr/vm/ceeload.cpp
index 45dfe704ac1b5b..9487b62ec9b0be 100644
--- a/src/coreclr/vm/ceeload.cpp
+++ b/src/coreclr/vm/ceeload.cpp
@@ -3429,26 +3429,17 @@ ISymUnmanagedReader *Module::GetISymUnmanagedReader(void)
"reachable or needs to be reimplemented for CoreCLR!");
}
- // We're going to be working with Windows PDB format symbols. Attempt to CoCreate the symbol binder.
- // CoreCLR supports not having a symbol reader installed, so CoCreate searches the PATH env var
- // and then tries coreclr dll location.
- // On desktop, the framework installer is supposed to install diasymreader.dll as well
- // and so this shouldn't happen.
- hr = FakeCoCreateInstanceEx(CLSID_CorSymBinder_SxS, NATIVE_SYMBOL_READER_DLL, IID_ISymUnmanagedBinder, (void**)&pBinder, NULL);
+ PathString symbolReaderPath;
+ hr = GetClrModuleDirectory(symbolReaderPath);
if (FAILED(hr))
{
- PathString symbolReaderPath;
- hr = GetClrModuleDirectory(symbolReaderPath);
- if (FAILED(hr))
- {
- RETURN (NULL);
- }
- symbolReaderPath.Append(NATIVE_SYMBOL_READER_DLL);
- hr = FakeCoCreateInstanceEx(CLSID_CorSymBinder_SxS, symbolReaderPath.GetUnicode(), IID_ISymUnmanagedBinder, (void**)&pBinder, NULL);
- if (FAILED(hr))
- {
- RETURN (NULL);
- }
+ RETURN (NULL);
+ }
+ symbolReaderPath.Append(NATIVE_SYMBOL_READER_DLL);
+ hr = FakeCoCreateInstanceEx(CLSID_CorSymBinder_SxS, symbolReaderPath.GetUnicode(), IID_ISymUnmanagedBinder, (void**)&pBinder, NULL);
+ if (FAILED(hr))
+ {
+ RETURN (NULL);
}
LOG((LF_CORDB, LL_INFO10, "M::GISUR: Created binder\n"));
diff --git a/src/libraries/Common/src/System/Security/Cryptography/KdfWorkLimiter.cs b/src/libraries/Common/src/System/Security/Cryptography/KdfWorkLimiter.cs
new file mode 100644
index 00000000000000..7500212fe27d9c
--- /dev/null
+++ b/src/libraries/Common/src/System/Security/Cryptography/KdfWorkLimiter.cs
@@ -0,0 +1,86 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+using System.Diagnostics;
+
+namespace System.Security.Cryptography
+{
+ // Places KDF work limits on the current thread.
+ internal static class KdfWorkLimiter
+ {
+ [ThreadStatic]
+ private static State? t_state;
+
+ // Entry point: sets the iteration limit to a new value.
+ internal static void SetIterationLimit(ulong workLimit)
+ {
+ Debug.Assert(t_state == null, "This method is not intended to be called recursively.");
+ State state = new State();
+ state.RemainingAllowedWork = workLimit;
+ t_state = state;
+ }
+
+ internal static bool WasWorkLimitExceeded()
+ {
+ Debug.Assert(t_state != null, "This method should only be called within a protected block.");
+ return t_state.WorkLimitWasExceeded;
+ }
+
+ // Removes any iteration limit on the current thread.
+ internal static void ResetIterationLimit()
+ {
+ t_state = null;
+ }
+
+ // Records that we're about to perform some amount of work.
+ // Overflows if the work count is exceeded.
+ internal static void RecordIterations(int workCount)
+ {
+ RecordIterations((long)workCount);
+ }
+
+ // Records that we're about to perform some amount of work.
+ // Overflows if the work count is exceeded.
+ internal static void RecordIterations(long workCount)
+ {
+ State? state = t_state;
+ if (state == null)
+ {
+ return;
+ }
+
+ bool success = false;
+
+ if (workCount < 0)
+ {
+ throw new CryptographicException();
+ }
+
+ try
+ {
+ if (!state.WorkLimitWasExceeded)
+ {
+ state.RemainingAllowedWork = checked(state.RemainingAllowedWork - (ulong)workCount);
+ success = true;
+ }
+ }
+ finally
+ {
+ // If for any reason we failed, mark the thread as "no further work allowed" and
+ // normalize to CryptographicException.
+ if (!success)
+ {
+ state.RemainingAllowedWork = 0;
+ state.WorkLimitWasExceeded = true;
+ throw new CryptographicException();
+ }
+ }
+ }
+
+ private sealed class State
+ {
+ internal ulong RemainingAllowedWork;
+ internal bool WorkLimitWasExceeded;
+ }
+ }
+}
diff --git a/src/libraries/Common/src/System/Security/Cryptography/PasswordBasedEncryption.cs b/src/libraries/Common/src/System/Security/Cryptography/PasswordBasedEncryption.cs
index dc1fd465acfe3b..d988ad14288e40 100644
--- a/src/libraries/Common/src/System/Security/Cryptography/PasswordBasedEncryption.cs
+++ b/src/libraries/Common/src/System/Security/Cryptography/PasswordBasedEncryption.cs
@@ -377,6 +377,7 @@ internal static unsafe int Encrypt(
Debug.Assert(pwdTmpBytes!.Length == 0);
}
+ KdfWorkLimiter.RecordIterations(iterationCount);
using (var pbkdf2 = new Rfc2898DeriveBytes(pwdTmpBytes, salt.ToArray(), iterationCount, prf))
{
derivedKey = pbkdf2.GetBytes(keySizeBytes);
diff --git a/src/libraries/Common/src/System/Security/Cryptography/Pkcs12Kdf.cs b/src/libraries/Common/src/System/Security/Cryptography/Pkcs12Kdf.cs
index 132b7a7e354835..feb6b9604b89d3 100644
--- a/src/libraries/Common/src/System/Security/Cryptography/Pkcs12Kdf.cs
+++ b/src/libraries/Common/src/System/Security/Cryptography/Pkcs12Kdf.cs
@@ -147,6 +147,7 @@ private static void Derive(
I = IRented.AsSpan(0, ILen);
}
+ KdfWorkLimiter.RecordIterations(iterationCount);
IncrementalHash hash = IncrementalHash.CreateHash(hashAlgorithm);
try
diff --git a/src/libraries/Common/tests/System/Net/Http/TestHelper.cs b/src/libraries/Common/tests/System/Net/Http/TestHelper.cs
index 98c19464db941a..b1ae822ea9e8fb 100644
--- a/src/libraries/Common/tests/System/Net/Http/TestHelper.cs
+++ b/src/libraries/Common/tests/System/Net/Http/TestHelper.cs
@@ -157,7 +157,7 @@ public static X509Certificate2 CreateServerSelfSignedCertificate(string name = "
X509Certificate2 cert = req.CreateSelfSigned(start, end);
if (PlatformDetection.IsWindows)
{
- cert = new X509Certificate2(cert.Export(X509ContentType.Pfx));
+ cert = new X509Certificate2(cert.Export(X509ContentType.Pfx), (string?)null);
}
return cert;
diff --git a/src/libraries/Common/tests/System/Security/Cryptography/X509Certificates/RevocationResponder.cs b/src/libraries/Common/tests/System/Security/Cryptography/X509Certificates/RevocationResponder.cs
index 4e9e5e20612a94..b08655e6f1d10b 100644
--- a/src/libraries/Common/tests/System/Security/Cryptography/X509Certificates/RevocationResponder.cs
+++ b/src/libraries/Common/tests/System/Security/Cryptography/X509Certificates/RevocationResponder.cs
@@ -7,6 +7,7 @@
using System.Threading;
using System.Threading.Tasks;
using System.Web;
+using Xunit;
namespace System.Security.Cryptography.X509Certificates.Tests.Common
{
@@ -29,6 +30,7 @@ private readonly Dictionary _crlPaths
public string UriPrefix { get; }
public bool RespondEmpty { get; set; }
+ public AiaResponseKind AiaResponseKind { get; set; }
public TimeSpan ResponseDelay { get; set; }
public DelayedActionsFlag DelayedActions { get; set; }
@@ -181,13 +183,13 @@ private void HandleRequest(HttpListenerContext context, ref bool responded)
Thread.Sleep(ResponseDelay);
}
- byte[] certData = RespondEmpty ? Array.Empty() : authority.GetCertData();
+ byte[] certData = RespondEmpty ? Array.Empty() : GetCertDataForAiaResponseKind(AiaResponseKind, authority);
responded = true;
context.Response.StatusCode = 200;
- context.Response.ContentType = "application/pkix-cert";
+ context.Response.ContentType = AiaResponseKindToContentType(AiaResponseKind);
context.Response.Close(certData, willBlock: true);
- Trace($"Responded with {certData.Length}-byte certificate from {authority.SubjectName}.");
+ Trace($"Responded with {certData.Length}-byte {AiaResponseKind} from {authority.SubjectName}.");
return;
}
@@ -295,6 +297,41 @@ private static HttpListener OpenListener(out string uriPrefix)
}
}
+ private static string AiaResponseKindToContentType(AiaResponseKind kind)
+ {
+ if (kind == AiaResponseKind.Cert)
+ {
+ return "application/pkix-cert";
+ }
+ else if (kind == AiaResponseKind.Pkcs12)
+ {
+ return "application/x-pkcs12";
+ }
+ else
+ {
+ Assert.True(false, $"Unknown value AiaResponseKind.`{kind}`.");
+ return null;
+ }
+ }
+
+ private static byte[] GetCertDataForAiaResponseKind(AiaResponseKind kind, CertificateAuthority authority)
+ {
+ if (kind == AiaResponseKind.Cert)
+ {
+ return authority.GetCertData();
+ }
+ else if (kind == AiaResponseKind.Pkcs12)
+ {
+ using X509Certificate2 cert = new X509Certificate2(authority.GetCertData());
+ return cert.Export(X509ContentType.Pkcs12);
+ }
+ else
+ {
+ Assert.True(false, $"Unknown value AiaResponseKind.`{kind}`.");
+ return null;
+ }
+ }
+
private static bool TryGetOcspRequestBytes(HttpListenerRequest request, string prefix, out byte[] requestBytes)
{
requestBytes = null;
@@ -425,4 +462,10 @@ public enum DelayedActionsFlag : byte
Aia = 0b100,
All = 0b11111111
}
+
+ public enum AiaResponseKind
+ {
+ Cert = 0,
+ Pkcs12 = 1,
+ }
}
diff --git a/src/libraries/System.Data.Common/src/System/Data/Common/SqlUDTStorage.cs b/src/libraries/System.Data.Common/src/System/Data/Common/SqlUDTStorage.cs
index b804c470ed02ec..be76c7da050734 100644
--- a/src/libraries/System.Data.Common/src/System/Data/Common/SqlUDTStorage.cs
+++ b/src/libraries/System.Data.Common/src/System/Data/Common/SqlUDTStorage.cs
@@ -187,6 +187,9 @@ public override object ConvertXmlToObject(XmlReader xmlReader, XmlRootAttribute?
}
}
Type type = (typeName == null) ? _dataType : Type.GetType(typeName)!;
+
+ TypeLimiter.EnsureTypeIsAllowed(type);
+
object Obj = System.Activator.CreateInstance(type, true)!;
Debug.Assert(xmlReader is DataTextReader, "Invalid DataTextReader is being passed to customer");
((IXmlSerializable)Obj).ReadXml(xmlReader);
diff --git a/src/libraries/System.Data.Common/tests/System/Data/RestrictedTypeHandlingTests.cs b/src/libraries/System.Data.Common/tests/System/Data/RestrictedTypeHandlingTests.cs
index 54644b678a5bc2..b1bb652b1a0331 100644
--- a/src/libraries/System.Data.Common/tests/System/Data/RestrictedTypeHandlingTests.cs
+++ b/src/libraries/System.Data.Common/tests/System/Data/RestrictedTypeHandlingTests.cs
@@ -241,6 +241,59 @@ public void DataTable_HonorsGloballyDefinedAllowList()
}
}
+ [Fact]
+ public void DataTable_HonorsGloballyDefinedAllowListForSqlTypes()
+ {
+ // Arrange
+
+ DataTable table = new DataTable("MyTable");
+ table.Columns.Add("MyNullableColumn", typeof(MyCustomNullable1));
+ table.Rows.Add(new MyCustomNullable1());
+ table.AcceptChanges();
+
+ var asXml = @$"
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ false
+
+
+";
+
+ // Act & assert
+ // Deserialization should fail since MyCustomNullable2 is not on the allow list,
+ // even though MyCustomNullable1 is on the allow list.
+
+ try
+ {
+ AppDomain.CurrentDomain.SetData(AppDomainDataSetDefaultAllowedTypesKey, new Type[]
+ {
+ typeof(MyCustomNullable1)
+ });
+
+ table = new DataTable();
+ Assert.Throws(() => table.ReadXml(new StringReader(asXml)));
+ }
+ finally
+ {
+ AppDomain.CurrentDomain.SetData(AppDomainDataSetDefaultAllowedTypesKey, null);
+ }
+ }
+
[Fact]
public void DataColumn_ConvertExpression_SubjectToAllowList_Success()
{
@@ -400,6 +453,20 @@ private sealed class MyCustomClass
{
}
+ public sealed class MyCustomNullable1 : INullable
+ {
+ public static MyCustomNullable1 Null { get; } = new MyCustomNullable1();
+
+ public bool IsNull => false;
+ }
+
+ public sealed class MyCustomNullable2 : INullable
+ {
+ public static MyCustomNullable2 Null { get; } = new MyCustomNullable2();
+
+ public bool IsNull => false;
+ }
+
public sealed class MyXmlSerializableClass : IXmlSerializable
{
public XmlSchema GetSchema()
diff --git a/src/libraries/System.Net.Security/tests/FunctionalTests/SslStreamStreamToStreamTest.cs b/src/libraries/System.Net.Security/tests/FunctionalTests/SslStreamStreamToStreamTest.cs
index bc8e3cf471b3f3..b9917bee216dc4 100644
--- a/src/libraries/System.Net.Security/tests/FunctionalTests/SslStreamStreamToStreamTest.cs
+++ b/src/libraries/System.Net.Security/tests/FunctionalTests/SslStreamStreamToStreamTest.cs
@@ -63,7 +63,7 @@ public static IEnumerable