--- /dev/null
+From 591a22c14d3f45cc38bd1931c593c221df2f1881 Mon Sep 17 00:00:00 2001
+From: Kees Cook <keescook@chromium.org>
+Date: Tue, 8 Jun 2021 10:12:21 -0700
+Subject: proc: Track /proc/$pid/attr/ opener mm_struct
+
+From: Kees Cook <keescook@chromium.org>
+
+commit 591a22c14d3f45cc38bd1931c593c221df2f1881 upstream.
+
+Commit bfb819ea20ce ("proc: Check /proc/$pid/attr/ writes against file opener")
+tried to make sure that there could not be a confusion between the opener of
+a /proc/$pid/attr/ file and the writer. It used struct cred to make sure
+the privileges didn't change. However, there were existing cases where a more
+privileged thread was passing the opened fd to a differently privileged thread
+(during container setup). Instead, use mm_struct to track whether the opener
+and writer are still the same process. (This is what several other proc files
+already do, though for different reasons.)
+
+Reported-by: Christian Brauner <christian.brauner@ubuntu.com>
+Reported-by: Andrea Righi <andrea.righi@canonical.com>
+Tested-by: Andrea Righi <andrea.righi@canonical.com>
+Fixes: bfb819ea20ce ("proc: Check /proc/$pid/attr/ writes against file opener")
+Cc: stable@vger.kernel.org
+Signed-off-by: Kees Cook <keescook@chromium.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/proc/base.c | 9 ++++++++-
+ 1 file changed, 8 insertions(+), 1 deletion(-)
+
+--- a/fs/proc/base.c
++++ b/fs/proc/base.c
+@@ -2527,6 +2527,11 @@ 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);
++}
++
+ static ssize_t proc_pid_attr_read(struct file * file, char __user * buf,
+ size_t count, loff_t *ppos)
+ {
+@@ -2557,7 +2562,7 @@ static ssize_t proc_pid_attr_write(struc
+ int rv;
+
+ /* A task may only write when it was the opener. */
+- if (file->f_cred != current_real_cred())
++ if (file->private_data != current->mm)
+ return -EPERM;
+
+ rcu_read_lock();
+@@ -2607,9 +2612,11 @@ out:
+ }
+
+ static const struct file_operations proc_pid_attr_operations = {
++ .open = proc_pid_attr_open,
+ .read = proc_pid_attr_read,
+ .write = proc_pid_attr_write,
+ .llseek = generic_file_llseek,
++ .release = mem_release,
+ };
+
+ #define LSM_DIR_OPS(LSM) \