Merged PR 785522: [Linux sandbox] Don't resolve paths that we got from /proc/self/fd. Add test coverage for intermediate symlink resolution

The paths we get from `/proc/self/fd` are already resolved
This commit is contained in:
Marcelo Lynch 🧉 2024-05-16 23:48:10 +00:00
Родитель 96f8db5c1b
Коммит 069143520f
3 изменённых файлов: 59 добавлений и 1 удалений

Просмотреть файл

@ -105,5 +105,42 @@ namespace Test.BuildXL.Processes
AssertLogContains(GetRegex("readlink", "realDir/symlink.txt"));
AssertLogNotContains(GetRegex("readlink", "symlinkDir/file.txt"));
}
[FactIfSupported(requiresSymlinkPermission: true)]
public void FileDescriptorAccessesFullyResolvesPath()
{
var tempFiles = new TempFileStorage(canGetFileNames : true);
var link = tempFiles.GetDirectory("symlinkDir", skipCreate: true);
var real = tempFiles.GetDirectory("realDir");
var realFile = tempFiles.GetFileName(real, "file.txt");
File.WriteAllText(realFile, "chelivery");
XAssert.IsTrue(File.Exists(realFile));
var createSymlink = FileUtilities.TryCreateSymbolicLink(link, real, isTargetFile: false);
if (!createSymlink.Succeeded)
{
XAssert.IsTrue(false, createSymlink.Failure.Describe());
}
var fileLink = tempFiles.GetFileName(real, "symlink.txt");
createSymlink = FileUtilities.TryCreateSymbolicLink(fileLink, realFile, isTargetFile: true);
if (!createSymlink.Succeeded)
{
XAssert.IsTrue(false, createSymlink.Failure.Describe());
}
RunNativeTest("FileDescriptorAccessesFullyResolvesPath", workingDirectory: tempFiles);
// The native side does:
// fd = open(symlinkDir/symlink.txt);
// __fxstat(fd)
// For the __fxstat report, we should associate the file descriptor to the real path, with the symlinks resolved
AssertLogContains(GetRegex("__fxstat", realFile));
// At some point (namely, on open) we also should get reports for the intermediate symlinks that got us to the file
AssertLogContains(GetRegex("_readlink", link));
AssertLogContains(GetRegex("_readlink", fileLink));
}
}
}

Просмотреть файл

@ -54,6 +54,23 @@ int ReadlinkReportDoesNotResolveFinalComponent()
return EXIT_SUCCESS;
}
// The managed side creates:
// - a directory symlink realDir -> symlinkDir
// - a file symlink realDir/symlink.txt -> realDir/real.txt.
int FileDescriptorAccessesFullyResolvesPath()
{
char buf[PATH_MAX] = { 0 };
GET_CWD;
std::string testFile(cwd);
testFile.append("/realDir/symlink.txt");
int fd = open("symlinkDir/symlink.txt", O_RDONLY);
struct stat sb;
// Use __fxtat as representative for a "file descriptor event"
__fxstat(1, fd, &sb);
return EXIT_SUCCESS;
}
int main(int argc, char **argv)
{
@ -191,6 +208,7 @@ int main(int argc, char **argv)
IF_COMMAND(TestAnonymousFile);
IF_COMMAND(FullPathResolutionOnReports);
IF_COMMAND(ReadlinkReportDoesNotResolveFinalComponent);
IF_COMMAND(FileDescriptorAccessesFullyResolvesPath);
// Invalid command
exit(-1);

Просмотреть файл

@ -290,7 +290,10 @@ bool BxlObserver::ResolveEventPaths(buildxl::linux::SandboxEvent& event) {
if (event.GetDstFd() != -1) {
FileDescriptorToPath(event.GetDstFd(), event.GetPid(), resolved_path_dst, PATH_MAX);
}
ResolveEventPaths(event, resolved_path_src, resolved_path_dst);
// FileDescriptorToPath returns a fully resolved path (by virtue of resolving /proc/self/fd/{fd})
// so no need to call ResolveEventPaths here, we can just set them directly
event.SetResolvedPaths(resolved_path_src, resolved_path_dst);
break;
}
case buildxl::linux::SandboxEventPathType::kRelativePaths: {