Skip to content
Closed
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 @@ -418,75 +418,87 @@ private static string InitalizeSharedFilesPath()

internal static SafeFileHandle CreateOrOpenFile(string sharedMemoryFilePath, SharedMemoryId id, bool createIfNotExist, out bool createdFile)
{
SafeFileHandle fd = Interop.Sys.Open(sharedMemoryFilePath, Interop.Sys.OpenFlags.O_RDWR | Interop.Sys.OpenFlags.O_CLOEXEC, 0);
Interop.ErrorInfo error = Interop.Sys.GetLastErrorInfo();
if (!fd.IsInvalid)
{
if (id.IsUserScope)
// Retry loop to handle the TOCTOU race between open(O_RDWR) returning ENOENT
// and open(O_CREAT|O_EXCL) returning EEXIST when another process creates the
// file in between.
for (int retries = 0; ; retries++)
Comment on lines +421 to +424
{
SafeFileHandle fd = Interop.Sys.Open(sharedMemoryFilePath, Interop.Sys.OpenFlags.O_RDWR | Interop.Sys.OpenFlags.O_CLOEXEC, 0);
Interop.ErrorInfo error = Interop.Sys.GetLastErrorInfo();
if (!fd.IsInvalid)
{
if (Interop.Sys.FStat(fd, out Interop.Sys.FileStatus fileStatus) != 0)
{
error = Interop.Sys.GetLastErrorInfo();
fd.Dispose();
throw Interop.GetExceptionForIoErrno(error, sharedMemoryFilePath);
}

if (fileStatus.Uid != id.Uid)
if (id.IsUserScope)
{
fd.Dispose();
throw new IOException(SR.Format(SR.IO_SharedMemory_FileNotOwnedByUid, sharedMemoryFilePath, id.Uid));
if (Interop.Sys.FStat(fd, out Interop.Sys.FileStatus fileStatus) != 0)
{
error = Interop.Sys.GetLastErrorInfo();
fd.Dispose();
throw Interop.GetExceptionForIoErrno(error, sharedMemoryFilePath);
}

if (fileStatus.Uid != id.Uid)
{
fd.Dispose();
throw new IOException(SR.Format(SR.IO_SharedMemory_FileNotOwnedByUid, sharedMemoryFilePath, id.Uid));
}

if ((fileStatus.Mode & (int)PermissionsMask_AllUsers_ReadWriteExecute) != (int)PermissionsMask_OwnerUser_ReadWrite)
{
fd.Dispose();
throw new IOException(SR.Format(SR.IO_SharedMemory_FilePermissionsIncorrect, sharedMemoryFilePath, PermissionsMask_OwnerUser_ReadWrite));
}
}
createdFile = false;
return fd;
}

if ((fileStatus.Mode & (int)PermissionsMask_AllUsers_ReadWriteExecute) != (int)PermissionsMask_OwnerUser_ReadWrite)
{
fd.Dispose();
throw new IOException(SR.Format(SR.IO_SharedMemory_FilePermissionsIncorrect, sharedMemoryFilePath, PermissionsMask_OwnerUser_ReadWrite));
}
if (error.Error != Interop.Error.ENOENT)
{
throw Interop.GetExceptionForIoErrno(error, sharedMemoryFilePath);
}
createdFile = false;
return fd;
}

if (error.Error != Interop.Error.ENOENT)
{
throw Interop.GetExceptionForIoErrno(error, sharedMemoryFilePath);
}
if (!createIfNotExist)
{
createdFile = false;
return fd;
}

if (!createIfNotExist)
{
createdFile = false;
return fd;
}
fd.Dispose();

fd.Dispose();
UnixFileMode permissionsMask = id.IsUserScope
? PermissionsMask_OwnerUser_ReadWrite
: PermissionsMask_AllUsers_ReadWrite;

UnixFileMode permissionsMask = id.IsUserScope
? PermissionsMask_OwnerUser_ReadWrite
: PermissionsMask_AllUsers_ReadWrite;
fd = Interop.Sys.Open(
sharedMemoryFilePath,
Interop.Sys.OpenFlags.O_RDWR | Interop.Sys.OpenFlags.O_CLOEXEC | Interop.Sys.OpenFlags.O_CREAT | Interop.Sys.OpenFlags.O_EXCL,
(int)permissionsMask);

fd = Interop.Sys.Open(
sharedMemoryFilePath,
Interop.Sys.OpenFlags.O_RDWR | Interop.Sys.OpenFlags.O_CLOEXEC | Interop.Sys.OpenFlags.O_CREAT | Interop.Sys.OpenFlags.O_EXCL,
(int)permissionsMask);
if (fd.IsInvalid)
{
error = Interop.Sys.GetLastErrorInfo();
if (error.Error == Interop.Error.EEXIST && retries < 1)
{
// Another process created the file between our open and create attempts.
// Retry the open to use the existing file.
continue;
}
Comment on lines +480 to +485
throw Interop.GetExceptionForIoErrno(error, sharedMemoryFilePath);
}

if (fd.IsInvalid)
{
error = Interop.Sys.GetLastErrorInfo();
throw Interop.GetExceptionForIoErrno(error, sharedMemoryFilePath);
}
int result = Interop.Sys.FChMod(fd, (int)permissionsMask);

int result = Interop.Sys.FChMod(fd, (int)permissionsMask);
if (result != 0)
{
error = Interop.Sys.GetLastErrorInfo();
fd.Dispose();
Interop.Sys.Unlink(sharedMemoryFilePath);
throw Interop.GetExceptionForIoErrno(error, sharedMemoryFilePath);
}

if (result != 0)
{
error = Interop.Sys.GetLastErrorInfo();
fd.Dispose();
Interop.Sys.Unlink(sharedMemoryFilePath);
throw Interop.GetExceptionForIoErrno(error, sharedMemoryFilePath);
createdFile = true;
return fd;
}

createdFile = true;
return fd;
}

internal static bool EnsureDirectoryExists(string directoryPath, SharedMemoryId id, bool isGlobalLockAcquired, bool createIfNotExist = true, bool isSystemDirectory = false)
Expand Down
Loading