Skip to content

Add test that ensures handles are not inherited #126628

@adamsitnik

Description

@adamsitnik

Edit: following approach turned out to be too complex to worth pursuing (all sys-calls allow us to get device path, which is something .NET users are not used to)

Details

As of today, FileStream.Name delegates all the work to the strategy:

/// <summary>Gets the path that was passed to the constructor.</summary>
public virtual string Name => _strategy.Name;

Which returns "[Unknown]" if path is not available:

internal sealed override string Name => _fileHandle.Path ?? SR.IO_UnknownFileName;

We should extend SafeFileHandle.Name with the ability to fetch the file path for regular files (and document it as a breaking change).

The Windows implementation from src/libraries/System.Private.CoreLib/src/Microsoft/Win32/SafeHandles/SafeFileHandle.Windows.cs should use the GetFinalPathNameByHandle sys-call to obtain the path.

The Unix implementation from src/libraries/System.Private.CoreLib/src/Microsoft/Win32/SafeHandles/SafeFileHandle.Unix.cs should extend pal_io.c and pal_io.h with a method that takes the file descriptor, buffer and writeable size and populates it with data:

  • calls readlink("/proc/self/fd/3", buf, size); on Linux
  • calls fcntl(fd, F_GETPATH, buf); on BSD systems (apple platforms + FreeBSD)
  • sets errno = ENOTSUP and returns -1 on other systems. In such case the calling managed method needs to return SR.IO_UnknownFileName

We don't need dedicated tests, it's fine to just extend the tests from src/libraries/System.Runtime/tests/System.IO.FileSystem.Tests/SafeFileHandle/GetFileType.cs.

We need to use the property in src/libraries/System.Diagnostics.Process/tests/ProcessHandlesTests.cs in order to implement a test that ensures that given file handle was not inherited when Process was started:

  • creates an inheritable SafeFileHandle that points to a regular file
  • spawns a new remote executor process with InheritedHandles = [] and passes the raw file descriptor as a string and file path to the RemoteExecutor.Invoke method. Then inside remote executor we need to ensure that given file handle is not available. If it's available, then we need to check the path it points to by creating a FileStream from it and using Name API and comparing it with the path passed via args.
  • use this test as a starting point

Metadata

Metadata

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions