--- /dev/null
+From 520da69d265a91c6536c63851cbb8a53946974f0 Mon Sep 17 00:00:00 2001
+From: Yuxuan Shui <yshuiv7@gmail.com>
+Date: Wed, 27 May 2020 04:08:02 +0100
+Subject: ovl: initialize error in ovl_copy_xattr
+
+From: Yuxuan Shui <yshuiv7@gmail.com>
+
+commit 520da69d265a91c6536c63851cbb8a53946974f0 upstream.
+
+In ovl_copy_xattr, if all the xattrs to be copied are overlayfs private
+xattrs, the copy loop will terminate without assigning anything to the
+error variable, thus returning an uninitialized value.
+
+If ovl_copy_xattr is called from ovl_clear_empty, this uninitialized error
+value is put into a pointer by ERR_PTR(), causing potential invalid memory
+accesses down the line.
+
+This commit initialize error with 0. This is the correct value because when
+there's no xattr to copy, because all xattrs are private, ovl_copy_xattr
+should succeed.
+
+This bug is discovered with the help of INIT_STACK_ALL and clang.
+
+Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
+Link: https://bugs.chromium.org/p/chromium/issues/detail?id=1050405
+Fixes: 0956254a2d5b ("ovl: don't copy up opaqueness")
+Cc: stable@vger.kernel.org # v4.8
+Signed-off-by: Alexander Potapenko <glider@google.com>
+Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/overlayfs/copy_up.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/fs/overlayfs/copy_up.c
++++ b/fs/overlayfs/copy_up.c
+@@ -43,7 +43,7 @@ int ovl_copy_xattr(struct dentry *old, s
+ {
+ ssize_t list_size, size, value_size = 0;
+ char *buf, *name, *value = NULL;
+- int uninitialized_var(error);
++ int error = 0;
+ size_t slen;
+
+ if (!(old->d_inode->i_opflags & IOP_XATTR) ||
--- /dev/null
+From ef1548adada51a2f32ed7faef50aa465e1b4c5da Mon Sep 17 00:00:00 2001
+From: "Eric W. Biederman" <ebiederm@xmission.com>
+Date: Fri, 12 Jun 2020 09:42:03 -0500
+Subject: proc: Use new_inode not new_inode_pseudo
+
+From: Eric W. Biederman <ebiederm@xmission.com>
+
+commit ef1548adada51a2f32ed7faef50aa465e1b4c5da upstream.
+
+Recently syzbot reported that unmounting proc when there is an ongoing
+inotify watch on the root directory of proc could result in a use
+after free when the watch is removed after the unmount of proc
+when the watcher exits.
+
+Commit 69879c01a0c3 ("proc: Remove the now unnecessary internal mount
+of proc") made it easier to unmount proc and allowed syzbot to see the
+problem, but looking at the code it has been around for a long time.
+
+Looking at the code the fsnotify watch should have been removed by
+fsnotify_sb_delete in generic_shutdown_super. Unfortunately the inode
+was allocated with new_inode_pseudo instead of new_inode so the inode
+was not on the sb->s_inodes list. Which prevented
+fsnotify_unmount_inodes from finding the inode and removing the watch
+as well as made it so the "VFS: Busy inodes after unmount" warning
+could not find the inodes to warn about them.
+
+Make all of the inodes in proc visible to generic_shutdown_super,
+and fsnotify_sb_delete by using new_inode instead of new_inode_pseudo.
+The only functional difference is that new_inode places the inodes
+on the sb->s_inodes list.
+
+I wrote a small test program and I can verify that without changes it
+can trigger this issue, and by replacing new_inode_pseudo with
+new_inode the issues goes away.
+
+Cc: stable@vger.kernel.org
+Link: https://lkml.kernel.org/r/000000000000d788c905a7dfa3f4@google.com
+Reported-by: syzbot+7d2debdcdb3cb93c1e5e@syzkaller.appspotmail.com
+Fixes: 0097875bd415 ("proc: Implement /proc/thread-self to point at the directory of the current thread")
+Fixes: 021ada7dff22 ("procfs: switch /proc/self away from proc_dir_entry")
+Fixes: 51f0885e5415 ("vfs,proc: guarantee unique inodes in /proc")
+Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/proc/inode.c | 2 +-
+ fs/proc/self.c | 2 +-
+ fs/proc/thread_self.c | 2 +-
+ 3 files changed, 3 insertions(+), 3 deletions(-)
+
+--- a/fs/proc/inode.c
++++ b/fs/proc/inode.c
+@@ -451,7 +451,7 @@ const struct inode_operations proc_link_
+
+ struct inode *proc_get_inode(struct super_block *sb, struct proc_dir_entry *de)
+ {
+- struct inode *inode = new_inode_pseudo(sb);
++ struct inode *inode = new_inode(sb);
+
+ if (inode) {
+ inode->i_ino = de->low_ino;
+--- a/fs/proc/self.c
++++ b/fs/proc/self.c
+@@ -42,7 +42,7 @@ int proc_setup_self(struct super_block *
+ inode_lock(root_inode);
+ self = d_alloc_name(s->s_root, "self");
+ if (self) {
+- struct inode *inode = new_inode_pseudo(s);
++ struct inode *inode = new_inode(s);
+ if (inode) {
+ inode->i_ino = self_inum;
+ inode->i_mtime = inode->i_atime = inode->i_ctime = current_time(inode);
+--- a/fs/proc/thread_self.c
++++ b/fs/proc/thread_self.c
+@@ -42,7 +42,7 @@ int proc_setup_thread_self(struct super_
+ inode_lock(root_inode);
+ thread_self = d_alloc_name(s->s_root, "thread-self");
+ if (thread_self) {
+- struct inode *inode = new_inode_pseudo(s);
++ struct inode *inode = new_inode(s);
+ if (inode) {
+ inode->i_ino = thread_self_inum;
+ inode->i_mtime = inode->i_atime = inode->i_ctime = current_time(inode);