This is an archive of the discontinued LLVM Phabricator instance.

[libcxx] [test] Ifdef out tests that rely on perms::none on directories for triggering errors
ClosedPublic

Authored by mstorsjo on Feb 26 2021, 3:25 AM.

Details

Summary

On windows, one can't use perms::none on a directory to trigger failures to read the directory entries.

This fixes 23 tests on windows.

Diff Detail

Event Timeline

mstorsjo created this revision.Feb 26 2021, 3:25 AM
mstorsjo requested review of this revision.Feb 26 2021, 3:25 AM
Herald added a project: Restricted Project. · View Herald TranscriptFeb 26 2021, 3:25 AM
Herald added 1 blocking reviewer(s): Restricted Project. · View Herald Transcript
ldionne requested changes to this revision.Mar 2 2021, 9:27 AM
ldionne added a subscriber: ldionne.

So actually, I think those tests are the same that fail when we run under sudo. I believe it would be useful to find an alternative way to trigger those failures. This would allow us to both run the tests on Windows and also would remove this weird quirk about running under sudo (which is useful e.g. when running in a Docker image).

Can you think of another way to do this? Could we change the owner of the directory?

This revision now requires changes to proceed.Mar 2 2021, 9:27 AM

Tagging @curdeius and @amccarth for input and ideas

So actually, I think those tests are the same that fail when we run under sudo. I believe it would be useful to find an alternative way to trigger those failures. This would allow us to both run the tests on Windows and also would remove this weird quirk about running under sudo (which is useful e.g. when running in a Docker image).

Can you think of another way to do this? Could we change the owner of the directory?

If a process running as root can iterate over a directory even after chmod 000, I don't think changing the owner would help. Dunno about windows - on the API level we operate so far, permissions only consist of a boolean readonly flag, not much more. On some other level, windows filesystems have full ACLs for controlling access though.

@curdeius Any ideas on this one? There's lots of tests that test the error cases when unable to read a directory, by giving those directories perms::none, which doesn't stop them from being read on windows. (On windows, the perms we have available essentially is only a binary readonly-flag.) And if I understand things right, these tests also fail if running the tests as root or in sudo, as one apparently ends up able to read the directories regardless, in those cases.

Tagging @curdeius and @amccarth for input and ideas
If a process running as root can iterate over a directory even after chmod 000, I don't think changing the owner would help. Dunno about windows - on the API level we operate so far, permissions only consist of a boolean readonly flag, not much more. On some other level, windows filesystems have full ACLs for controlling access though.

I can't think of a way to trigger a permission denied error with anything less than an ACL. And it might be hard for the owner that just created the directory to then lock itself out. And if it succeeded, then the test might have trouble cleaning up afterwards.

I having a hard time even thinking of a Windows directory that would block permission to list contents. The best I can come up with is C:\Users\SomebodyElse, but that's not guaranteed to exist on any other machine, and you couldn't temporarily change the permissions to set up the rest of the scenario being tested.

I tried thinking of something other than an access problem that would temporarily interfere with iterating directory contents, but I'm not coming up with any good options.

Unfortunately I haven't found anything really satisfying that will provoke this or similar behaviour on Windows without, as Adrian noted, accessing other user's folder or changing ACLs.
Funnily, I had the very same problem in one of my projects just last week.

Anyway, speaking of C:\Users\SomebodyElse and stuff. That's not really nice to do some setup using a different user.
But if we used an already existing directory to which a normal user does not have access rights?
E.g. a normal user cannot write to C:\Users\Default.
Also, one cannot traverse nor read the contents of C:\System Volume Information and this folder always exists (at least for Windows 7+, Server 2012+, probably even Server 2008). Maybe this would make the trick, at least for some tests?

Unfortunately I haven't found anything really satisfying that will provoke this or similar behaviour on Windows without, as Adrian noted, accessing other user's folder or changing ACLs.
Funnily, I had the very same problem in one of my projects just last week.

Anyway, speaking of C:\Users\SomebodyElse and stuff. That's not really nice to do some setup using a different user.
But if we used an already existing directory to which a normal user does not have access rights?
E.g. a normal user cannot write to C:\Users\Default.
Also, one cannot traverse nor read the contents of C:\System Volume Information and this folder always exists (at least for Windows 7+, Server 2012+, probably even Server 2008). Maybe this would make the trick, at least for some tests?

Thanks! That does indeed seem to work. Ideally I'd like to first check that it exists before proceeding with a test that assumes its existence and behaviour, but exists("C:\System Volume Information") fails as we don't really have access to access the directory much at all. We can iterate over C:\ and see that it's listed as one of the entries there though.

Converting all these instances to use that does feel like overkill, and most of these tests are kinda redundant with other tests, but there's at least a few instances where it can make sense to use this. And this did uncover a bug regarding the handling of the skip_permission_denied flag. I'll post a separate patch for that and a few tests to use that dir, and then we can update this one to ifdef out other cases that are less necessary.

mstorsjo updated this revision to Diff 336521.Apr 9 2021, 11:21 AM
mstorsjo edited the summary of this revision. (Show Details)

Updated after splitting out changes that use GetWindowsInaccessibleDir().

These remaining tests can't use GetWindowsInaccessibleDir() sensibly, e.g. for tests that rely on toggling accessibility back and forth during the test, or where the semantics of the dir provided by GetWindowsInaccessibleDir() doesn't allow for running the ifdeffed tests meaningfully.

@curdeius - WDYT about the rest of this?

curdeius accepted this revision as: curdeius.Apr 15 2021, 1:15 PM

No objection from my side. @ldionne?

Ping for second approval

@ldionne - TL;DR: Nobody has so far come up with a reliable crossplatform way of making those tests work under sudo. For windows, there's a special directory with suitable characteristics that work for some tests. (If it turns out the special dir doesn't exist or doesn't behave as we need it to, we use TEST_UNSUPPORTED() to bail out of that particular test - maybe such an approach could be used to waive failures when run under sudo, too? That's a separate effort anyway.) This patch now ifdefs out the remaining few cases where the special dir couldn't be used (e.g. where the test requires changing permissions back and forth during the test).

ldionne accepted this revision.Apr 19 2021, 11:49 AM

This LGTM, but can we perhaps define a macro like TEST_WIN_NO_FAILURES_WITH_PERMISSIONS defined when _WIN32 is defined (pick a better name) and use that instead? Just to avoid sprinkling naked _WIN32's in the test suite if we can. No need for review either way, but please consider my suggestion.

This revision is now accepted and ready to land.Apr 19 2021, 11:49 AM