Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

syscall: windows doesn't allow read-only directories #35042

Open
zx2c4 opened this issue Oct 21, 2019 · 9 comments
Open

syscall: windows doesn't allow read-only directories #35042

zx2c4 opened this issue Oct 21, 2019 · 9 comments
Labels
compiler/runtime Issues related to the Go compiler and/or runtime. Documentation NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. OS-Windows
Milestone

Comments

@zx2c4
Copy link
Contributor

zx2c4 commented Oct 21, 2019

On Windows, right now we map the lack of the writable bit in Unix file permissions to FILE_ATTRIBUTES_READONLY. This sort of works fine, but MSDN says that it's not honored for directories. This has implications for the Go module cache.

I'm not suggesting that we change this mapping to something else right now, but in case things pop up down the line related to this, here's a bug to track it.

cc @bcmills @alexbrainman

@dmitshur dmitshur added the NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. label Oct 21, 2019
@dmitshur dmitshur added this to the Backlog milestone Oct 21, 2019
@zx2c4
Copy link
Contributor Author

zx2c4 commented Oct 21, 2019

cc @jayconrod like the other bug.

@bcmills
Copy link
Contributor

bcmills commented Oct 21, 2019

Same question here: is there anything to actively do for this issue? (Should we leave it open, or close it and just use it as a point of reference?)

@bcmills bcmills modified the milestones: Backlog, Unplanned Oct 21, 2019
@bcmills
Copy link
Contributor

bcmills commented Oct 21, 2019

Hmm... At the very least, the documentation for os.Chmod should be updated.
It currently says:

On Windows, only the 0200 bit (owner writable) of mode is used; it controls whether the file's read-only attribute is set or cleared. The other bits are currently unused. For compatibility with Go 1.12 and earlier, use a non-zero mode. Use mode 0400 for a read-only file and 0600 for a readable+writable file.

It notably does not mention any behavior for directories.

@alexbrainman
Copy link
Member

Windows files and directory permissions cannot be mapped onto Unix user/group/everyone + read/write/execute. Most Windows users don't care about file permissions - as long as their files inherit permissions of containing directories, most things just work. For anything unusual Windows Go users would have to use Windows APIs directly.

More documentation is not always better. If documentation is long, people won't read it.

But we should correct wrong documentation.

Alex

@bcmills
Copy link
Contributor

bcmills commented Oct 22, 2019

I'm in way over my head, but from what I can tell there may be a reasonable mapping of the unix “write” permission bit to the windows ACTRL_DIR_CREATE_OBJECT, ACTRL_DIR_CREATE_CHILD or ACTRL_DS_CREATE_CHILD, and ACTRL_DIR_DELETE_CHILD or ACTRL_DS_DELETE_CHILD permissions.

Similarly, the execute bit might reasonably map to ACTRL_DIR_TRAVERSE or ACTRL_DS_LIST.

(But none of that is to say that we should actually implement that mapping.)

@alexbrainman
Copy link
Member

I'm in way over my head,

Same here. I will let Jason reply to you, if he wants to. I think we should leave things as they are.

Alex

@zx2c4
Copy link
Contributor Author

zx2c4 commented Oct 23, 2019

I'm in way over my head, but from what I can tell there may be a reasonable mapping of the unix “write” permission bit to the windows ACTRL_DIR_CREATE_OBJECT, ACTRL_DIR_CREATE_CHILD or ACTRL_DS_CREATE_CHILD, and ACTRL_DIR_DELETE_CHILD or ACTRL_DS_DELETE_CHILD permissions.

Similarly, the execute bit might reasonably map to ACTRL_DIR_TRAVERSE or ACTRL_DS_LIST.

(But none of that is to say that we should actually implement that mapping.)

Mapping Unix permission bits to Windows ACLs probably makes more sense than what we do now, which is mapping a single Unix permission bit to a "file attribute", which is not an ACL (and apparently doesn't work for directories either).

I think there probably would be a quasi coherent scheme we could come up with, for all of user, group, and world, and maybe even for the sticky bit. It would map better than what we currently have and would wind up supporting things like directories.

But it does certainly require more than a moment's thought. As with most things Windows, the devil is in the details.

The actual implementation would wind up looking something like:

func unixPermToSA(perm FileMode) *SECURITY_ATTRIBUTES
func saToUnixPerm(sa *SECURITY_ATTRIBUTES) FileMode

And then all of the various Windows file creation and retrieval functions will take or return a security attribute struct, which we're currently passing in as nil.

But, as I said, the devil is really in the details, and there are tons of unanswered questions. Then, let's say we get the mapping down. Do we want to emulate umask too? Probably, since people tend to pass in 0666 rather than 0644. So now we're doing umask emulation...

It all seems possible to do, but probably hard, and risky if it's not done right. So maybe this kind of project is best deferred until somebody actually complains compellingly about the status quo.

@networkimprov
Copy link

@jstarks has Microsoft published a guide re mapping Unix filemode to/from Windows security_attributes? Or is there .NET code to handle this?

@jstarks
Copy link

jstarks commented Oct 23, 2019

There is no such document that I am aware of.

I don't think you want to try to do anything automatic with ACLs. You're unlikely to come up with a policy that will make everyone happy.

@gopherbot gopherbot added the compiler/runtime Issues related to the Go compiler and/or runtime. label Jul 7, 2022
UnseenWizzard added a commit to Dynatrace/dynatrace-configuration-as-code that referenced this issue Sep 18, 2023
A new table-driven test is added, covering new cases as well as replacing
the two existing tests. Tests run in a temp dir filesystem, to ensure permission
issues are actually tested.

TestPrepareLogFile_ReturnsErrIfParentDirIsReadOnly is separate from the other
log file tests, as there is no portable way of handling folder permissions on
a real filesystem.
(Go has no way to set Windows folder permissions:golang/go#35042)

Thus it tests the "can't write even the .logs/ dir" case by setting the whole
afero FS to read only... In the real world, this would happen if the Windows
folder is marked read only, or POSIX permissions don't allow writing to it.
UnseenWizzard added a commit to Dynatrace/dynatrace-configuration-as-code that referenced this issue Sep 18, 2023
A new table-driven test is added, covering new cases as well as replacing
the two existing tests. Tests run in a temp dir filesystem, to ensure permission
issues are actually tested.

TestPrepareLogFile_ReturnsErrIfParentDirIsReadOnly is separate from the other
log file tests, as there is no portable way of handling folder permissions on
a real filesystem.
(Go has no way to set Windows folder permissions:golang/go#35042)

Thus it tests the "can't write even the .logs/ dir" case by setting the whole
afero FS to read only... In the real world, this would happen if the Windows
folder is marked read only, or POSIX permissions don't allow writing to it.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
compiler/runtime Issues related to the Go compiler and/or runtime. Documentation NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. OS-Windows
Projects
None yet
Development

No branches or pull requests

7 participants