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

Follow symlink for --device argument. #20684

Merged
merged 1 commit into from Mar 1, 2016
Merged

Follow symlink for --device argument. #20684

merged 1 commit into from Mar 1, 2016

Conversation

yongtang
Copy link
Member

This pull request fixes issue #13840 where a --device argument fails when the listed device is actually a symlink to a device. It checks to see if the path is a symlink and, if it is, resolves the symlink and continue the operation with the resolved path.

The tests are done in this way. First a symlink is created to link to /dev/zero. Then this symlink is used to map devices in the container. Inside the container a buffer is created and the md5 is calculated:

dd if=/dev/symzero bs=4K count=8 | md5sum

The expected md5 should be bb7df04e1b0a2570657527a7e108ae23.

Fixes: #13840

Signed-off-by: Yong Tang yong.tang.github@outlook.com

@thaJeztah
Copy link
Member

Should we have tests for this?

@yongtang
Copy link
Member Author

@thaJeztah Sure let me update the pull request.

@yongtang
Copy link
Member Author

@thaJeztah Just added the tests. Please let me know if you see any other issues.

@timthelion
Copy link
Contributor

Code looks good. It is certainly lucky that it was decided that --device and --volume should be separate. Otherwise, this PR would lead an absolutely devilish security problem:

Any volume that got mounted twice by the same image could contain a symlink to an otherwise forbidden device, because the first time the container was launched the symlink would be created, and the second time the container was launched, the symlink would be followed.

It might be worth adding a note in the docs that you can no longer safely use --device in an untrusted directory which might contain malicious symlinks...

@thaJeztah
Copy link
Member

It's still in design review, so we could consider making this behavior optional, e.g. Add an extra option (--device /foobar:follow-symlinks).

@timthelion
Copy link
Contributor

I don't think that there are many cases where the security flaw could happen, but the following one comes to mind, which I know exists in the wild:

$ docker run --volume=/dev/snd:/dev/snd --device=/dev/snd image-tag /path/to/executable

The reason why people do this is in order to get the /dev/snd/by-path/ to show up in the container. The exploit would be to have the container create a symlink in /dev/snd which would point to some otherwise forbidden device, say /dev/sda1. The next time the container was run (or any container which was passed the --device=/dev/snd argument, for that matter) that new container would have access to /dev/sda1. Even though the user who issued --volume=/dev/snd never had the intention of giving containers access to /dev/sda1...

Perhaps there really should be a :follow-symlinks option, because we know that this can be exploited in reality, even though it is really the fault of the people doing --volume=/dev/snd:/dev/snd rather than --volume=/dev/snd:/dev/snd:r. And not Docker's fault at all...

@calavera
Copy link
Contributor

LGTM

c.Assert(err, checker.IsNil)

// Create a temporary file, then a symbolic link to the temporary file
tmpFile := filepath.Join(tmpDir, "zero")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you explain this?
tmpFile is the same as symZero and then we're writing to it. Can we skip the tmpFile parts and instead use symZero?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@cpuguy83:
Sorry my bad. That was a bug/typo.
There are two tests:
In the first test is to create a symlink (tmpDir/zero) pointing to /dev/zero, then inside the container do a md5 calculation. This test is to show symlink to a device works.
In the second test, I was meant to create a temporary file, write some data into this temporary file, then create a symlink (tmpDir/file) pointing to the temporary file created. This test was meant to show that symlink to a file (not a device) will not work. (The name of the tmpFile should be something else, not filepath.Join(tmpDir, "zero"))
I will update the pull request shortly.

Fixes: #13840

Signed-off-by: Yong Tang <yong.tang.github@outlook.com>
@yongtang
Copy link
Member Author

yongtang commented Mar 1, 2016

@cpuguy83 Just updated the pull request. Let me know if there are any other issues.

@cpuguy83
Copy link
Member

cpuguy83 commented Mar 1, 2016

Thanks, LGTM.

cpuguy83 added a commit that referenced this pull request Mar 1, 2016
Follow symlink for --device argument.
@cpuguy83 cpuguy83 merged commit d883002 into moby:master Mar 1, 2016
@thaJeztah thaJeztah added this to the 1.11.0 milestone Mar 6, 2016
yongtang added a commit to yongtang/docker that referenced this pull request Apr 25, 2016
This fix tries to address the issue raised in moby#22271 where
relative symlinks don't work with --device argument.

Previously, the symlinks in --device was implemneted (moby#20684)
with `os.Readlink()` which does not resolve if the linked
target is a relative path. In this fix, `filepath.EvalSymlinks()`
has been used which will reolve correctly with relative
paths.

An additional test case has been added to the existing
`TestRunDeviceSymlink` to cover changes in this fix.

This fix is related to moby#13840 and moby#20684, moby#22271.
This fix fixes moby#22271.

Signed-off-by: Yong Tang <yong.tang.github@outlook.com>
liusdu pushed a commit to liusdu/moby that referenced this pull request Oct 30, 2017
This fix tries to address the issue raised in moby#22271 where
relative symlinks don't work with --device argument.

Previously, the symlinks in --device was implemneted (moby#20684)
with `os.Readlink()` which does not resolve if the linked
target is a relative path. In this fix, `filepath.EvalSymlinks()`
has been used which will reolve correctly with relative
paths.

An additional test case has been added to the existing
`TestRunDeviceSymlink` to cover changes in this fix.

backport from: moby#22272

Signed-off-by: Yong Tang <yong.tang.github@outlook.com>
Signed-off-by: Yuanhong Peng <pengyuanhong@huawei.com>
liusdu pushed a commit to liusdu/moby that referenced this pull request Oct 30, 2017
Relative symlinks don't work with --device argument

This fix tries to address the issue raised in moby#22271 where
relative symlinks don't work with --device argument.

Previously, the symlinks in --device was implemneted (moby#20684)
with `os.Readlink()` which does not resolve if the linked
target is a relative path. In this fix, `filepath.EvalSymlinks()`
has been used which will reolve correctly with relative
paths.

An additional test case has been added to the existing
`TestRunDeviceSymlink` to cover changes in this fix.

backport from: moby#22272

Signed-off-by: Yong Tang <yong.tang.github@outlook.com>
Signed-off-by: Yuanhong Peng <pengyuanhong@huawei.com>


See merge request docker/docker!348
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Follow symlink for --device argument
6 participants