The summary is rather long, but the problem arises when the merged directory of an overlayfs mount is under another directory that the application has full access to and we use '/' as the lowerdir and chroot into merged. This simulates the situation of something like schroot that wants a readonly '/' with all writes above it writable, but the mountpoint happens to be under a directory that schroot has full access to.
# merged/ is under COMMONDIR and because we give full access to COMMONDIR, the
# following alias rule ends up granting access to files in / as if they were in
# COMMONDIR (directories are correctly mediated)
alias / -> /tmp/tmp.sQqTm4RqpW/common/mnt/merged/,
profile test-profile (attach_disconnected) {
...
# full access to COMMONDIR
@{COMMONDIR}/ rw,
@{COMMONDIR}/** rwklix,
...
mount fstype=overlay overlay -> @{TOPDIR}/merged/,
}
Notice that there are no rules for @{TOPDIR}/merged in the policy. With the above, directories are properly mediated, but file and exec rules are not.
Reproducer:
$ tar -zxvf ./overlay-with-chroot-and-alias-rules.tar.gz && sudo ./overlay-with-chroot-and-alias-rules/drv
overlay-with-chroot-and-alias-rules/
overlay-with-chroot-and-alias-rules/p.in
overlay-with-chroot-and-alias-rules/overlay.c
overlay-with-chroot-and-alias-rules/drv
overlay-with-chroot-and-alias-rules/tst
Created tmpdir '/tmp/tmp.sQqTm4RqpW'
Test /etc (expect denied dir)
ls: cannot open directory '/etc': Permission denied
Test /etc/shadow (expect denied file read)
daemon:*:17268:0:99999:7:::
FAIL: could access /etc/shadow
Test netstat --version (expect denied exec)
/tmp/tmp.sQqTm4RqpW/data/tst: line 23: netstat: command not found
Cleaning up
- umount /tmp/tmp.sQqTm4RqpW/common/mnt/merged
- rm -rf /tmp/tmp.sQqTm4RqpW
The fact that directories are properly mediated here and that upper and lower rules are needed in bug #1703674 for directories makes me think that this bug and bug #1703674 may be related.
The summary is rather long, but the problem arises when the merged directory of an overlayfs mount is under another directory that the application has full access to and we use '/' as the lowerdir and chroot into merged. This simulates the situation of something like schroot that wants a readonly '/' with all writes above it writable, but the mountpoint happens to be under a directory that schroot has full access to.
Eg
@{TESTDIR} ="/tmp/ tmp.sQqTm4RqpW/ data" ="/tmp/ tmp.sQqTm4RqpW/ common" ="/tmp/ tmp.sQqTm4RqpW/ common/ mnt"
@{COMMONDIR}
@{TOPDIR}
# merged/ is under COMMONDIR and because we give full access to COMMONDIR, the sQqTm4RqpW/ common/ mnt/merged/ ,
# following alias rule ends up granting access to files in / as if they were in
# COMMONDIR (directories are correctly mediated)
alias / -> /tmp/tmp.
profile test-profile (attach_ disconnected) {
...
# full access to COMMONDIR
@{COMMONDIR}/ rw,
@{COMMONDIR}/** rwklix,
...
mount fstype=overlay overlay -> @{TOPDIR}/merged/,
}
Notice that there are no rules for @{TOPDIR}/merged in the policy. With the above, directories are properly mediated, but file and exec rules are not.
Reproducer: with-chroot- and-alias- rules.tar. gz && sudo ./overlay- with-chroot- and-alias- rules/drv with-chroot- and-alias- rules/ with-chroot- and-alias- rules/p. in with-chroot- and-alias- rules/overlay. c with-chroot- and-alias- rules/drv with-chroot- and-alias- rules/tst sQqTm4RqpW'
$ tar -zxvf ./overlay-
overlay-
overlay-
overlay-
overlay-
overlay-
Created tmpdir '/tmp/tmp.
Ubuntu 4.10.0- 26.30-generic 4.10.17
Disabling kernel rate-limiting printk_ ratelimit = 0
kernel.
Loading /tmp/tmp. sQqTm4RqpW/ data/p
chdir(/ tmp/tmp. sQqTm4RqpW/ common/ mnt)
Creating the overlay directories sQqTm4RqpW/ common/ mnt/lower sQqTm4RqpW/ common/ mnt/upper sQqTm4RqpW/ common/ mnt/work sQqTm4RqpW/ common/ mnt/merged
- mkdir /tmp/tmp.
- mkdir /tmp/tmp.
- mkdir /tmp/tmp.
- mkdir /tmp/tmp.
Populating /tmp/tmp. sQqTm4RqpW/ common/ mnt/lower sQqTm4RqpW/ common/ mnt/lower/ test-lower
- /tmp/tmp.
Populating /tmp/tmp. sQqTm4RqpW/ common/ mnt/upper sQqTm4RqpW/ common/ mnt/upper/ test-upper
- /tmp/tmp.
Creating /tmp/tmp. sQqTm4RqpW/ common/ mnt/scratch
Perform the overlay tmp/tmp. sQqTm4RqpW/ common/ mnt/upper tmp.sQqTm4RqpW/ common/ mnt/work tmp/tmp. sQqTm4RqpW/ common/ mnt/merged tmp.sQqTm4RqpW/ data/tst sQqTm4RqpW/ common/ mnt/merged' , 'overlay', MS_MGC_VAL, lowerdir= /,upperdir= /tmp/tmp. sQqTm4RqpW/ common/ mnt/upper, workdir= /tmp/tmp. sQqTm4RqpW/ common/ mnt/work /tmp/tmp. sQqTm4RqpW/ common/ mnt/merged' ) sQqTm4RqpW/ data/tst'
lower=/
upper=/
work=/tmp/
where=/
exe=/tmp/
- mount('overlay', '/tmp/tmp.
- success
- chdir('
- success
- chroot('.')
- success
starting '/tmp/tmp.
Test /etc (expect denied dir)
ls: cannot open directory '/etc': Permission denied
Test /etc/shadow (expect denied file read) *:17268: 0:99999: 7:::
daemon:
FAIL: could access /etc/shadow
Test netstat --version (expect denied exec) sQqTm4RqpW/ data/tst: line 23: netstat: command not found
/tmp/tmp.
Cleaning up sQqTm4RqpW/ common/ mnt/merged
- umount /tmp/tmp.
- rm -rf /tmp/tmp.sQqTm4RqpW
The fact that directories are properly mediated here and that upper and lower rules are needed in bug #1703674 for directories makes me think that this bug and bug #1703674 may be related.