Skip to content

Lozensky/gotta change the locks #3189

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

Merged
merged 4 commits into from
Apr 2, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@
using Microsoft.IdentityModel.Tokens;
using Microsoft.IdentityModel.Tokens.Json;

#if NET9_0_OR_GREATER
using System.Threading;
#endif

namespace Microsoft.IdentityModel.JsonWebTokens
{
/// <summary>
Expand All @@ -21,8 +25,11 @@ namespace Microsoft.IdentityModel.JsonWebTokens
internal class JsonClaimSet
{
internal const string ClassName = "Microsoft.IdentityModel.JsonWebTokens.JsonClaimSet";

#if NET9_0_OR_GREATER
internal Lock _claimsLock = new();
#else
internal object _claimsLock = new();
#endif
internal readonly Dictionary<string, object> _jsonClaims;
private List<Claim> _claims;

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Microsoft.IdentityModel.JsonWebTokens.JsonClaimSet._claimsLock -> System.Threading.Lock
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@
using System.Security.Cryptography;
using Microsoft.IdentityModel.Logging;

#if NET9_0_OR_GREATER
using System.Threading;
#endif

namespace Microsoft.IdentityModel.Tokens
{
/// <summary>
Expand All @@ -15,9 +19,13 @@ public class SymmetricKeyWrapProvider : KeyWrapProvider
private static readonly byte[] _defaultIV = new byte[] { 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6 };
private const int _blockSizeInBits = 64;
private const int _blockSizeInBytes = _blockSizeInBits >> 3;
private static readonly object _encryptorLock = new object();
private static readonly object _decryptorLock = new object();

#if NET9_0_OR_GREATER
private static readonly Lock s_encryptorLock = new();
private static readonly Lock s_decryptorLock = new();
#else
private static readonly object s_encryptorLock = new();
private static readonly object s_decryptorLock = new();
#endif
private Lazy<SymmetricAlgorithm> _symmetricAlgorithm;
private ICryptoTransform _symmetricAlgorithmEncryptor;
private ICryptoTransform _symmetricAlgorithmDecryptor;
Expand Down Expand Up @@ -259,7 +267,7 @@ Return an error

if (_symmetricAlgorithmDecryptor == null)
{
lock (_decryptorLock)
lock (s_decryptorLock)
{
if (_symmetricAlgorithmDecryptor == null)
_symmetricAlgorithmDecryptor = _symmetricAlgorithm.Value.CreateDecryptor();
Expand Down Expand Up @@ -409,7 +417,7 @@ private byte[] WrapKeyPrivate(byte[] inputBuffer, int inputOffset, int inputCoun

if (_symmetricAlgorithmEncryptor == null)
{
lock (_encryptorLock)
lock (s_encryptorLock)
{
if (_symmetricAlgorithmEncryptor == null)
_symmetricAlgorithmEncryptor = _symmetricAlgorithm.Value.CreateEncryptor();
Expand Down
12 changes: 10 additions & 2 deletions src/Microsoft.IdentityModel.Tokens/SecurityKey.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@
using System.Text.Json.Serialization;
using Microsoft.IdentityModel.Logging;

#if NET9_0_OR_GREATER
using System.Threading;
#endif

namespace Microsoft.IdentityModel.Tokens
{
/// <summary>
Expand All @@ -13,9 +17,13 @@ namespace Microsoft.IdentityModel.Tokens
public abstract class SecurityKey
{
private CryptoProviderFactory _cryptoProviderFactory;
private object _internalIdLock = new object();
private string _internalId;

#if NET9_0_OR_GREATER
private readonly Lock _internalIdLock = new();
#else
private readonly object _internalIdLock = new();
#endif
private string _internalId;
internal SecurityKey(SecurityKey key)
{
_cryptoProviderFactory = key._cryptoProviderFactory;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,11 @@ public class TokenValidationResult
// reordered relative to the other operations. The rest of the objects are not because the .NET memory model
// guarantees object writes are store releases and that reads won't be introduced.
private volatile bool _claimsIdentityInitialized;
#if NET9_0_OR_GREATER
private Lock _claimsIdentitySyncObj;
#else
private object _claimsIdentitySyncObj;
#endif
private ClaimsIdentity _claimsIdentity;
private Dictionary<string, object> _claims;
private Dictionary<string, object> _propertyBag;
Expand Down Expand Up @@ -196,6 +200,23 @@ internal ClaimsIdentity ClaimsIdentityNoLocking
}
}

#if NET9_0_OR_GREATER
/// <summary>Gets the object to use in <see cref="ClaimsIdentity"/> for double-checked locking.</summary>
private Lock ClaimsIdentitySyncObj
{
get
{
Lock syncObj = _claimsIdentitySyncObj;
if (syncObj is null)
{
Interlocked.CompareExchange(ref _claimsIdentitySyncObj, new Lock(), null);
syncObj = _claimsIdentitySyncObj;
}

return syncObj;
}
}
#else
/// <summary>Gets the object to use in <see cref="ClaimsIdentity"/> for double-checked locking.</summary>
private object ClaimsIdentitySyncObj
{
Expand All @@ -211,7 +232,7 @@ private object ClaimsIdentitySyncObj
return syncObj;
}
}

#endif
/// <summary>
/// Gets or sets the <see cref="Exception"/> that occurred during validation.
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -114,9 +114,13 @@ ActorValidationResult is not null
// reordered relative to the other operations. The rest of the objects are not because the .NET memory model
// guarantees object writes are store releases and that reads won't be introduced.
private volatile bool _claimsIdentityInitialized;
private object? _claimsIdentitySyncObj;
private ClaimsIdentity? _claimsIdentity;
private Dictionary<string, object>? _claims;
#if NET9_0_OR_GREATER
private Lock? _claimsIdentitySyncObj;
#else
private object? _claimsIdentitySyncObj;
#endif

/// <summary>
/// The <see cref="Dictionary{String, Object}"/> created from the validated security token.
Expand Down Expand Up @@ -190,6 +194,23 @@ internal ClaimsIdentity ClaimsIdentityNoLocking
}
}

#if NET9_0_OR_GREATER
/// <summary>Gets the Lock to use in <see cref="ClaimsIdentity"/> for double-checked locking.</summary>
private Lock ClaimsIdentitySyncObj
{
get
{
Lock? syncObj = _claimsIdentitySyncObj;
if (syncObj is null)
{
Interlocked.CompareExchange(ref _claimsIdentitySyncObj, new Lock(), null);
syncObj = _claimsIdentitySyncObj;
}

return syncObj;
}
}
#else
/// <summary>Gets the object to use in <see cref="ClaimsIdentity"/> for double-checked locking.</summary>
private object ClaimsIdentitySyncObj
{
Expand All @@ -205,6 +226,7 @@ private object ClaimsIdentitySyncObj
return syncObj;
}
}
#endif
#endregion

#region Logging
Expand Down
16 changes: 12 additions & 4 deletions src/Microsoft.IdentityModel.Tokens/X509SecurityKey.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
using Microsoft.IdentityModel.Logging;
#if NET9_0_OR_GREATER
using System.Threading;
#endif

namespace Microsoft.IdentityModel.Tokens
{
Expand All @@ -16,8 +19,11 @@ public class X509SecurityKey : AsymmetricSecurityKey
AsymmetricAlgorithm _privateKey;
bool _privateKeyAvailabilityDetermined;
AsymmetricAlgorithm _publicKey;
object _thisLock = new Object();

#if NET9_0_OR_GREATER
Lock _thisLock = new();
#else
object _thisLock = new();
#endif
internal X509SecurityKey(JsonWebKey webKey)
: base(webKey)
{
Expand Down Expand Up @@ -110,12 +116,14 @@ public AsymmetricAlgorithm PublicKey
return _publicKey;
}
}

#if NET9_0_OR_GREATER
Lock ThisLock => _thisLock;
#else
object ThisLock
{
get { return _thisLock; }
}

#endif
/// <summary>
/// Gets a bool indicating if a private key exists.
/// </summary>
Expand Down
11 changes: 10 additions & 1 deletion src/Microsoft.IdentityModel.Xml/EnvelopedSignatureWriter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@
using Microsoft.IdentityModel.Tokens;
using static Microsoft.IdentityModel.Logging.LogHelper;

#if NET9_0_OR_GREATER
using System.Threading;
#endif

namespace Microsoft.IdentityModel.Xml
{
/// <summary>
Expand Down Expand Up @@ -39,7 +43,12 @@ public class EnvelopedSignatureWriter : DelegatingXmlDictionaryWriter
private bool _signaturePlaceholderWritten;
private SigningCredentials _signingCredentials;
private MemoryStream _internalStream;
private object _signatureLock = new object();

#if NET9_0_OR_GREATER
private Lock _signatureLock = new();
#else
private object _signatureLock = new();
#endif

/// <summary>
/// Initializes an instance of <see cref="EnvelopedSignatureWriter"/>. The returned writer can be directly used
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright(c) Microsoft Corporation.All rights reserved.
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

using System;
Expand Down
Loading