Skip to content
This repository was archived by the owner on Jan 23, 2023. It is now read-only.

Commit 392d2a4

Browse files
kouveljanvorli
authored andcommitted
Don't require all-user permissions on the temp directory for named mutexes on Unix under docker (#17206)
Avoids the need for a workaround for one of the issues seen in https://github.com/dotnet/coreclr/issues/17098
1 parent dac3fa6 commit 392d2a4

File tree

3 files changed

+33
-4
lines changed

3 files changed

+33
-4
lines changed

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ class SharedMemoryException
9393
class SharedMemoryHelpers
9494
{
9595
private:
96+
static const mode_t PermissionsMask_CurrentUser_ReadWriteExecute;
9697
static const mode_t PermissionsMask_AllUsers_ReadWrite;
9798
static const mode_t PermissionsMask_AllUsers_ReadWriteExecute;
9899
public:
@@ -110,7 +111,7 @@ class SharedMemoryHelpers
110111
template<SIZE_T DestinationByteCount> static SIZE_T CopyString(char (&destination)[DestinationByteCount], SIZE_T destinationStartOffset, LPCSTR source, SIZE_T sourceCharCount);
111112
template<SIZE_T DestinationByteCount> static SIZE_T AppendUInt32String(char (&destination)[DestinationByteCount], SIZE_T destinationStartOffset, UINT32 value);
112113

113-
static bool EnsureDirectoryExists(const char *path, bool isGlobalLockAcquired, bool createIfNotExist = true);
114+
static bool EnsureDirectoryExists(const char *path, bool isGlobalLockAcquired, bool createIfNotExist = true, bool isSystemDirectory = false);
114115
private:
115116
static int Open(LPCSTR path, int flags, mode_t mode = static_cast<mode_t>(0));
116117
public:

src/pal/src/sharedmemory/sharedmemory.cpp

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

65+
const mode_t SharedMemoryHelpers::PermissionsMask_CurrentUser_ReadWriteExecute = S_IRUSR | S_IWUSR | S_IXUSR;
6566
const mode_t SharedMemoryHelpers::PermissionsMask_AllUsers_ReadWrite =
6667
S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH;
6768
const mode_t SharedMemoryHelpers::PermissionsMask_AllUsers_ReadWriteExecute =
@@ -92,10 +93,16 @@ SIZE_T SharedMemoryHelpers::AlignUp(SIZE_T value, SIZE_T alignment)
9293
return AlignDown(value + (alignment - 1), alignment);
9394
}
9495

95-
bool SharedMemoryHelpers::EnsureDirectoryExists(const char *path, bool isGlobalLockAcquired, bool createIfNotExist)
96+
bool SharedMemoryHelpers::EnsureDirectoryExists(
97+
const char *path,
98+
bool isGlobalLockAcquired,
99+
bool createIfNotExist,
100+
bool isSystemDirectory)
96101
{
97102
_ASSERTE(path != nullptr);
103+
_ASSERTE(!(isSystemDirectory && createIfNotExist)); // should not create or change permissions on system directories
98104
_ASSERTE(SharedMemoryManager::IsCreationDeletionProcessLockAcquired());
105+
_ASSERTE(!isGlobalLockAcquired || SharedMemoryManager::IsCreationDeletionFileLockAcquired());
99106

100107
// Check if the path already exists
101108
struct stat statInfo;
@@ -155,7 +162,24 @@ bool SharedMemoryHelpers::EnsureDirectoryExists(const char *path, bool isGlobalL
155162
throw SharedMemoryException(static_cast<DWORD>(SharedMemoryError::IO));
156163
}
157164

158-
// Check the directory's permissions and try to update them
165+
if (isSystemDirectory)
166+
{
167+
// For system directories (such as SHARED_MEMORY_TEMP_DIRECTORY_PATH), require sufficient permissions only for the
168+
// current user. For instance, "docker run --mount ..." to mount /tmp to some directory on the host mounts the
169+
// destination directory with the same permissions as the source directory, which may not include some permissions for
170+
// other users. In the docker container, other user permissions are typically not relevant and relaxing the permissions
171+
// requirement allows for that scenario to work without having to work around it by first giving sufficient permissions
172+
// for all users.
173+
if ((statInfo.st_mode & PermissionsMask_CurrentUser_ReadWriteExecute) == PermissionsMask_CurrentUser_ReadWriteExecute)
174+
{
175+
return true;
176+
}
177+
throw SharedMemoryException(static_cast<DWORD>(SharedMemoryError::IO));
178+
}
179+
180+
// For non-system directories (such as SHARED_MEMORY_RUNTIME_TEMP_DIRECTORY_PATH), require sufficient permissions for all
181+
// users and try to update them if requested to create the directory, so that shared memory files may be shared by all
182+
// processes on the system.
159183
if ((statInfo.st_mode & PermissionsMask_AllUsers_ReadWriteExecute) == PermissionsMask_AllUsers_ReadWriteExecute)
160184
{
161185
return true;
@@ -214,6 +238,8 @@ int SharedMemoryHelpers::CreateOrOpenFile(LPCSTR path, bool createIfNotExist, bo
214238
{
215239
_ASSERTE(path != nullptr);
216240
_ASSERTE(path[0] != '\0');
241+
_ASSERTE(SharedMemoryManager::IsCreationDeletionProcessLockAcquired());
242+
_ASSERTE(!createIfNotExist || SharedMemoryManager::IsCreationDeletionFileLockAcquired());
217243

218244
// Try to open the file
219245
int openFlags = O_RDWR;
@@ -1032,7 +1058,8 @@ void SharedMemoryManager::AcquireCreationDeletionFileLock()
10321058
if (!SharedMemoryHelpers::EnsureDirectoryExists(
10331059
SHARED_MEMORY_TEMP_DIRECTORY_PATH,
10341060
false /* isGlobalLockAcquired */,
1035-
false /* createIfNotExist */))
1061+
false /* createIfNotExist */,
1062+
true /* isSystemDirectory */))
10361063
{
10371064
throw SharedMemoryException(static_cast<DWORD>(SharedMemoryError::IO));
10381065
}

src/pal/src/synchobj/mutex.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1159,6 +1159,7 @@ SharedMemoryProcessDataHeader *NamedMutexProcessData::CreateOrOpen(
11591159
{
11601160
// If the shared memory file was created, the creation/deletion file lock would have been acquired so that we can
11611161
// initialize the shared data
1162+
_ASSERTE(SharedMemoryManager::IsCreationDeletionFileLockAcquired());
11621163
autoCleanup.m_acquiredCreationDeletionFileLock = true;
11631164
}
11641165
if (processDataHeader == nullptr)

0 commit comments

Comments
 (0)