aufs: kernel bug with apparmor and fuseblk
Affects | Status | Importance | Assigned to | Milestone | |
---|---|---|---|---|---|
linux (Ubuntu) |
Invalid
|
Undecided
|
Unassigned | ||
Bionic |
Fix Released
|
Low
|
Mauricio Faria de Oliveira | ||
Focal |
Fix Released
|
Low
|
Mauricio Faria de Oliveira | ||
Hirsute |
Fix Released
|
Low
|
Mauricio Faria de Oliveira | ||
Impish |
Invalid
|
Undecided
|
Unassigned | ||
Jammy |
Invalid
|
Undecided
|
Unassigned |
Bug Description
[Impact]
* AppArmor-enabled applications on the aufs filesystem
might hit a kernel bug when getting file attributes.
* The aufs filesystem explicitly assigns a NULL pointer
to `struct path.mnt` for `vfs_getattr()`, which calls
into AppArmor that checks `struct path.mnt-
triggering a kernel NULL pointer dereference.
* This is almost 10 years old [1,2], reproducible w/ the
Linux v3.2 kernel, but it's rare as apparently it needs
a fuseblk mount as an aufs branch, and file creation/
open (O_CREAT), with a filename that exists only in a
lower aufs branch. On Linux v5.15-rc* it doesn't need
AppArmor anymore.
[Fix]
* The patch fixing this issue does set `struct path.mnt`
properly, by taking `struct path` as parameter instead
of just `struct dentry` (and making up an incomplete
`struct path` w/ that `dentry` and `mnt = NULL`.)
* Since it changes the signature of a key, leaf function
with several callers, the patch is a bit long/refactor,
but it has been tested by the upstream aufs maintainer
with a private test-suite.
[Test Plan]
* Synthetic reproducer available in [1] and comment #1.
[Regression Potential]
* Regressions would probably manifest as kernel errors
mostly in the lookup and open paths, but more subtle
manifestations would be possible as well.
* The patch modifies a fair number of functions, even if
doing so in simple ways. The synthetic reproducer only
covers one of those functions.
* The other code paths have been tested by the maintainer
w/ the mainline kernel, and should be equivalent to our
kernel as none of such changed for cherry-
* The upstream aufs maintainer runs a private test suite
that covers several features and use cases of aufs, so
hopefully that provides some relief to take this patch.
[Other Info]
* Impish no longer ships aufs; no fix needed.
* Hirsute/
* Hirsute/Focal are clean cherry-picks.
* Bionic is a trivial backport.
[1] https:/
[2] https:/
[Kernel Traces]
BUG: kernel NULL pointer dereference, address: 0000000000000010
...
CPU: 23 PID: 17623 Comm: drone-agent Not tainted 5.4.0-1058-azure #60~18.04.1-Ubuntu
Hardware name: Microsoft Corporation Virtual Machine/Virtual Machine, BIOS 090008 12/07/2018
RIP: 0010:aa_
...
Call Trace:
? request_
path_name+0x60/0xe0
profile_
aa_path_
common_
common_
apparmor_
security_
vfs_getattr+
vfsub_update_
? lookup_
? lookup_
vfsub_lookup_
au_sio_
au_lkup_
aufs_lookup.
aufs_atomic_
path_openat+
? aufs_lookup+
? path_openat+
? unlock_
? filemap_
do_filp_
? __check_
? __alloc_
do_sys_
? do_sys_
__x64_sys_
do_syscall_
entry_SYSCALL_
RIP: 0033:0x4a06fa
Changed in linux (Ubuntu Hirsute): | |
status: | In Progress → Invalid |
status: | Invalid → In Progress |
description: | updated |
Changed in linux (Ubuntu Bionic): | |
status: | In Progress → Fix Committed |
Changed in linux (Ubuntu Focal): | |
status: | In Progress → Fix Committed |
Changed in linux (Ubuntu Hirsute): | |
status: | In Progress → Fix Committed |
Steps to Reproduce:
1) test app
# cat openat.c
#include <stdio.h>
#include <fcntl.h>
int main() {
perror( "openat" );
int rc;
rc = openat(AT_FDCWD, "test", O_RDWR | O_CREAT | S_IRWXU);
if (rc < 0) {
return 1;
}
return 0;
}
# gcc -o openat openat.c
2) ntfs-3g mount (fuseblk)
# truncate -s 1g ntfs.img
# DEV=$(losetup -f --show ntfs.img)
# mkfs.ntfs --fast $DEV
# mkdir ntfs
# mount -t ntfs-3g $DEV ntfs
# mount | grep ntfs | grep fuseblk user_id= 0,group_ id=0,allow_ other,blksize= 4096)
/dev/loop6 on /home/ubuntu/ntfs type fuseblk (rw,relatime,
3) aufs mount (with 'test' file in the read-only branch)
# mkdir ro aufs
# touch ro/test
# mount -t aufs -o br=ntfs:ro none aufs
4) enable apparmor for the test app (even in complain mode with aa-genprof)
# aa-genprof ./openat &
...
Please start the application to be profiled in
another window and exercise its functionality now.
...
<press enter>
[1]+ Stopped aa-genprof ./openat
5) remove 'test' file from read-write branch (still exists in read-only branch)
# cd aufs
# rm test
6) run the test app
# ../openat
Killed
7) check kernel logs
# dmesg