Skip to content

Commit 1c4e4c1

Browse files
authored
Fix session-local named mutex compat issue (#90342)
- A previous change that was serviced back changed session-local named mutexes to be user-specific by restricting the permissions of the session directories and files under them, and adding the sticky bit to some directoires. A compat issue arose from that change, as the session directories have the session ID in their name and session IDs can be reused between different users. The current plan that we have discussed is to revert the change and service back the revert, which also restores the intended behavior, and offer user-specific mutexes as a new feature in a future .NET that would satisfy some user scenarios in a better way. - This PR reverts the previous change (first commit) and restores one change from the previous change (second commit) to improve backward compatibility due to differences in permissions for session directories before and after the change - Fixes #80619
1 parent d87964d commit 1c4e4c1

File tree

3 files changed

+17
-36
lines changed

3 files changed

+17
-36
lines changed

src/coreclr/pal/src/include/pal/sharedmemory.h

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -88,11 +88,9 @@ class SharedMemoryException
8888
class SharedMemoryHelpers
8989
{
9090
private:
91-
static const mode_t PermissionsMask_CurrentUser_ReadWrite;
9291
static const mode_t PermissionsMask_CurrentUser_ReadWriteExecute;
9392
static const mode_t PermissionsMask_AllUsers_ReadWrite;
9493
static const mode_t PermissionsMask_AllUsers_ReadWriteExecute;
95-
9694
public:
9795
static const UINT32 InvalidProcessId;
9896
static const SIZE_T InvalidThreadId;
@@ -108,12 +106,12 @@ class SharedMemoryHelpers
108106
static void BuildSharedFilesPath(PathCharString& destination, const char *suffix, int suffixByteCount);
109107
static bool AppendUInt32String(PathCharString& destination, UINT32 value);
110108

111-
static bool EnsureDirectoryExists(const char *path, bool isGlobalLockAcquired, bool hasCurrentUserAccessOnly, bool setStickyFlag, bool createIfNotExist = true, bool isSystemDirectory = false);
109+
static bool EnsureDirectoryExists(const char *path, bool isGlobalLockAcquired, bool createIfNotExist = true, bool isSystemDirectory = false);
112110
private:
113111
static int Open(LPCSTR path, int flags, mode_t mode = static_cast<mode_t>(0));
114112
public:
115113
static int OpenDirectory(LPCSTR path);
116-
static int CreateOrOpenFile(LPCSTR path, bool createIfNotExist = true, bool isSessionScope = true, bool *createdRef = nullptr);
114+
static int CreateOrOpenFile(LPCSTR path, bool createIfNotExist = true, bool *createdRef = nullptr);
117115
static void CloseFile(int fileDescriptor);
118116

119117
static SIZE_T GetFileSize(int fileDescriptor);

src/coreclr/pal/src/sharedmemory/sharedmemory.cpp

Lines changed: 12 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,6 @@ DWORD SharedMemoryException::GetErrorCode() const
6262
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6363
// SharedMemoryHelpers
6464

65-
const mode_t SharedMemoryHelpers::PermissionsMask_CurrentUser_ReadWrite = S_IRUSR | S_IWUSR;
6665
const mode_t SharedMemoryHelpers::PermissionsMask_CurrentUser_ReadWriteExecute = S_IRUSR | S_IWUSR | S_IXUSR;
6766
const mode_t SharedMemoryHelpers::PermissionsMask_AllUsers_ReadWrite =
6867
S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH;
@@ -97,22 +96,13 @@ SIZE_T SharedMemoryHelpers::AlignUp(SIZE_T value, SIZE_T alignment)
9796
bool SharedMemoryHelpers::EnsureDirectoryExists(
9897
const char *path,
9998
bool isGlobalLockAcquired,
100-
bool hasCurrentUserAccessOnly,
101-
bool setStickyFlag,
10299
bool createIfNotExist,
103100
bool isSystemDirectory)
104101
{
105102
_ASSERTE(path != nullptr);
106103
_ASSERTE(!(isSystemDirectory && createIfNotExist)); // should not create or change permissions on system directories
107104
_ASSERTE(SharedMemoryManager::IsCreationDeletionProcessLockAcquired());
108105
_ASSERTE(!isGlobalLockAcquired || SharedMemoryManager::IsCreationDeletionFileLockAcquired());
109-
_ASSERTE(!(setStickyFlag && hasCurrentUserAccessOnly)); // Sticky bit doesn't make sense with current user access only
110-
111-
mode_t mode = hasCurrentUserAccessOnly ? PermissionsMask_CurrentUser_ReadWriteExecute : PermissionsMask_AllUsers_ReadWriteExecute;
112-
if (setStickyFlag)
113-
{
114-
mode |= S_ISVTX;
115-
}
116106

117107
// Check if the path already exists
118108
struct stat statInfo;
@@ -133,11 +123,11 @@ bool SharedMemoryHelpers::EnsureDirectoryExists(
133123

134124
if (isGlobalLockAcquired)
135125
{
136-
if (mkdir(path, mode) != 0)
126+
if (mkdir(path, PermissionsMask_AllUsers_ReadWriteExecute) != 0)
137127
{
138128
throw SharedMemoryException(static_cast<DWORD>(SharedMemoryError::IO));
139129
}
140-
if (chmod(path, mode) != 0)
130+
if (chmod(path, PermissionsMask_AllUsers_ReadWriteExecute) != 0)
141131
{
142132
rmdir(path);
143133
throw SharedMemoryException(static_cast<DWORD>(SharedMemoryError::IO));
@@ -152,7 +142,7 @@ bool SharedMemoryHelpers::EnsureDirectoryExists(
152142
{
153143
throw SharedMemoryException(static_cast<DWORD>(SharedMemoryError::IO));
154144
}
155-
if (chmod(tempPath, mode) != 0)
145+
if (chmod(tempPath, PermissionsMask_AllUsers_ReadWriteExecute) != 0)
156146
{
157147
rmdir(tempPath);
158148
throw SharedMemoryException(static_cast<DWORD>(SharedMemoryError::IO));
@@ -192,11 +182,11 @@ bool SharedMemoryHelpers::EnsureDirectoryExists(
192182
// For non-system directories (such as gSharedFilesPath/SHARED_MEMORY_RUNTIME_TEMP_DIRECTORY_NAME),
193183
// require sufficient permissions for all users and try to update them if requested to create the directory, so that
194184
// shared memory files may be shared by all processes on the system.
195-
if ((statInfo.st_mode & mode) == mode)
185+
if ((statInfo.st_mode & PermissionsMask_AllUsers_ReadWriteExecute) == PermissionsMask_AllUsers_ReadWriteExecute)
196186
{
197187
return true;
198188
}
199-
if (!createIfNotExist || chmod(path, mode) != 0)
189+
if (!createIfNotExist || chmod(path, PermissionsMask_AllUsers_ReadWriteExecute) != 0)
200190
{
201191
// We were not asked to create the path or we weren't able to set the new permissions.
202192
// As a last resort, check that at least the current user has full access.
@@ -253,7 +243,7 @@ int SharedMemoryHelpers::OpenDirectory(LPCSTR path)
253243
return fileDescriptor;
254244
}
255245

256-
int SharedMemoryHelpers::CreateOrOpenFile(LPCSTR path, bool createIfNotExist, bool isSessionScope, bool *createdRef)
246+
int SharedMemoryHelpers::CreateOrOpenFile(LPCSTR path, bool createIfNotExist, bool *createdRef)
257247
{
258248
_ASSERTE(path != nullptr);
259249
_ASSERTE(path[0] != '\0');
@@ -283,13 +273,12 @@ int SharedMemoryHelpers::CreateOrOpenFile(LPCSTR path, bool createIfNotExist, bo
283273

284274
// File does not exist, create the file
285275
openFlags |= O_CREAT | O_EXCL;
286-
mode_t mode = isSessionScope ? PermissionsMask_CurrentUser_ReadWrite : PermissionsMask_AllUsers_ReadWrite;
287-
fileDescriptor = Open(path, openFlags, mode);
276+
fileDescriptor = Open(path, openFlags, PermissionsMask_AllUsers_ReadWrite);
288277
_ASSERTE(fileDescriptor != -1);
289278

290279
// The permissions mask passed to open() is filtered by the process' permissions umask, so open() may not set all of
291280
// the requested permissions. Use chmod() to set the proper permissions.
292-
if (chmod(path, mode) != 0)
281+
if (chmod(path, PermissionsMask_AllUsers_ReadWrite) != 0)
293282
{
294283
CloseFile(fileDescriptor);
295284
unlink(path);
@@ -675,7 +664,7 @@ SharedMemoryProcessDataHeader *SharedMemoryProcessDataHeader::CreateOrOpen(
675664
SharedMemoryHelpers::VerifyStringOperation(SharedMemoryManager::CopySharedMemoryBasePath(filePath));
676665
SharedMemoryHelpers::VerifyStringOperation(filePath.Append('/'));
677666
SharedMemoryHelpers::VerifyStringOperation(id.AppendSessionDirectoryName(filePath));
678-
if (!SharedMemoryHelpers::EnsureDirectoryExists(filePath, true /* isGlobalLockAcquired */, id.IsSessionScope(), false /* setStickyFlag */, createIfNotExist))
667+
if (!SharedMemoryHelpers::EnsureDirectoryExists(filePath, true /* isGlobalLockAcquired */, createIfNotExist))
679668
{
680669
_ASSERTE(!createIfNotExist);
681670
return nullptr;
@@ -688,7 +677,7 @@ SharedMemoryProcessDataHeader *SharedMemoryProcessDataHeader::CreateOrOpen(
688677
SharedMemoryHelpers::VerifyStringOperation(filePath.Append(id.GetName(), id.GetNameCharCount()));
689678

690679
bool createdFile;
691-
int fileDescriptor = SharedMemoryHelpers::CreateOrOpenFile(filePath, createIfNotExist, id.IsSessionScope(), &createdFile);
680+
int fileDescriptor = SharedMemoryHelpers::CreateOrOpenFile(filePath, createIfNotExist, &createdFile);
692681
if (fileDescriptor == -1)
693682
{
694683
_ASSERTE(!createIfNotExist);
@@ -1163,23 +1152,17 @@ void SharedMemoryManager::AcquireCreationDeletionFileLock()
11631152
if (!SharedMemoryHelpers::EnsureDirectoryExists(
11641153
*gSharedFilesPath,
11651154
false /* isGlobalLockAcquired */,
1166-
false /* hasCurrentUserAccessOnly */,
1167-
true /* setStickyFlag */,
11681155
false /* createIfNotExist */,
11691156
true /* isSystemDirectory */))
11701157
{
11711158
throw SharedMemoryException(static_cast<DWORD>(SharedMemoryError::IO));
11721159
}
11731160
SharedMemoryHelpers::EnsureDirectoryExists(
11741161
*s_runtimeTempDirectoryPath,
1175-
false /* isGlobalLockAcquired */,
1176-
false /* hasCurrentUserAccessOnly */,
1177-
false /* setStickyFlag */);
1162+
false /* isGlobalLockAcquired */);
11781163
SharedMemoryHelpers::EnsureDirectoryExists(
11791164
*s_sharedMemoryDirectoryPath,
1180-
false /* isGlobalLockAcquired */,
1181-
false /* hasCurrentUserAccessOnly */,
1182-
true /* setStickyFlag */);
1165+
false /* isGlobalLockAcquired */);
11831166
s_creationDeletionLockFileDescriptor = SharedMemoryHelpers::OpenDirectory(*s_sharedMemoryDirectoryPath);
11841167
if (s_creationDeletionLockFileDescriptor == -1)
11851168
{

src/coreclr/pal/src/synchobj/mutex.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1115,7 +1115,7 @@ SharedMemoryProcessDataHeader *NamedMutexProcessData::CreateOrOpen(
11151115
SharedMemoryHelpers::BuildSharedFilesPath(lockFilePath, SHARED_MEMORY_LOCK_FILES_DIRECTORY_NAME);
11161116
if (created)
11171117
{
1118-
SharedMemoryHelpers::EnsureDirectoryExists(lockFilePath, true /* isGlobalLockAcquired */, false /* hasCurrentUserAccessOnly */, true /* setStickyFlag */);
1118+
SharedMemoryHelpers::EnsureDirectoryExists(lockFilePath, true /* isGlobalLockAcquired */);
11191119
}
11201120

11211121
// Create the session directory
@@ -1124,15 +1124,15 @@ SharedMemoryProcessDataHeader *NamedMutexProcessData::CreateOrOpen(
11241124
SharedMemoryHelpers::VerifyStringOperation(id->AppendSessionDirectoryName(lockFilePath));
11251125
if (created)
11261126
{
1127-
SharedMemoryHelpers::EnsureDirectoryExists(lockFilePath, true /* isGlobalLockAcquired */, id->IsSessionScope(), false /* setStickyFlag */);
1127+
SharedMemoryHelpers::EnsureDirectoryExists(lockFilePath, true /* isGlobalLockAcquired */);
11281128
autoCleanup.m_lockFilePath = &lockFilePath;
11291129
autoCleanup.m_sessionDirectoryPathCharCount = lockFilePath.GetCount();
11301130
}
11311131

11321132
// Create or open the lock file
11331133
SharedMemoryHelpers::VerifyStringOperation(lockFilePath.Append('/'));
11341134
SharedMemoryHelpers::VerifyStringOperation(lockFilePath.Append(id->GetName(), id->GetNameCharCount()));
1135-
int lockFileDescriptor = SharedMemoryHelpers::CreateOrOpenFile(lockFilePath, created, id->IsSessionScope());
1135+
int lockFileDescriptor = SharedMemoryHelpers::CreateOrOpenFile(lockFilePath, created);
11361136
if (lockFileDescriptor == -1)
11371137
{
11381138
_ASSERTE(!created);

0 commit comments

Comments
 (0)