-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Taken from the justification in the launchpad bug: To a task in freezer cgroup /a/b/c/d, it should appear that there are no cgroups other than its descendents. Since this is a filesystem, we must have the parent directories, but each parent cgroup should only contain the child which the task can see. So, when this task looks at /a/b, it should see only directory 'c' and no files. Attempt to create /a/b/x should result in -EPERM, whether /a/b/x already exists or not. Attempts to query /a/b/x should result in -ENOENT whether /a/b/x exists or not. Opening /a/b/tasks should result in -ENOENT. The caller_may_see_dir checks specifically whether a task may see a cgroup directory - i.e. /a/b/x if opening /a/b/x/tasks, and /a/b/c/d if doing opendir('/a/b/c/d'). caller_is_in_ancestor() will return true if the caller in /a/b/c/d looks at /a/b/c/d/e. If the caller is in a child cgroup of the queried one - i.e. if the task in /a/b/c/d queries /a/b, then *nextcg will container the next (the only) directory which he can see in the path - 'c'. Beyond this, regular DAC permissions should apply, with the root-in-user-namespace privilege over its mapped uids being respected. The fc_may_access check does this check for both directories and files. This is CVE-2015-1342 (LP: #1508481) Signed-off-by: Serge Hallyn <[email protected]>
- Loading branch information
Showing
4 changed files
with
646 additions
and
46 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
#!/bin/bash | ||
|
||
set -ex | ||
|
||
[ $(id -u) -eq 0 ] | ||
|
||
d=$(mktemp -t -d tmp.XXX) | ||
d2=$(mktemp -t -d tmp.XXX) | ||
|
||
pid=-1 | ||
cleanup() { | ||
[ $pid -ne -1 ] && kill -9 $pid | ||
umount -l $d || true | ||
umount -l $d2 || true | ||
rm -rf $d $d2 | ||
} | ||
|
||
cmdline=$(realpath $0) | ||
dirname=$(dirname ${cmdline}) | ||
topdir=$(dirname ${dirname}) | ||
|
||
trap cleanup EXIT HUP INT TERM | ||
|
||
${topdir}/lxcfs $d & | ||
pid=$! | ||
|
||
# put ourselves into x1 | ||
cgm movepidabs freezer / $$ | ||
cgm create freezer x1 | ||
cgm movepid freezer x1 $$ | ||
|
||
mount -t cgroup -o freezer freezer $d2 | ||
sudo rmdir $d2/lxcfs_test_a1/lxcfs_test_a2 || true | ||
sudo rmdir $d2/lxcfs_test_a1 || true | ||
|
||
echo "Making sure root cannot mkdir" | ||
bad=0 | ||
mkdir $d/cgroup/freezer/lxcfs_test_a1 && bad=1 | ||
if [ "${bad}" -eq 1 ]; then | ||
false | ||
fi | ||
|
||
echo "Making sure root cannot rmdir" | ||
mkdir $d2/lxcfs_test_a1 | ||
mkdir $d2/lxcfs_test_a1/lxcfs_test_a2 | ||
rmdir $d/cgroup/freezer/lxcfs_test_a1 && bad=1 | ||
if [ "${bad}" -eq 1 ]; then | ||
false | ||
fi | ||
[ -d $d2/lxcfs_test_a1 ] | ||
rmdir $d/cgroup/freezer/lxcfs_test_a1/lxcfs_test_a2 && bad=1 | ||
if [ "${bad}" -eq 1 ]; then | ||
false | ||
fi | ||
[ -d $d2/lxcfs_test_a1/lxcfs_test_a2 ] | ||
|
||
echo "Making sure root cannot read/write" | ||
sleep 200 & | ||
p=$! | ||
echo $p > $d/cgroup/freezer/lxcfs_test_a1/tasks && bad=1 | ||
if [ "${bad}" -eq 1 ]; then | ||
false | ||
fi | ||
cat $d/cgroup/freezer/lxcfs_test_a1/tasks && bad=1 | ||
if [ "${bad}" -eq 1 ]; then | ||
false | ||
fi | ||
echo $p > $d/cgroup/freezer/lxcfs_test_a1/lxcfs_test_a2/tasks && bad=1 | ||
if [ "${bad}" -eq 1 ]; then | ||
false | ||
fi | ||
cat $d/cgroup/freezer/lxcfs_test_a1/lxcfs_test_a2/tasks && bad=1 | ||
if [ "${bad}" -eq 1 ]; then | ||
false | ||
fi | ||
|
||
# make sure things like truncate and access don't leak info about | ||
# the /lxcfs_test_a1 cgroup which we shouldn't be able to reach | ||
echo "Testing other system calls" | ||
${dirname}/test_syscalls $d/cgroup/freezer/lxcfs_test_a1 | ||
${dirname}/test_syscalls $d/cgroup/freezer/lxcfs_test_a1/lxcfs_test_a2 | ||
|
||
echo "Making sure root can act on descendents" | ||
mycg=$(cgm getpidcgroupabs freezer $$) | ||
newcg=${mycg}/lxcfs_test_a1 | ||
rmdir $d2/$newcg || true # cleanup previosu run | ||
mkdir $d/cgroup/freezer/$newcg | ||
echo $p > $d/cgroup/freezer/$newcg/tasks | ||
cat $d/cgroup/freezer/$newcg/tasks | ||
kill -9 $p | ||
while [ `wc -l $d/cgroup/freezer/$newcg/tasks | awk '{ print $1 }'` -ne 0 ]; do | ||
sleep 1 | ||
done | ||
rmdir $d/cgroup/freezer/$newcg | ||
|
||
echo "All tests passed!" |
Oops, something went wrong.