-
Notifications
You must be signed in to change notification settings - Fork 18.8k
Docker should use /var/lib/docker/tmp for large temporary files. #6456
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
Conversation
|
Oh good call! +1 |
|
I'm okay with this unless anyone has illusions of running Docker on non-Unixy machines, although I'd prefer if we could set this as a runtime flag. The old code allowed setting a TMPDIR environment variable. |
|
Link related issue: #4396 |
|
-1 - we have used If hardcoding to |
|
Is it possible to use /var/tmp as default and let |
|
I think maybe the best fix would be to set TMPDIR=/var/tmp by default iff TMPDIR is not set. |
|
This patch will basically replace the TempDir patch from OS with one that defaults to /var/tmp. I am not sure if the is should also be done for the non daemon code path. Should continue to work on non Unix systems. |
|
I wonder if this needs documentation, as i assume that most users will think the default will be |
|
Not sure we document anything about the handling of temp content within docker. At least in the man pages I see no mention of tmp or temp. In a perfect world, I would not want the docker daemon saving this content to /tmp or /var/tmp. It should be saved in a place like /var/lib/docker so that evil users could not attempt to muck around with it. |
|
agreed - thing is, if we are using TMPDIR, we should be consistent with expectations. I wonder if we can consistently ensure no-one unwittingly uses /tmp or TMPDIR - or ... can we just default to |
|
I kind of like defaulting it to /var/lib/docker/tmp and then modifying all of the calls to MKTMP to use it. Not sure how this would effect non unit machines. |
|
@rhatdan What about manually setting TMPDIR for those particular systems which want to use /var/lib/docker/tmp? It's possible to reconfigure Docker today using TMPDIR to store large files in /var/lib/docker/tmp or /var/tmp. We can also change the code to default to /var/tmp by setting TMPDIR to that unless it's manually specified. |
|
Why not set this to /var/lib/docker/tmp and then allow it to be overridden by the user to be in /var/tmp or /tmp. Then make /var/lib/docker/tmp not searchable by anyone but root and docker users root docker 660 This would guarantee that a non priv user would not be able to attack/steal the image while it is in temporary storage. |
|
I don't really understand why we are discussing the security of /tmp. From my reading of documentation most programming languages provide a secure mktemp function, does golang not do so? Is this broken on weird kernels? |
|
Nobody here is discussing the security of |
|
Well I actually believe this is a potential security issue as well as a space issue. I wrote this blog in 2007 about this. https://danwalsh.livejournal.com/11467.html Having a privileged process write to /tmp or /var/tmp is potentially dangerous, mkstemp and friends are attempts of mitigating this danger. They probably will prevent well known guess attempts at the name, but the image could contain content that you might not want to leak to a unpriv user. and for a period of time this content could be stored in a temporary file. Do we make sure of the permissions on this temp content? Such that the user could not read it? I don't know? Are we sure in the future that no programmer will make a mistake on the protection flags. If we make /var/lib/docker/tmp as 660, and then default all tmp functions in docker to use it, there is a much smaller attack surface. The secondary issue is that these images can be large and we have already told people the images are stored in /var/lib/docker, so I would assume that the temporary content for the images would also fit there. Relying on /tmp or /var/tmp which would probably be on a different partition could be problematic. |
|
@rhatdan You say "If we make /var/lib/docker/tmp as 660, and then default all tmp functions in docker to use it, there is a much smaller attack surface." Does it actually reduce attack surface? It's only advantage is that it reduces the risk that a programmer would forget to set the file mode. If the file mode is set correctly and the mktemp function is implemented correctly(and really, a correctly implemented mktemp function should set the file mode correctly when you are root ;) ) there is no security risk. However, I agree that large files don't belong in |
|
Yes if Programmers do not create bugs we have nothing to worry about. :^( |
|
I'm +1 to using
|
|
Updated the patch to use /var/lib/docker/tmp. Also added to utils utils.RootDir to save the setting of the -g command. |
|
@rhatdan can you please push it :) |
|
@SvenDowideit oops. |
Additionally, this can be overridden by setting the TMPDIR variable, like this was already the case for the generic `mkimage.sh` script. As explained in moby#6456, the rationale to use `/var/tmp` instead of `/tmp` is that `/tmp` is often a small tmpfs filesystem with more restricted rights. Docker-DCO-1.1-Signed-off-by: Vincent Bernat <vincent@bernat.im> (github: vincentbernat)
| RootDir = "/var/lib/docker" | ||
| ) | ||
|
|
||
| func SetRootDir(tmpdir string) { |
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.
What has this got to do with tmpdir? I presume dir string would be more what you mean?
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.
Fixed
|
I feel it would be worth mentioning that the tmp dir defaults to otherwise its one of those hidden secrets only the code readers know. but on the other hand - maybe they are the only ones that have a good reason? |
|
I updated to patch to use DOCKER_TMPDIR, is this what you meant? |
|
So, I meant something more like: var tmpDir string
if tmpDir = os.Getenv("DOCKER_TMPDIR"); tmpDir == "" {
tmpDir = filepath.Join(RootDir, "tmp")
}
os.MkdirAll(...)
return tmpDir |
| rootdir = RootDir | ||
| } | ||
| dir := fmt.Sprintf("%s/tmp", rootdir) | ||
| if _, err := os.Stat(dir); os.IsNotExist(err) { |
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.
From godoc: If path is already a directory, MkdirAll does nothing and returns nil.
So no need for the if.
|
Renamed to tmpdir_unix.go |
| @@ -48,7 +48,7 @@ func main() { | |||
| bridgeName = flag.String([]string{"b", "-bridge"}, "", "Attach containers to a pre-existing network bridge\nuse 'none' to disable container networking") | |||
| bridgeIp = flag.String([]string{"#bip", "-bip"}, "", "Use this CIDR notation address for the network bridge's IP, not compatible with -b") | |||
| pidfile = flag.String([]string{"p", "-pidfile"}, "/var/run/docker.pid", "Path to use for daemon PID file") | |||
| flRoot = flag.String([]string{"g", "-graph"}, "/var/lib/docker", "Path to use as the root of the Docker runtime") | |||
| flRoot = flag.String([]string{"g", "-graph"}, utils.RootDir, "Path to use as the root of the Docker runtime") | |||
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.
I also think it makes more sense to store the RootDir variable not in utils, but in the var section of this file, just like dockerConfDir, unexported so rootDir. Then you could have utils.TempDir take the rootDir as a parameter. It just feels wrong to have the RootDir variable in the utils package. Let me know if you disagree.
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.
ping @rhatdan
|
Switched to use @tiborvass method. |
|
LGTM |
|
TestBuldForbiddenContextPath fails: |
|
#assignee=tiborvass |
|
@tiborvass What does this mean? I have rebased. |
|
@rhatdan rebasing was without conflict so it was mainly about fixing that test case. |
|
@tiborvass How does it look now? |
|
LGTM |
| if tmpDir = os.Getenv("DOCKER_TMPDIR"); tmpDir == "" { | ||
| tmpDir = filepath.Join(rootdir, "tmp") | ||
| } | ||
| os.MkdirAll(tmpDir, 0700) |
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.
Any particular reason we're ignoring any errors from MkdirAll? Would it be prudent to either not do that, or add a comment as to why we're doing that?
|
LGTM |
1 similar comment
|
LGTM |
|
LGTM (that's a docs quorum). ping @vieux @crosbymichael |
/tmp is often a tmpfs file system and large temporary files could cause docker commands to fail. Also using /tmp potentially allows users on the system to get access to content, or even attack the content. Moving the tmpdir to /var/lib/container/tmp will protect the data. Docker-DCO-1.1-Signed-off-by: Dan Walsh <dwalsh@redhat.com> (github: rhatdan) Conflicts: docker/docker.go
|
Rebased to current docker. Can we get this pull request upstream. |
|
ping @vieux @crosbymichael |
|
@crosbymichael This PR is good to go. Can you review it, please? |
Docker should use /var/lib/docker/tmp for large temporary files.
/tmp is often a tmpfs file system and large temporary files could cause
docker commands to fail.
Fixes #4396
Docker-DCO-1.1-Signed-off-by: Dan Walsh dwalsh@redhat.com (github: rhatdan)