Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
9f9f4ea
Fix DateTime parsing with Hebrew characters
Aug 12, 2026
2a58d9e
Minor feedback
Aug 13, 2026
a0511a4
Add exception helper
Aug 13, 2026
018b489
Fix DateTime parsing when raw info buffer is full parsing Hebrew numbers
Aug 21, 2026
9e1fa23
Merged PR 64448: [release/9.0] Fix missing root for default servicing…
elinor-fung Aug 29, 2026
9726e06
Merge commit '59ee5dfd30ff2c50d2352739dbe121df0bd7c1d3'
Sep 2, 2026
e3c8e58
Merge commit 'db534f81c615d4ad79da3978b8bd83eef22a1e6e'
Sep 3, 2026
648f10a
Apply Encrypted XML and Signed CMS security fixes
PranavSenthilnathan Sep 3, 2026
916f6f4
Bound encrypted data candidate processing
PranavSenthilnathan Sep 4, 2026
0e57e6a
Remove unnecessary .NET 9 package opt-ins
PranavSenthilnathan Sep 4, 2026
1303384
Adjust canonicalization stress test for attribute limit
PranavSenthilnathan Sep 5, 2026
31face5
Update MsQuic to 2.5.11-ci.156755675
rzikm Sep 7, 2026
a1ec77b
EnvelopedCms.Decode should not run attribute-merge.
bartonjs Sep 8, 2026
acba91f
Merged PR 63383: [HTTP] Clear proxy auth header on redirect
Sep 10, 2026
b68b171
Merged PR 65026: [release/9.0] Update MsQuic to 2.5.11-ci.156755675
rzikm Sep 10, 2026
21c0c8c
Merge commit '01c71028a330667b2aaffb064d1fe47a7c509a4b'
Sep 10, 2026
b4a7043
Merge commit '1a69fbfb1a5d6ece0e1e958d5d6ce6b4271b68c9'
Sep 10, 2026
2bcc4eb
Merge commit 'c72be290ca54cfe85c4613bd7344339e5385c5ee'
Sep 11, 2026
0ea995e
Merged PR 63567: [release/9.0] Correctly evaluate relative parent sym…
rzikm Sep 11, 2026
193f35e
Merged PR 64973: [release/9.0] Signed CMS and Signed XML fixes (10B)
PranavSenthilnathan Sep 11, 2026
01e241f
Merged PR 63930: Fix DateTime parsing with Hebrew characters
Sep 11, 2026
5b1e892
Merge commit '2f40c2c61593bd61443404495f0dcb9cce41bd0d'
Sep 14, 2026
e64d126
Merge commit '7078c766b9abe32301ccfdf660a1c70c2ea9836a'
Sep 15, 2026
5cd6d95
Merged PR 63817: [internal/release/9.0] Fixes for Shared Mutex privil…
Sep 20, 2026
2543ad4
Add maximum depth enforcement to CborReader
eiriktsarpalis Sep 3, 2026
13ebc6b
Merged PR 65575: [release/9.0] Add max depth enforcement to `CborRead…
eiriktsarpalis Sep 21, 2026
2d7028d
Don't check perms for shared mutexes. Let the fs handle permissions i…
jkoritzinsky Sep 23, 2026
0bba4ab
Merged PR 65723: Don't check perms for shared mutexes. Let the fs han…
Sep 23, 2026
d280e4f
Merged PR 66111: Update MsQuic to 2.5.11-ci-159417053
mmitche Oct 4, 2026
051e9a3
Merge commit 'd280e4fb388c6deed22d480daada060b6b456008' into internal…
dotnet-bot Oct 13, 2026
9347ebe
[release/9.0-staging] Update MsQuic to 2.5.12 (#135884)
ViveliDuCh Oct 15, 2026
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
2 changes: 1 addition & 1 deletion eng/Versions.props
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,7 @@
<!-- ICU -->
<MicrosoftNETCoreRuntimeICUTransportVersion>9.0.0-rtm.26509.1</MicrosoftNETCoreRuntimeICUTransportVersion>
<!-- MsQuic -->
<MicrosoftNativeQuicMsQuicSchannelVersion>2.5.10</MicrosoftNativeQuicMsQuicSchannelVersion>
<MicrosoftNativeQuicMsQuicSchannelVersion>2.5.12</MicrosoftNativeQuicMsQuicSchannelVersion>
<!-- Mono LLVM -->
<runtimelinuxarm64MicrosoftNETCoreRuntimeMonoLLVMSdkVersion>19.1.0-alpha.1.26505.5</runtimelinuxarm64MicrosoftNETCoreRuntimeMonoLLVMSdkVersion>
<runtimelinuxarm64MicrosoftNETCoreRuntimeMonoLLVMToolsVersion>19.1.0-alpha.1.26505.5</runtimelinuxarm64MicrosoftNETCoreRuntimeMonoLLVMToolsVersion>
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.Diagnostics.CodeAnalysis;
using System.IO;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
Expand All @@ -14,9 +15,15 @@ namespace System.Threading
/// </summary>
public sealed partial class Mutex : WaitHandle
{
[FeatureSwitchDefinition("System.Threading.Mutex.UnsafeDefaultMutexScopeGlobal")]
private static bool UnsafeDefaultMutexScopeGlobal { get; } =
AppContext.TryGetSwitch("System.Threading.Mutex.UnsafeDefaultMutexScopeGlobal", out bool enabled) && enabled;

private void CreateMutexCore(bool initiallyOwned, string? name, out bool createdNew)
{
SafeWaitHandle mutexHandle = CreateMutexCore(initiallyOwned, name, out int errorCode, out string? errorDetails);
bool isUserScope = !string.IsNullOrEmpty(name) && !UnsafeDefaultMutexScopeGlobal;
SafeWaitHandle mutexHandle =
CreateMutexCore(initiallyOwned, name, isUserScope, out int errorCode, out string? errorDetails);
if (mutexHandle.IsInvalid)
{
mutexHandle.SetHandleAsInvalid();
Expand All @@ -42,7 +49,8 @@ private static OpenExistingResult OpenExistingWorker(string name, out Mutex? res
// with parameters to allow us to view & edit the ACL. This will
// fail if we don't have permission to view or edit the ACL's.
// If that happens, ask for less permissions.
SafeWaitHandle myHandle = OpenMutexCore(name, out int errorCode, out string? errorDetails);
SafeWaitHandle myHandle =
OpenMutexCore(name, isUserScope: !UnsafeDefaultMutexScopeGlobal, out int errorCode, out string? errorDetails);

if (myHandle.IsInvalid)
{
Expand Down Expand Up @@ -86,11 +94,13 @@ public void ReleaseMutex()
private static unsafe SafeWaitHandle CreateMutexCore(
bool initialOwner,
string? name,
bool isUserScope,
out int errorCode,
out string? errorDetails)
{
byte* systemCallErrors = stackalloc byte[SystemCallErrorsBufferSize];
SafeWaitHandle mutexHandle = CreateMutex(initialOwner, name, systemCallErrors, SystemCallErrorsBufferSize);
SafeWaitHandle mutexHandle =
CreateMutex(initialOwner, name, isUserScope, systemCallErrors, SystemCallErrorsBufferSize);

// Get the error code even if the handle is valid, as it could be ERROR_ALREADY_EXISTS, indicating that the mutex
// already exists and was opened
Expand All @@ -100,10 +110,14 @@ private static unsafe SafeWaitHandle CreateMutexCore(
return mutexHandle;
}

private static unsafe SafeWaitHandle OpenMutexCore(string name, out int errorCode, out string? errorDetails)
private static unsafe SafeWaitHandle OpenMutexCore(
string name,
bool isUserScope,
out int errorCode,
out string? errorDetails)
{
byte* systemCallErrors = stackalloc byte[SystemCallErrorsBufferSize];
SafeWaitHandle mutexHandle = OpenMutex(name, systemCallErrors, SystemCallErrorsBufferSize);
SafeWaitHandle mutexHandle = OpenMutex(name, isUserScope, systemCallErrors, SystemCallErrorsBufferSize);
errorCode = mutexHandle.IsInvalid ? Marshal.GetLastPInvokeError() : Interop.Errors.ERROR_SUCCESS;
errorDetails = mutexHandle.IsInvalid ? GetErrorDetails(systemCallErrors) : null;
return mutexHandle;
Expand All @@ -127,9 +141,18 @@ private static unsafe SafeWaitHandle OpenMutexCore(string name, out int errorCod
}

[LibraryImport(RuntimeHelpers.QCall, EntryPoint = "PAL_CreateMutexW", SetLastError = true, StringMarshalling = StringMarshalling.Utf16)]
private static unsafe partial SafeWaitHandle CreateMutex([MarshalAs(UnmanagedType.Bool)] bool initialOwner, string? name, byte* systemCallErrors, uint systemCallErrorsBufferSize);
private static unsafe partial SafeWaitHandle CreateMutex(
[MarshalAs(UnmanagedType.Bool)] bool initialOwner,
string? name,
[MarshalAs(UnmanagedType.Bool)] bool isUserScope,
byte* systemCallErrors,
uint systemCallErrorsBufferSize);

[LibraryImport(RuntimeHelpers.QCall, EntryPoint = "PAL_OpenMutexW", SetLastError = true, StringMarshalling = StringMarshalling.Utf16)]
private static unsafe partial SafeWaitHandle OpenMutex(string name, byte* systemCallErrors, uint systemCallErrorsBufferSize);
private static unsafe partial SafeWaitHandle OpenMutex(
string name,
[MarshalAs(UnmanagedType.Bool)] bool isUserScope,
byte* systemCallErrors,
uint systemCallErrorsBufferSize);
}
}
2 changes: 2 additions & 0 deletions src/coreclr/pal/inc/pal.h
Original file line number Diff line number Diff line change
Expand Up @@ -932,6 +932,7 @@ PALAPI
PAL_CreateMutexW(
IN BOOL bInitialOwner,
IN LPCWSTR lpName,
IN BOOL bCurrentUserOnly,
IN LPSTR lpSystemCallErrors,
IN DWORD dwSystemCallErrorsBufferSize);

Expand All @@ -953,6 +954,7 @@ HANDLE
PALAPI
PAL_OpenMutexW(
IN LPCWSTR lpName,
IN BOOL bCurrentUserOnly,
IN LPSTR lpSystemCallErrors,
IN DWORD dwSystemCallErrorsBufferSize);

Expand Down
1 change: 0 additions & 1 deletion src/coreclr/pal/inc/pal_error.h
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,6 @@
#define ERROR_PALINIT_TLS 65295L
#define ERROR_PALINIT_ENV 65296L
#define ERROR_PALINIT_DBG_CHANNELS 65297L
#define ERROR_PALINIT_SHARED_MEMORY_MANAGER 65298L
#define ERROR_PALINIT_SHM 65299L
#define ERROR_PALINIT_MODULE_MANAGER 65300L

Expand Down
19 changes: 13 additions & 6 deletions src/coreclr/pal/src/include/pal/mutex.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ namespace CorUnix
LPSECURITY_ATTRIBUTES lpMutexAttributes,
BOOL bInitialOwner,
LPCSTR lpName,
BOOL bCurrentUserOnly,
HANDLE *phMutex
);

Expand All @@ -51,6 +52,7 @@ namespace CorUnix
SharedMemorySystemCallErrors *errors,
CPalThread *pThread,
LPCSTR lpName,
BOOL bCurrentUserOnly,
HANDLE *phMutex
);

Expand All @@ -76,8 +78,13 @@ Design
find any other sync object with a timed wait with the necessary properties, so polling is done for timed waits.

Shared memory files
- Session-scoped mutexes (name not prefixed, or prefixed with Local) go in /tmp/.dotnet/shm/session<sessionId>/<mutexName>
- Globally-scoped mutexes (name prefixed with Global) go in /tmp/.dotnet/shm/global/<mutexName>
- Session-scoped mutexes (name not prefixed, or prefixed with Local) go in
<system base>/{.dotnet|.dotnet-uid}/shm/session<sessionId>/<mutexName>
- Globally-scoped mutexes (name prefixed with Global) go in
<system base>/{.dotnet|.dotnet-uid}/shm/global/<mutexName>
- User-unscoped mutexes use the global shared-files base. User-scoped mutexes use a user-specific system base.
- In an Apple application-group container, user-scoped mutexes use .dotnet-uid in parallel to the .dotnet directory used by
user-unscoped mutexes, preserving the distinction between the scopes within the already-user-specific container.
- Contains shared state, and is mmap'ped into the process, see SharedMemorySharedDataHeader and NamedMutexSharedData for data
stored
- Creation and deletion is synchronized using an exclusive file lock on the shm directory
Expand All @@ -94,7 +101,7 @@ Shared memory files
Lock files when using file locks:
- In addition to the shared memory file, we need another file for the actual synchronization file lock, since a file lock on the
shared memory file is used for lifetime purposes.
- These files go in /tmp/.dotnet/lockfiles/session<sessionId>|global/<mutexName>
- These files go in <system base>/{.dotnet|.dotnet-uid}/lockfiles/session<sessionId>|global/<mutexName>
- The file is empty, and is only used for file locks

Process data
Expand Down Expand Up @@ -216,10 +223,10 @@ class NamedMutexProcessData : public SharedMemoryProcessDataBase
bool m_hasRefFromLockOwnerThread;

public:
static SharedMemoryProcessDataHeader *CreateOrOpen(SharedMemorySystemCallErrors *errors, LPCSTR name, bool acquireLockIfCreated, bool *createdRef);
static SharedMemoryProcessDataHeader *Open(SharedMemorySystemCallErrors *errors, LPCSTR name);
static SharedMemoryProcessDataHeader *CreateOrOpen(SharedMemorySystemCallErrors *errors, LPCSTR name, bool isUserScope, bool acquireLockIfCreated, bool *createdRef);
static SharedMemoryProcessDataHeader *Open(SharedMemorySystemCallErrors *errors, LPCSTR name, bool isUserScope);
private:
static SharedMemoryProcessDataHeader *CreateOrOpen(SharedMemorySystemCallErrors *errors, LPCSTR name, bool createIfNotExist, bool acquireLockIfCreated, bool *createdRef);
static SharedMemoryProcessDataHeader *CreateOrOpen(SharedMemorySystemCallErrors *errors, LPCSTR name, bool isUserScope, bool createIfNotExist, bool acquireLockIfCreated, bool *createdRef);

public:
NamedMutexProcessData(
Expand Down
Loading
Loading