Fix copying of symlinks in containers#14885
Conversation
|
ping @tonistiigi @thaJeztah |
|
see discussion in #13171 (comment) |
|
Can you please let us know if this is strictly required for 1.8.0, and if we're only fixing usability issues or potential security holes? |
|
@icecrime So far it's just a usability/behavior issue. We haven't yet determined if there's a real security issue with this. |
|
Because none of us is a security expert, I'd prefer to have the security team to have a look, ping @ewindisch @diogomonica @NathanMcCauley (just my 0.02, apologies if I crossed my boundaries here) |
|
This seems to only address the Stat-header issue and not rebasing. If I run This breaks symlink targets without slash. Any comment on the other points in #13171 (comment) ? |
daemon/archive.go
Outdated
There was a problem hiding this comment.
I think we should do this clean step always. There's a breakout with path /.. for example.
There was a problem hiding this comment.
ah, yeah. I'll remove this condition then.
|
Ok! Adding this to the milestone, we don't have to block 1.8.0-rc1 on it though. |
I'll add a test case for this and make sure it's fixed. |
There was a problem hiding this comment.
Rationale for removing this: It is never used, we have logic that uses it below, but I replaced it with the rebaseNames map.
|
|
|
@jlhawn I'm sure @ahmetalpbalkan is able to give you access to an azure machine 😄 |
|
@thaJeztah eh, no biggie... I have a windows 8.1 VM locally that I could use, I just haven't bothered setting up the docker dev environment on it. The test failure was also pretty minor: I was comparing a local windows backslash-delimited path with a constant unix-style forward-slash-delimited path. |
465df6a to
afb7388
Compare
|
@tonistiigi This should now fix the behavior you saw on the source being a symlink to a directory. As for your other question from #13171 (comment):
I think the only thing we could do is require that the container be stopped or paused? (can that be considered outside the scope of this PR?) |
5c268ea to
ec8e53d
Compare
|
Is The Having two separate code paths that do tar rebasing probably also isn't ideal maintenance-wise and I can't help to point out that by not having the first-level directory we could have probably avoided the need to do rebasing in both ends(plus the need to validate downloaded tar that we should probably also do). |
daemon/archive.go
Outdated
There was a problem hiding this comment.
This does not seem right. If the path is /myvolume/symlinktoroot/ it would be matched to the volume and writing would go to the readonly rootfs.
This should only apply to the source argument. From your example (thanks!) it looks like we've also erroneously applied it to the destination argument 😦. I'll fold this into this PR also (and add a test case for it based on your example). |
266dadd to
6c25a12
Compare
|
Okay, all updated again. Currently the |
69a564e to
9417a29
Compare
daemon/archive.go
Outdated
There was a problem hiding this comment.
What's the definition of Name? If its always basename of Path then why return as a separate field at all?
There was a problem hiding this comment.
Yes, it's the basename, while Path is the absolute path.
There was a problem hiding this comment.
I'll go ahead ad remove the Path field. Your right, it's unnecessary given that the user has to provide a path in the first place.
There was a problem hiding this comment.
Well, Path is cleaned and made absolute so it may actually have some value. Name, on the other hand, anyone can easily get from Path (if the definition remains as it is currently).
|
LGTM |
1 similar comment
|
LGTM |
f199312 to
05478d9
Compare
|
LGTM, but can we squash all those commits? all of the are related to the same thing and it would be easier to keep track of the for the release. |
|
@calavera okay, I'll squash them together |
[pkg/archive] Update archive/copy path handling - Remove unused TarOptions.Name field. - Add new TarOptions.RebaseNames field. - Update some of the logic around path dir/base splitting. - Update some of the logic behind archive entry name rebasing. [api/types] Add LinkTarget field to PathStat [daemon] Fix stat, archive, extract of symlinks These operations *should* resolve symlinks that are in the path but if the resource itself is a symlink then it *should not* be resolved. This patch puts this logic into a common function `resolvePath` which resolves symlinks of the path's dir in scope of the container rootfs but does not resolve the final element of the path. Now archive, extract, and stat operations will return symlinks if the path is indeed a symlink. [api/client] Update cp path hanling [docs/reference/api] Update description of stat Add the linkTarget field to the header of the archive endpoint. Remove path field. [integration-cli] Fix/Add cp symlink test cases Copying a symlink should do just that: copy the symlink NOT copy the target of the symlink. Also, the resulting file from the copy should have the name of the symlink NOT the name of the target file. Copying to a symlink should copy to the symlink target and not modify the symlink itself. Docker-DCO-1.1-Signed-off-by: Josh Hawn <[email protected]> (github: jlhawn)
|
💚 Merging! |
Fix copying of symlinks in containers
|
🎉 |
|
cherry picked into #15091 |
|
Great work guys! |
Copying a symlink should do just that: copy the symlink NOT copy the target of the symlink. Also, the resulting file from the copy should have the name of the symlink NOT the name of the target file.
This patch includes a fix to StatPath, ArchivePath, and ExtractToDir methods on containers. These operations should resolve symlinks that are in the path but if the resource itself is a symlink then it should not be resolved. This patch puts this logic into a common function
resolvePathwhich resolves symlinks of the path's dir in scope of the container rootfs but does not resolve the final element of the path. Now archive, extract, and stat operations will return symlinks if the path is indeed a symlink.Notably, destination paths should always be fully resolved, i.e., copying to a symlink should affect the symlink target, not the symlink itself.