-
-
Notifications
You must be signed in to change notification settings - Fork 3k
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
get: Handle symlink creation and sanitize paths on Windows #4956
base: master
Are you sure you want to change the base?
Conversation
5b1032d
to
325696a
Compare
This should be a direct improvement, we're adding in 2 methods for regular users to create links, skipping them when creation is impossible, and sanitizing output to be platform legal. The only thing that needs a firm decision is, should we require users hold symlink-creation-privilege or not?
The functions in |
I should also mention that W10 support will only work in Go 1.11+ |
I have given this some thought. Originally, I was leaning towards skipping links on Windows to match (bugged) behaviour of previous However, since we can now handle link creation with the right privileges, I'm leaning towards erroring out and telling users how to alter their privileges. |
core/commands/get.go
Outdated
bar := makeProgressBar(gw.Err, gw.Size) | ||
bar.Start() | ||
defer bar.Finish() | ||
defer bar.Set64(gw.Size) | ||
|
||
extractor := &tar.Extractor{Path: fpath, Progress: bar.Add64} | ||
return extractor.Extract(r) | ||
if osh.IsWindows() { | ||
extractor.Sanitize(true) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would be great to pull this windows specific logic out into its own function
core/commands/get.go
Outdated
if osh.IsWindows() { | ||
extractor.Sanitize(true) | ||
builtinSanitizer := extractor.SanitizePathFunc | ||
extractor.SanitizePathFunc = func(path string) (string, error) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
also, if not too difficult, making these anonymous functions into real functions would improve readability here a good deal
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
actually, just doing this should clean everything up well enough
f4f3ca7
to
fadbeb7
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Cool, this LGTM. I'd like one more quick review before merge, either @kevina or @schomatis would be good.
Sure, I can take a look at it next week. |
I'd second this but don't have a strong opinion.
We could set links with non-existing targets aside and fill them in at the end. However, we can do this later. |
This PR has mostly specific Win stuff, I don't think I can review much here, I'll take a look at the (already merged) tar-utils PR that actually does the sanitizing against path traversal attacks (which the (Wow, I never imagined Win symlinking was this involved, great work @djdv!) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To the extent that I can review this (it has a lot of low-level windows code that I'm unfamiliar with), LGTM.
However:
- I'd still like to be smarter about directory versus file symlinks.
- We should make a final decision as to what to do by default.
46f1e88
to
5ea60b9
Compare
@Stebalien i'm assuming that those are blocking comments since you didnt give an explicit approval. |
Yes, the current patch will fail with a less-ambiguous error (previously: "Access denied"), pointing users to documentation about the issue. We always attempt to create the link, but if we encounter an error, we try to distinguish the reason based on the environment. Wall of text recap: The original alternative was to skip creating links, with a warning message, if we didn't have the ability to create them (as opposed to failing outright). This was proposed because a previous release version of The only other option I can think of, is adding a flag to
Agreed, this is something I would like to look into further. The current idea is to determine the type from the tar contents if we can, but ultimately, if the link points to a target outside of the hash/tar, I don't think we can determine which type is intended. |
I'd actually like to ban that outright for security reasons. Unfortunately, that would break valid use cases. I'd like to at least have a flag.
Got it. SGTM. So, I'd like to punt all the symlink stuff to: #5161. We can merge this once the tests pass (looks like a go fmt issue). |
License: MIT Signed-off-by: Dominic Della Valle <ddvpublic@gmail.com>
@schomatis A lot of this was discussed in a separate PR whyrusleeping/tar-utils#2 (unfortunately a lot over private email as well) We need hard decisions on what the default behaviour of symlinks should be and how to configure that behaviour for go-ipfs and through api calls. The default sanitizer implemented in the tar reader can be changed to support whatever symlink or path policies we want, either in that package or in go-ipfs, by changing the function pointers and cascading filter functions. Outside of some refactoring of the Windows specific systemcalls, this can be ready to go as soon as we decide how we wish symlinks to behave. |
I'll add too, at least 1 person was interested in also modifying symlinks during Some users are avoiding the issue by just resolving symlinks on add, but this won't fix all cases, and is only a solution for providers, not downloaders. This was implemented here but the functionality was split into 2 arguments |
This is my current work in progress for handling the issue of
get
ing symlinks on Windows.It relies on extending the tar-utils API whyrusleeping/tar-utils#2.
Giving us a method to sanitize paths and handle link creation however we like.
Note that the API extensions are not finalized themselves yet, see: whyrusleeping/tar-utils#2 (comment).Given the restrictions Windows imposes on symlinks, I've opted for a compromise where we will create symlinks if we have permission to, but skip them and warn the user if we don't (instead of failing out).
A similar approach will need to be taken in
gx
later, with its own set of rules.I'm looking for general criticism of the approach and implementation.
Some of my own thoughts on this:
Positive
get
hashes that contain linksWe want this for build dependencies that only use symlinks for testing and are not actually required for building<-This applies togo-ipfs-api
notgo-ipfs
Negative
Warning is currently too verbosewindows.md
if it encounters link issues. Telling users how they can enable the permission for their version of the OS.I'm unsure if the tar-utils patch seems good or if it's just a convenient hack/core/commands/get_sanitize_windows.go
should probably live in another repo. It checks and attempts to enable symlink creation privileges for the current process.Maybe in https://github.com/Kubuxu/go-os-helper asCanCreateLinks()
/x/sys/windows