yama hardlink restriction misbehaves under aufs

Bug #729338 reported by Kees Cook
30
This bug affects 5 people
Affects Status Importance Assigned to Milestone
linux (Ubuntu)
Triaged
Medium
Andy Whitcroft

Bug Description

On the mythbuntu liveCD mysqld throws errors during renaming of database files because hardlink restrictions are incorrectly triggered:

root@ubuntu:~# sudo -u mysql /bin/bash
mysql@ubuntu:/root$ id
uid=102(mysql) gid=105(mysql) groups=105(mysql)
mysql@ubuntu:/root$ cd /var/lib/mysql/mysql
mysql@ubuntu:/var/lib/mysql/mysql$ umask 0006
mysql@ubuntu:/var/lib/mysql/mysql$ touch cow
mysql@ubuntu:/var/lib/mysql/mysql$ ls -lda . user.MYI cow
drwx------ 2 mysql root 140 2011-03-04 12:44 .
-rw-rw---- 1 mysql mysql 0 2011-03-04 12:44 cow
-rw-rw---- 1 mysql mysql 2048 2011-03-01 19:04 user.MYI
mysql@ubuntu:/var/lib/mysql/mysql$ mv cow cow2
mysql@ubuntu:/var/lib/mysql/mysql$ mv user.MYI user2
mv: cannot move `user.MYI' to `user2': Operation not permitted
mysql@ubuntu:/var/lib/mysql/mysql$ dmesg | tail -n1
[ 6382.911220] non-accessible hardlink creation was attempted by: mv (fsuid 102)
mysql@ubuntu:/var/lib/mysql/mysql$ cat user.MYI > cow2
mysql@ubuntu:/var/lib/mysql/mysql$ ls -la cow2 user.MYI
-rw-rw---- 1 mysql mysql 2048 2011-03-04 12:45 cow2
-rw-rw---- 1 mysql mysql 2048 2011-03-01 19:04 user.MYI
mysql@ubuntu:/var/lib/mysql/mysql$ lsattr cow2 user.MYI
lsattr: Inappropriate ioctl for device While reading flags on cow2
lsattr: Inappropriate ioctl for device While reading flags on user.MYI
mysql@ubuntu:/var/lib/mysql/mysql$ df -h .
Filesystem Size Used Avail Use% Mounted on
aufs 247M 28M 220M 12% /
mysql@ubuntu:/var/lib/mysql/mysql$ grep aufs /proc/mounts
aufs / aufs rw,noatime,si=428526c014c98973 0 0
mysql@ubuntu:/var/lib/mysql/mysql$ exit
mysql@ubuntu:/var/lib/mysql/mysql# cd /sys/fs/aufs/si_428526c014c98973
root@ubuntu:/sys/fs/aufs/si_428526c014c98973# ls -la
total 0
drwxr-xr-x 2 root root 0 2011-03-04 12:52 .
drwxr-xr-x 3 root root 0 2011-03-04 12:52 ..
-r--r--r-- 1 root root 4096 2011-03-04 12:52 br0
-r--r--r-- 1 root root 4096 2011-03-04 12:52 br1
-r--r--r-- 1 root root 4096 2011-03-04 12:52 xi_path
root@ubuntu:/sys/fs/aufs/si_428526c014c98973# cat br0
/cow=rw
root@ubuntu:/sys/fs/aufs/si_428526c014c98973# cat br1
/rofs=rr

The main hardlink restriction check is this:
        if (cred->fsuid != inode->i_uid &&
            (!S_ISREG(mode) || (mode & S_ISUID) ||
             ((mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP)) ||
             (generic_permission(inode, MAY_READ | MAY_WRITE, 0, NULL))) &&
            !capable(CAP_FOWNER)) {
or, in english:
 * Block hardlink when all of:
 * - fsuid does not match inode
 * - not CAP_FOWNER
 * - and at least one of:
 * - inode is not a regular file
 * - inode is setuid
 * - inode is setgid and group-exec
 * - access failure for read and write

nothing visible in userspace seems to violate this, so this looks like some kind of aufs issue where the exposed inode does not match the toplevel visible to userspace? I'm not sure yet what's going on.

Revision history for this message
Andy Whitcroft (apw) wrote :

Managed to reproduce this on the Oneiric kernel, the error seems to be triggered on renaming of an object on the ro layer.

Changed in linux (Ubuntu):
status: New → Triaged
importance: Undecided → Low
assignee: nobody → Andy Whitcroft (apw)
importance: Low → Medium
Revision history for this message
Robert Collins (lifeless) wrote :

FWIW we see this in LXC containers when we use aufs to make ephemeral containers. An easy trigger seems to be deleting a file in the rw layer that exists in the ro layer.

Revision history for this message
Daniel (hackie) wrote :

Same problem here. Use this script to reproduce

----script:
testuser=set-a-valid-non-root-user
mkdir d1/
mkdir d1/x/
echo "This is a samefile-test" >d1/x/file.txt
chown $testuser: d1/x/ d1/x/*
mksquashfs d1/ testdata_L1.squashfs -noappend
mkdir L1root
mount -t squashfs -oloop ./testdata_L1.squashfs L1root/
mkdir L2top
mkdir aufs
mount -t aufs -odirs=L2top=rw:L1root=ro,sum none aufs/
su $testuser -c "rm --interactive=none /tmp/aufstest/aufs/x/file.txt" ; echo $?
dmesg | tail
----find L*/ aufs/ -ls after mounting
     2 0 drwxr-xr-x 3 root root 24 Okt 12 23:44 L1root/
     1 0 drwxr-xr-x 2 daniel daniel 31 Okt 12 23:44 L1root/x
     3 1 -rw-r--r-- 1 daniel daniel 24 Okt 12 23:44 L1root/x/file.txt
696501 4 drwxr-xr-x 4 root root 4096 Okt 12 23:44 L2top/
696504 4 drwx------ 2 root root 4096 Okt 12 23:44 L2top/.wh..wh.orph
696503 4 drwx------ 2 root root 4096 Okt 12 23:44 L2top/.wh..wh.plnk
656502 0 -r--r--r-- 1 root root 0 Okt 12 23:44 L2top/.wh..wh.aufs
     2 4 drwxr-xr-x 5 root root 4096 Okt 12 23:44 aufs/
    12 0 drwxr-xr-x 2 daniel daniel 31 Okt 12 23:44 aufs/x
    13 1 -rw-r--r-- 1 daniel daniel 24 Okt 12 23:44 aufs/x/file.txt
----

using both self-compiled aufs 2.2-standalone.tree-38-20110919 and default aufs.ko from 2.6.38-11-generic (natty)

To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.