--- /dev/null
+From f4e19e595cc2e76a8a58413eb19d3d9c51328b53 Mon Sep 17 00:00:00 2001
+From: Zhihao Cheng <chengzhihao1@huawei.com>
+Date: Tue, 16 May 2023 22:16:19 +0800
+Subject: ovl: fix null pointer dereference in ovl_get_acl_rcu()
+
+From: Zhihao Cheng <chengzhihao1@huawei.com>
+
+commit f4e19e595cc2e76a8a58413eb19d3d9c51328b53 upstream.
+
+Following process:
+ P1 P2
+ path_openat
+ link_path_walk
+ may_lookup
+ inode_permission(rcu)
+ ovl_permission
+ acl_permission_check
+ check_acl
+ get_cached_acl_rcu
+ ovl_get_inode_acl
+ realinode = ovl_inode_real(ovl_inode)
+ drop_cache
+ __dentry_kill(ovl_dentry)
+ iput(ovl_inode)
+ ovl_destroy_inode(ovl_inode)
+ dput(oi->__upperdentry)
+ dentry_kill(upperdentry)
+ dentry_unlink_inode
+ upperdentry->d_inode = NULL
+ ovl_inode_upper
+ upperdentry = ovl_i_dentry_upper(ovl_inode)
+ d_inode(upperdentry) // returns NULL
+ IS_POSIXACL(realinode) // NULL pointer dereference
+, will trigger an null pointer dereference at realinode:
+ [ 205.472797] BUG: kernel NULL pointer dereference, address:
+ 0000000000000028
+ [ 205.476701] CPU: 2 PID: 2713 Comm: ls Not tainted
+ 6.3.0-12064-g2edfa098e750-dirty #1216
+ [ 205.478754] RIP: 0010:do_ovl_get_acl+0x5d/0x300
+ [ 205.489584] Call Trace:
+ [ 205.489812] <TASK>
+ [ 205.490014] ovl_get_inode_acl+0x26/0x30
+ [ 205.490466] get_cached_acl_rcu+0x61/0xa0
+ [ 205.490908] generic_permission+0x1bf/0x4e0
+ [ 205.491447] ovl_permission+0x79/0x1b0
+ [ 205.491917] inode_permission+0x15e/0x2c0
+ [ 205.492425] link_path_walk+0x115/0x550
+ [ 205.493311] path_lookupat.isra.0+0xb2/0x200
+ [ 205.493803] filename_lookup+0xda/0x240
+ [ 205.495747] vfs_fstatat+0x7b/0xb0
+
+Fetch a reproducer in [Link].
+
+Use the helper ovl_i_path_realinode() to get realinode and then do
+non-nullptr checking.
+
+Link: https://bugzilla.kernel.org/show_bug.cgi?id=217404
+Fixes: 332f606b32b6 ("ovl: enable RCU'd ->get_acl()")
+Cc: <stable@vger.kernel.org> # v5.15
+Signed-off-by: Zhihao Cheng <chengzhihao1@huawei.com>
+Suggested-by: Christian Brauner <brauner@kernel.org>
+Suggested-by: Amir Goldstein <amir73il@gmail.com>
+Signed-off-by: Amir Goldstein <amir73il@gmail.com>
+Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/overlayfs/inode.c | 12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
+
+--- a/fs/overlayfs/inode.c
++++ b/fs/overlayfs/inode.c
+@@ -558,20 +558,20 @@ struct posix_acl *do_ovl_get_acl(struct
+ struct inode *inode, int type,
+ bool rcu, bool noperm)
+ {
+- struct inode *realinode = ovl_inode_real(inode);
++ struct inode *realinode;
+ struct posix_acl *acl;
+ struct path realpath;
+
+- if (!IS_POSIXACL(realinode))
+- return NULL;
+-
+ /* Careful in RCU walk mode */
+- ovl_i_path_real(inode, &realpath);
+- if (!realpath.dentry) {
++ realinode = ovl_i_path_real(inode, &realpath);
++ if (!realinode) {
+ WARN_ON(!rcu);
+ return ERR_PTR(-ECHILD);
+ }
+
++ if (!IS_POSIXACL(realinode))
++ return NULL;
++
+ if (rcu) {
+ /*
+ * If the layer is idmapped drop out of RCU path walk
--- /dev/null
+From 1a73f5b8f079fd42a544c1600beface50c63af7c Mon Sep 17 00:00:00 2001
+From: Zhihao Cheng <chengzhihao1@huawei.com>
+Date: Tue, 16 May 2023 22:16:18 +0800
+Subject: ovl: fix null pointer dereference in ovl_permission()
+
+From: Zhihao Cheng <chengzhihao1@huawei.com>
+
+commit 1a73f5b8f079fd42a544c1600beface50c63af7c upstream.
+
+Following process:
+ P1 P2
+ path_lookupat
+ link_path_walk
+ inode_permission
+ ovl_permission
+ ovl_i_path_real(inode, &realpath)
+ path->dentry = ovl_i_dentry_upper(inode)
+ drop_cache
+ __dentry_kill(ovl_dentry)
+ iput(ovl_inode)
+ ovl_destroy_inode(ovl_inode)
+ dput(oi->__upperdentry)
+ dentry_kill(upperdentry)
+ dentry_unlink_inode
+ upperdentry->d_inode = NULL
+ realinode = d_inode(realpath.dentry) // return NULL
+ inode_permission(realinode)
+ inode->i_sb // NULL pointer dereference
+, will trigger an null pointer dereference at realinode:
+ [ 335.664979] BUG: kernel NULL pointer dereference,
+ address: 0000000000000002
+ [ 335.668032] CPU: 0 PID: 2592 Comm: ls Not tainted 6.3.0
+ [ 335.669956] RIP: 0010:inode_permission+0x33/0x2c0
+ [ 335.678939] Call Trace:
+ [ 335.679165] <TASK>
+ [ 335.679371] ovl_permission+0xde/0x320
+ [ 335.679723] inode_permission+0x15e/0x2c0
+ [ 335.680090] link_path_walk+0x115/0x550
+ [ 335.680771] path_lookupat.isra.0+0xb2/0x200
+ [ 335.681170] filename_lookup+0xda/0x240
+ [ 335.681922] vfs_statx+0xa6/0x1f0
+ [ 335.682233] vfs_fstatat+0x7b/0xb0
+
+Fetch a reproducer in [Link].
+
+Use the helper ovl_i_path_realinode() to get realinode and then do
+non-nullptr checking.
+
+Link: https://bugzilla.kernel.org/show_bug.cgi?id=217405
+Fixes: 4b7791b2e958 ("ovl: handle idmappings in ovl_permission()")
+Cc: <stable@vger.kernel.org> # v5.19
+Signed-off-by: Zhihao Cheng <chengzhihao1@huawei.com>
+Suggested-by: Christian Brauner <brauner@kernel.org>
+Suggested-by: Amir Goldstein <amir73il@gmail.com>
+Signed-off-by: Amir Goldstein <amir73il@gmail.com>
+Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/overlayfs/inode.c | 5 ++---
+ 1 file changed, 2 insertions(+), 3 deletions(-)
+
+--- a/fs/overlayfs/inode.c
++++ b/fs/overlayfs/inode.c
+@@ -288,8 +288,8 @@ int ovl_permission(struct mnt_idmap *idm
+ int err;
+
+ /* Careful in RCU walk mode */
+- ovl_i_path_real(inode, &realpath);
+- if (!realpath.dentry) {
++ realinode = ovl_i_path_real(inode, &realpath);
++ if (!realinode) {
+ WARN_ON(!(mask & MAY_NOT_BLOCK));
+ return -ECHILD;
+ }
+@@ -302,7 +302,6 @@ int ovl_permission(struct mnt_idmap *idm
+ if (err)
+ return err;
+
+- realinode = d_inode(realpath.dentry);
+ old_cred = ovl_override_creds(inode->i_sb);
+ if (!upperinode &&
+ !special_file(realinode->i_mode) && mask & MAY_WRITE) {
--- /dev/null
+From b2dd05f107b11966e26fe52a313b418364cf497b Mon Sep 17 00:00:00 2001
+From: Zhihao Cheng <chengzhihao1@huawei.com>
+Date: Tue, 16 May 2023 22:16:17 +0800
+Subject: ovl: let helper ovl_i_path_real() return the realinode
+
+From: Zhihao Cheng <chengzhihao1@huawei.com>
+
+commit b2dd05f107b11966e26fe52a313b418364cf497b upstream.
+
+Let helper ovl_i_path_real() return the realinode to prepare for
+checking non-null realinode in RCU walking path.
+
+[msz] Use d_inode_rcu() since we are depending on the consitency
+between dentry and inode being non-NULL in an RCU setting.
+
+Signed-off-by: Zhihao Cheng <chengzhihao1@huawei.com>
+Signed-off-by: Amir Goldstein <amir73il@gmail.com>
+Fixes: ffa5723c6d25 ("ovl: store lower path in ovl_inode")
+Cc: <stable@vger.kernel.org> # v5.19
+Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/overlayfs/overlayfs.h | 2 +-
+ fs/overlayfs/util.c | 7 ++++---
+ 2 files changed, 5 insertions(+), 4 deletions(-)
+
+--- a/fs/overlayfs/overlayfs.h
++++ b/fs/overlayfs/overlayfs.h
+@@ -384,7 +384,7 @@ enum ovl_path_type ovl_path_type(struct
+ void ovl_path_upper(struct dentry *dentry, struct path *path);
+ void ovl_path_lower(struct dentry *dentry, struct path *path);
+ void ovl_path_lowerdata(struct dentry *dentry, struct path *path);
+-void ovl_i_path_real(struct inode *inode, struct path *path);
++struct inode *ovl_i_path_real(struct inode *inode, struct path *path);
+ enum ovl_path_type ovl_path_real(struct dentry *dentry, struct path *path);
+ enum ovl_path_type ovl_path_realdata(struct dentry *dentry, struct path *path);
+ struct dentry *ovl_dentry_upper(struct dentry *dentry);
+--- a/fs/overlayfs/util.c
++++ b/fs/overlayfs/util.c
+@@ -266,7 +266,7 @@ struct dentry *ovl_i_dentry_upper(struct
+ return ovl_upperdentry_dereference(OVL_I(inode));
+ }
+
+-void ovl_i_path_real(struct inode *inode, struct path *path)
++struct inode *ovl_i_path_real(struct inode *inode, struct path *path)
+ {
+ path->dentry = ovl_i_dentry_upper(inode);
+ if (!path->dentry) {
+@@ -275,6 +275,8 @@ void ovl_i_path_real(struct inode *inode
+ } else {
+ path->mnt = ovl_upper_mnt(OVL_FS(inode->i_sb));
+ }
++
++ return path->dentry ? d_inode_rcu(path->dentry) : NULL;
+ }
+
+ struct inode *ovl_inode_upper(struct inode *inode)
+@@ -1121,8 +1123,7 @@ void ovl_copyattr(struct inode *inode)
+ vfsuid_t vfsuid;
+ vfsgid_t vfsgid;
+
+- ovl_i_path_real(inode, &realpath);
+- realinode = d_inode(realpath.dentry);
++ realinode = ovl_i_path_real(inode, &realpath);
+ real_idmap = mnt_idmap(realpath.mnt);
+
+ vfsuid = i_uid_into_vfsuid(real_idmap, realinode);
kbuild-add-clang_flags-to-as-instr.patch
kbuild-add-kbuild_cppflags-to-as-option-invocation.patch
kbuild-add-clang_flags-to-kbuild_cppflags.patch
+ovl-fix-null-pointer-dereference-in-ovl_permission.patch
+ovl-let-helper-ovl_i_path_real-return-the-realinode.patch
+ovl-fix-null-pointer-dereference-in-ovl_get_acl_rcu.patch