This is an archive of the discontinued LLVM Phabricator instance.

[Support][Windows] Make sure only executables are found by sys::findProgramByName
ClosedPublic

Authored by zero9178 on Mar 25 2021, 11:01 AM.

Details

Summary

The function utilizes Windows' SearchPathW function, which as I found out today, may also return directories. After looking at the Unix implementation of the file I found that it contains a check whether the found path is also executable. While fixing the Windows implementation, I also learned that sys::fs::access returns successfully when querying whether directories are executable, which the Unix version does not.

This patch makes both of these functions equivalent to their Unix implementation and insures that any path returned by sys::findProgramByName on Windows may only be executable, just like the Unix implementation.

The equivalent additions I have made to the Windows implementation, in the Unix implementation are here:
sys::findProgramByName: https://github.com/llvm/llvm-project/blob/39ecfe614350fa5db7b8f13f81212f8e3831a390/llvm/lib/Support/Unix/Program.inc#L90
sys::fs::access: https://github.com/llvm/llvm-project/blob/c2a84771bb63947695ea50b89160c02b36fb634d/llvm/lib/Support/Unix/Path.inc#L608

I encountered this issue when running the LLVM testsuite. Commands of the form not test ... would fail to correctly execute test.exe, which is part of GnuWin32, as it actually tried to execute a folder called test, which happened to be in a directory on my PATH.

Regarding tests:
I added a test to check that sys::fs::access returns permission_denied for a directory. Besides that I am unsure how to test sys::findProgramByName, nor the not utility.

Diff Detail

Event Timeline

zero9178 created this revision.Mar 25 2021, 11:01 AM
zero9178 requested review of this revision.Mar 25 2021, 11:01 AM
Herald added a project: Restricted Project. · View Herald TranscriptMar 25 2021, 11:01 AM
rnk accepted this revision.Mar 25 2021, 12:14 PM

lgtm

This revision is now accepted and ready to land.Mar 25 2021, 12:14 PM
This revision was landed with ongoing or failed builds.Mar 25 2021, 12:30 PM
This revision was automatically updated to reflect the committed changes.

Just some drive-by comments.

llvm/lib/Support/Windows/Program.inc
65

Adding the empty string to the list of possible extensions for an executable seems like an odd thing to do on Windows (and that's a big part of the reason why SearchPathW is finding directories). I guess that's attempting to handle the case where Name already has the extension (e.g., "foo.exe"). In that case, I think the empty string should be conditional on whether the Name already has something that looks like an extension.

68

As the FIXME suggests, adding ".exe" is unnecessary. Worse it changes the search order. The PATHEXT environment variable determines not only what extensions are considered executable, but also what order they should be searched. Usually .COM and .BAT should be found before .EXE.

I would have done:

C++
if (const char *PathExtEnv = std::getenv("PATHEXT"))
    SplitString(PathExtEnv, PathExts, ";");
else
    PathExts.push_back(".exe");