Skip to content

unexpected file permission error in container #783

Closed
@astraw

Description

@astraw

I've narrowed down a problem in an originally more involved setup. Consider the following Dockerfile:

# Dockerfile
FROM      ubuntu:12.10

RUN apt-get install -y puppetmaster sudo

RUN rm -rf /etc/puppet
ADD puppet-config /etc/puppet
RUN chown -R puppet.puppet /etc/puppet
RUN chmod 755 /etc/puppet

When run with the following:

# make a dummy directory
mkdir puppet-config
echo "hi" >puppet-config/hello.txt

docker build -t dockbug .

echo "note the directory is owned by puppet with full read/write/execute privs"
docker run dockbug ls -al /etc/puppet

echo "but we get a permission error here"
docker run dockbug sudo -u puppet ls -al /etc/puppet

I see an unexpected permission error in the final command. This is with Docker 0.3.4 from the PPA on Ubuntu 13.04 with kernel 3.8.0-19-generic. Interestingly, if I remove the like "RUN rm -rf /etc/puppet" from the Dockerfile, I no longer see the permission error.

Activity

ghost assigned on Jun 1, 2013
creack

creack commented on Jun 1, 2013

@creack
Contributor

@jpetazzo can you take a look at this one?

jpetazzo

jpetazzo commented on Jun 11, 2013

@jpetazzo
Contributor

This is a kind of bug in AUFS. When a directory has a given permission mask in a lower layer, the upper layers cannot have a broader mask. Well, they can, but the more restrictive permission mask will be enforced anyways.

The rationale is the following:

  • suppose that you have directory /secret with permissions 0700, containing file /secret/key.pem
  • in an upper layer, you give /secret permissions 0755
  • now /secret/key.pem could become reachable

Multiple behaviors could be considered "acceptable" in this scenario:

  • give access to the file anyway (but this option was vetoed because it was deemed insecure)
  • prevent access
  • place a kind of "tombstone" or "opaque whiteout" for the whole directory so that the directory below becomes "opaqued" or "whited out", and the new one takes precedence

My understanding is that the last solution should be used, but for some reason, AUFS doesn't behave correctly. It might be because the directory exists in a lower layer, then doesn't exist anymore (because of the rm), then exists again (because of the ADD).

I'm willing to take a guess: the logic that decides whether or not to do a whiteout is not exactly the same as the one looking up permissions; so the first one stops when /etc/puppet is marked as non-existent in the middle layer, while the latter goes bottom up.

Anyway!

As a workaround, you can rm /etc/puppet/* instead of rm /etc/puppet, and that will do the trick.

shykes

shykes commented on Aug 13, 2013

@shykes
Contributor

Labelling as aufs-related.

shykes

shykes commented on Aug 13, 2013

@shykes
Contributor

Since this is documented aufs behavior, we can 1) close this as wontfix, 2) close + document the behavior in the docker docs, or 3) other?

shykes

shykes commented on Aug 13, 2013

@shykes
Contributor

@jpetazzo what do you think?

jpetazzo

jpetazzo commented on Aug 13, 2013

@jpetazzo
Contributor

Hmmm... What about a "KNOWN BUGS AND ISSUES" section in the documentation? /cc @metalivedev

metalivedev

metalivedev commented on Oct 14, 2013

@metalivedev
Contributor

Ok, some discussion here: https://botbot.me/freenode/docker-dev/msg/6889335/
I'll look at how to provide the known issues in context, which implies that the docs need some place to describe the file system in use.

xaviershay

xaviershay commented on Oct 15, 2013

@xaviershay

This bit me.

metalivedev

metalivedev commented on Oct 19, 2013

@metalivedev
Contributor

@xaviershay Could you give me the steps to reproduce the problem? I haven't been able to see an error with @astraw 's steps.

vagrant@precise64:~/src/783$ docker version
Client version: 0.6.4
Go version (client): go1.1.2
Git commit (client): 2f74b1c
Server version: 0.6.4
Git commit (server): 2f74b1c
Go version (server): go1.1.2
Last stable version: 0.6.4

vagrant@precise64:~/src/783$ docker build -t dockbug .
Uploading context 10240 bytes
Step 1 : FROM ubuntu:12.10
Pulling repository ubuntu
...
Step 6 : RUN chmod 755 /etc/puppet
 ---> Running in cf062fd724fb
 ---> 17620a2e9ea7
Successfully built 17620a2e9ea7

vagrant@precise64:~/src/783$ echo "note the directory is owned by puppet with full read/write/execute privs"
note the directory is owned by puppet with full read/write/execute privs

vagrant@precise64:~/src/783$ docker run dockbug ls -al /etc/puppet
total 12
drwxr-xr-x  2 puppet puppet 4096 Oct 19 00:18 .
drwxr-xr-x 78 root   root   4096 Oct 19 00:19 ..
-rw-rw-r--  1 puppet puppet    3 Oct 19 00:18 hello.txt

vagrant@precise64:~/src/783$ echo "but we get a permission error here"
but we get a permission error here

vagrant@precise64:~/src/783$ docker run dockbug sudo -u puppet ls -al /etc/puppet
total 12
drwxr-xr-x  2 puppet puppet 4096 Oct 19 00:18 .
drwxr-xr-x 78 root   root   4096 Oct 19 00:19 ..
-rw-rw-r--  1 puppet puppet    3 Oct 19 00:18 hello.txt

# HMM, no permission error
xaviershay

xaviershay commented on Oct 19, 2013

@xaviershay

Having trouble replicating again.

The shape of my setup was building an image on top of itself (which is potentially a terrible idea):

# Dockerfile.bootstrap
FROM ubuntu:12.10
# Dockerfile
FROM thisimage

RUN rm -Rf /app
RUN mkdir /app
docker build -t thisimage - < Dockerfile.boostrap
docker build -t thisimage - < Dockerfile
docker build -t thisimage - < Dockerfile # Do this a couple of times.
tianon

tianon commented on Oct 19, 2013

@tianon
Member

That looks to me like you'd run into the AUFS 42 layer limit pretty quickly.

xaviershay

xaviershay commented on Oct 19, 2013

@xaviershay

Yeah that was the next bug I hit :)

Have since redone my process to always build off a single base image.

147 remaining items

added a commit that references this issue on Oct 4, 2017
added a commit that references this issue on Dec 15, 2018
KnowSky404

KnowSky404 commented on Aug 23, 2021

@KnowSky404

rm /etc/puppet/* didn't work for me, instead I found that deleting individual files on the same layer works perfectly well:

find /etc/pappet -type f | xargs -L1 rm -f

Here is link to my Gist

Thanks, it works for me!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    area/docsarea/storage/aufsexp/beginnerkind/bugBugs are bugs. The cause may or may not be known at triage time so debugging may be needed.kind/enhancementEnhancements are not bugs or new features but can improve usability or performance.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

      Participants

      @xaviershay@lox@glasser@SvenDowideit@shykes

      Issue actions

        unexpected file permission error in container · Issue #783 · moby/moby