зеркало из https://github.com/microsoft/BuildXL.git
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:
Родитель
96f8db5c1b
Коммит
069143520f
|
@ -105,5 +105,42 @@ namespace Test.BuildXL.Processes
|
||||||
AssertLogContains(GetRegex("readlink", "realDir/symlink.txt"));
|
AssertLogContains(GetRegex("readlink", "realDir/symlink.txt"));
|
||||||
AssertLogNotContains(GetRegex("readlink", "symlinkDir/file.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;
|
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)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
|
@ -191,6 +208,7 @@ int main(int argc, char **argv)
|
||||||
IF_COMMAND(TestAnonymousFile);
|
IF_COMMAND(TestAnonymousFile);
|
||||||
IF_COMMAND(FullPathResolutionOnReports);
|
IF_COMMAND(FullPathResolutionOnReports);
|
||||||
IF_COMMAND(ReadlinkReportDoesNotResolveFinalComponent);
|
IF_COMMAND(ReadlinkReportDoesNotResolveFinalComponent);
|
||||||
|
IF_COMMAND(FileDescriptorAccessesFullyResolvesPath);
|
||||||
|
|
||||||
// Invalid command
|
// Invalid command
|
||||||
exit(-1);
|
exit(-1);
|
||||||
|
|
|
@ -290,7 +290,10 @@ bool BxlObserver::ResolveEventPaths(buildxl::linux::SandboxEvent& event) {
|
||||||
if (event.GetDstFd() != -1) {
|
if (event.GetDstFd() != -1) {
|
||||||
FileDescriptorToPath(event.GetDstFd(), event.GetPid(), resolved_path_dst, PATH_MAX);
|
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;
|
break;
|
||||||
}
|
}
|
||||||
case buildxl::linux::SandboxEventPathType::kRelativePaths: {
|
case buildxl::linux::SandboxEventPathType::kRelativePaths: {
|
||||||
|
|
Загрузка…
Ссылка в новой задаче