summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2021-06-15 19:26:19 +0300
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2021-06-16 12:36:36 +0300
commitb08854de4375b4bc8225b6513d586ebba9e5d038 (patch)
treed97f1605449d43ad1534c94eae0c0f6313df6d28
parentedcce01e0e50840a9aa6a70baed21477bdd2c9f9 (diff)
downloadlinux-b08854de4375b4bc8225b6513d586ebba9e5d038.tar.xz
proc: only require mm_struct for writing
commit 94f0b2d4a1d0c52035aef425da5e022bd2cb1c71 upstream. Commit 591a22c14d3f ("proc: Track /proc/$pid/attr/ opener mm_struct") we started using __mem_open() to track the mm_struct at open-time, so that we could then check it for writes. But that also ended up making the permission checks at open time much stricter - and not just for writes, but for reads too. And that in turn caused a regression for at least Fedora 29, where NIC interfaces fail to start when using NetworkManager. Since only the write side wanted the mm_struct test, ignore any failures by __mem_open() at open time, leaving reads unaffected. The write() time verification of the mm_struct pointer will then catch the failure case because a NULL pointer will not match a valid 'current->mm'. Link: https://lore.kernel.org/netdev/YMjTlp2FSJYvoyFa@unreal/ Fixes: 591a22c14d3f ("proc: Track /proc/$pid/attr/ opener mm_struct") Reported-and-tested-by: Leon Romanovsky <leon@kernel.org> Cc: Kees Cook <keescook@chromium.org> Cc: Christian Brauner <christian.brauner@ubuntu.com> Cc: Andrea Righi <andrea.righi@canonical.com> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--fs/proc/base.c4
1 files changed, 3 insertions, 1 deletions
diff --git a/fs/proc/base.c b/fs/proc/base.c
index 22fda757c5f2..0368ff9335cb 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -2495,7 +2495,9 @@ out:
#ifdef CONFIG_SECURITY
static int proc_pid_attr_open(struct inode *inode, struct file *file)
{
- return __mem_open(inode, file, PTRACE_MODE_READ_FSCREDS);
+ file->private_data = NULL;
+ __mem_open(inode, file, PTRACE_MODE_READ_FSCREDS);
+ return 0;
}
static ssize_t proc_pid_attr_read(struct file * file, char __user * buf,