shiftfs: prevent lower dentries from going negative during unlink
Affects | Status | Importance | Assigned to | Milestone | |
---|---|---|---|---|---|
linux (Ubuntu) |
Fix Released
|
Medium
|
Christian Brauner | ||
Disco |
Won't Fix
|
Medium
|
Unassigned | ||
Eoan |
Fix Released
|
Medium
|
Unassigned |
Bug Description
SRU Justification
Impact: All non-special files (For shiftfs this only includes fifos and - for this case - unix sockets - since we don't allow character and block devices to be created.) go through shiftfs_open() and have their dentry pinned through this codepath preventing it from going negative. But fifos don't use the shiftfs fops but rather use the pipefifo_fops which means they do not go through shiftfs_open() and thus don't have their dentry pinned that way. Thus, the lower dentries for such files can go negative on unlink causing segfaults. The following C program can be used to reproduce the crash:
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
struct stat stat;
unlink("./bbb");
int ret = mknod("./bbb", S_IFIFO|0666, 0);
if (ret < 0)
exit(1);
int fd = open("./bbb", O_RDWR);
if (fd < 0)
exit(2);
if (unlink("./bbb"))
exit(4);
fstat(fd, &stat);
return 0;
}
Fix: Similar to ecryptfs we need to dget() the lower dentry before calling vfs_unlink() on it and dput() it afterwards.
Regression Potential: Limited to shiftfs.
Test Case: Compiled a kernel with the fix and used the reproducer above to verify that the kernel cannot be crashed anymore.
CVE References
Changed in linux (Ubuntu): | |
status: | New → Confirmed |
status: | Confirmed → In Progress |
assignee: | nobody → Christian Brauner (cbrauner) |
Changed in linux (Ubuntu): | |
importance: | Undecided → Medium |
Changed in linux (Ubuntu Disco): | |
importance: | Undecided → Medium |
Changed in linux (Ubuntu Eoan): | |
importance: | Undecided → Medium |
Changed in linux (Ubuntu Disco): | |
status: | New → In Progress |
Changed in linux (Ubuntu Eoan): | |
status: | New → In Progress |
Changed in linux (Ubuntu): | |
status: | In Progress → Fix Committed |
Changed in linux (Ubuntu Disco): | |
status: | In Progress → Fix Committed |
Changed in linux (Ubuntu Eoan): | |
status: | In Progress → Fix Committed |
tags: |
added: verification-done-eoan removed: verification-needed-eoan |
Changed in linux (Ubuntu Disco): | |
status: | Fix Committed → Won't Fix |
This bug is awaiting verification that the kernel in -proposed solves the problem. Please test the kernel and update this bug with the results. If the problem is solved, change the tag 'verification- needed- eoan' to 'verification- done-eoan' . If the problem still exists, change the tag 'verification- needed- eoan' to 'verification- failed- eoan'.
If verification is not done by 5 working days from today, this fix will be dropped from the source code, and this bug will be closed.
See https:/ /wiki.ubuntu. com/Testing/ EnableProposed for documentation how to enable and use -proposed. Thank you!