Update mainline series

up to 0ee40e0e58eb ("FROMLIST: overlayfs: override_creds=off option bypass creator_cred")

Change-Id: I77a77d1faa37f99034c0115360bef63cce57d02d
diff --git a/android-mainline/FROMLIST-Add-flags-option-to-get-xattr-method-paired-to-__vfs_getxattr.patch b/android-mainline/FROMLIST-Add-flags-option-to-get-xattr-method-paired-to-__vfs_getxattr.patch
new file mode 100644
index 0000000..5918a55
--- /dev/null
+++ b/android-mainline/FROMLIST-Add-flags-option-to-get-xattr-method-paired-to-__vfs_getxattr.patch
@@ -0,0 +1,1025 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Mark Salyzyn <salyzyn@google.com>
+Date: Mon, 4 Nov 2019 08:57:10 -0800
+Subject: FROMLIST: Add flags option to get xattr method paired to
+ __vfs_getxattr
+
+Add a flag option to get xattr method that could have a bit flag of
+XATTR_NOSECURITY passed to it.  XATTR_NOSECURITY is generally then
+set in the __vfs_getxattr path when called by security
+infrastructure.
+
+This handles the case of a union filesystem driver that is being
+requested by the security layer to report back the xattr data.
+
+For the use case where access is to be blocked by the security layer.
+
+The path then could be security(dentry) ->
+__vfs_getxattr(dentry...XATTR_NOSECURITY) ->
+handler->get(dentry...XATTR_NOSECURITY) ->
+__vfs_getxattr(lower_dentry...XATTR_NOSECURITY) ->
+lower_handler->get(lower_dentry...XATTR_NOSECURITY)
+which would report back through the chain data and success as
+expected, the logging security layer at the top would have the
+data to determine the access permissions and report back the target
+context that was blocked.
+
+Without the get handler flag, the path on a union filesystem would be
+the errant security(dentry) -> __vfs_getxattr(dentry) ->
+handler->get(dentry) -> vfs_getxattr(lower_dentry) -> nested ->
+security(lower_dentry, log off) -> lower_handler->get(lower_dentry)
+which would report back through the chain no data, and -EACCES.
+
+For selinux for both cases, this would translate to a correctly
+determined blocked access. In the first case with this change a correct avc
+log would be reported, in the second legacy case an incorrect avc log
+would be reported against an uninitialized u:object_r:unlabeled:s0
+context making the logs cosmetically useless for audit2allow.
+
+This patch series is inert and is the wide-spread addition of the
+flags option for xattr functions, and a replacement of __vfs_getxattr
+with __vfs_getxattr(...XATTR_NOSECURITY).
+
+Signed-off-by: Mark Salyzyn <salyzyn@android.com>
+Reviewed-by: Jan Kara <jack@suse.cz>
+Acked-by: Jan Kara <jack@suse.cz>
+Acked-by: Jeff Layton <jlayton@kernel.org>
+Acked-by: David Sterba <dsterba@suse.com>
+Acked-by: Darrick J. Wong <darrick.wong@oracle.com>
+Acked-by: Mike Marshall <hubcap@omnibond.com>
+Cc: Stephen Smalley <sds@tycho.nsa.gov>
+Cc: linux-kernel@vger.kernel.org
+Cc: kernel-team@android.com
+Cc: linux-security-module@vger.kernel.org
+
+(cherry picked from (rejected from archive because of too many recipients))
+Signed-off-by: Mark Salyzyn <salyzyn@google.com>
+Bug: 133515582
+Bug: 136124883
+Bug: 129319403
+Change-Id: Iabbb8771939d5f66667a26bb23ddf4c562c349a1
+---
+ Documentation/filesystems/locking.rst |  2 +-
+ fs/9p/acl.c                           |  3 ++-
+ fs/9p/xattr.c                         |  3 ++-
+ fs/afs/xattr.c                        | 10 ++++----
+ fs/btrfs/xattr.c                      |  3 ++-
+ fs/ceph/xattr.c                       |  3 ++-
+ fs/cifs/xattr.c                       |  2 +-
+ fs/ecryptfs/inode.c                   |  6 +++--
+ fs/ecryptfs/mmap.c                    |  2 +-
+ fs/erofs/xattr.c                      |  3 ++-
+ fs/ext2/xattr_security.c              |  2 +-
+ fs/ext2/xattr_trusted.c               |  2 +-
+ fs/ext2/xattr_user.c                  |  2 +-
+ fs/ext4/xattr_security.c              |  2 +-
+ fs/ext4/xattr_trusted.c               |  2 +-
+ fs/ext4/xattr_user.c                  |  2 +-
+ fs/f2fs/xattr.c                       |  4 +--
+ fs/fuse/xattr.c                       |  4 +--
+ fs/gfs2/xattr.c                       |  3 ++-
+ fs/hfs/attr.c                         |  2 +-
+ fs/hfsplus/xattr.c                    |  3 ++-
+ fs/hfsplus/xattr_security.c           |  3 ++-
+ fs/hfsplus/xattr_trusted.c            |  3 ++-
+ fs/hfsplus/xattr_user.c               |  3 ++-
+ fs/jffs2/security.c                   |  3 ++-
+ fs/jffs2/xattr_trusted.c              |  3 ++-
+ fs/jffs2/xattr_user.c                 |  3 ++-
+ fs/jfs/xattr.c                        |  5 ++--
+ fs/kernfs/inode.c                     |  3 ++-
+ fs/nfs/nfs4proc.c                     |  6 +++--
+ fs/ocfs2/xattr.c                      |  9 ++++---
+ fs/orangefs/xattr.c                   |  3 ++-
+ fs/overlayfs/super.c                  |  8 +++---
+ fs/posix_acl.c                        |  2 +-
+ fs/reiserfs/xattr_security.c          |  3 ++-
+ fs/reiserfs/xattr_trusted.c           |  3 ++-
+ fs/reiserfs/xattr_user.c              |  3 ++-
+ fs/squashfs/xattr.c                   |  2 +-
+ fs/ubifs/xattr.c                      |  3 ++-
+ fs/xattr.c                            | 36 +++++++++++++--------------
+ fs/xfs/xfs_xattr.c                    |  3 ++-
+ include/linux/xattr.h                 |  9 ++++---
+ include/uapi/linux/xattr.h            |  7 ++++--
+ mm/shmem.c                            |  3 ++-
+ net/socket.c                          |  3 ++-
+ security/commoncap.c                  |  6 +++--
+ security/integrity/evm/evm_main.c     |  3 ++-
+ security/selinux/hooks.c              | 11 +++++---
+ security/smack/smack_lsm.c            |  5 ++--
+ 49 files changed, 131 insertions(+), 88 deletions(-)
+
+diff --git a/Documentation/filesystems/locking.rst b/Documentation/filesystems/locking.rst
+index fc3a0704553c..d4798204a5ee 100644
+--- a/Documentation/filesystems/locking.rst
++++ b/Documentation/filesystems/locking.rst
+@@ -125,7 +125,7 @@ prototypes::
+ 	bool (*list)(struct dentry *dentry);
+ 	int (*get)(const struct xattr_handler *handler, struct dentry *dentry,
+ 		   struct inode *inode, const char *name, void *buffer,
+-		   size_t size);
++		   size_t size, int flags);
+ 	int (*set)(const struct xattr_handler *handler, struct dentry *dentry,
+ 		   struct inode *inode, const char *name, const void *buffer,
+ 		   size_t size, int flags);
+diff --git a/fs/9p/acl.c b/fs/9p/acl.c
+index 6261719f6f2a..cb14e8b312bc 100644
+--- a/fs/9p/acl.c
++++ b/fs/9p/acl.c
+@@ -214,7 +214,8 @@ int v9fs_acl_mode(struct inode *dir, umode_t *modep,
+ 
+ static int v9fs_xattr_get_acl(const struct xattr_handler *handler,
+ 			      struct dentry *dentry, struct inode *inode,
+-			      const char *name, void *buffer, size_t size)
++			      const char *name, void *buffer, size_t size,
++			      int flags)
+ {
+ 	struct v9fs_session_info *v9ses;
+ 	struct posix_acl *acl;
+diff --git a/fs/9p/xattr.c b/fs/9p/xattr.c
+index ac8ff8ca4c11..5cfa772452fd 100644
+--- a/fs/9p/xattr.c
++++ b/fs/9p/xattr.c
+@@ -139,7 +139,8 @@ ssize_t v9fs_listxattr(struct dentry *dentry, char *buffer, size_t buffer_size)
+ 
+ static int v9fs_xattr_handler_get(const struct xattr_handler *handler,
+ 				  struct dentry *dentry, struct inode *inode,
+-				  const char *name, void *buffer, size_t size)
++				  const char *name, void *buffer, size_t size,
++				  int flags)
+ {
+ 	const char *full_name = xattr_full_name(handler, name);
+ 
+diff --git a/fs/afs/xattr.c b/fs/afs/xattr.c
+index 7af41fd5f3ee..e3a33d742e7f 100644
+--- a/fs/afs/xattr.c
++++ b/fs/afs/xattr.c
+@@ -40,7 +40,7 @@ ssize_t afs_listxattr(struct dentry *dentry, char *buffer, size_t size)
+ static int afs_xattr_get_acl(const struct xattr_handler *handler,
+ 			     struct dentry *dentry,
+ 			     struct inode *inode, const char *name,
+-			     void *buffer, size_t size)
++			     void *buffer, size_t size, int flags)
+ {
+ 	struct afs_fs_cursor fc;
+ 	struct afs_status_cb *scb;
+@@ -163,7 +163,7 @@ static const struct xattr_handler afs_xattr_afs_acl_handler = {
+ static int afs_xattr_get_yfs(const struct xattr_handler *handler,
+ 			     struct dentry *dentry,
+ 			     struct inode *inode, const char *name,
+-			     void *buffer, size_t size)
++			     void *buffer, size_t size, int flags)
+ {
+ 	struct afs_fs_cursor fc;
+ 	struct afs_status_cb *scb;
+@@ -334,7 +334,7 @@ static const struct xattr_handler afs_xattr_yfs_handler = {
+ static int afs_xattr_get_cell(const struct xattr_handler *handler,
+ 			      struct dentry *dentry,
+ 			      struct inode *inode, const char *name,
+-			      void *buffer, size_t size)
++			      void *buffer, size_t size, int flags)
+ {
+ 	struct afs_vnode *vnode = AFS_FS_I(inode);
+ 	struct afs_cell *cell = vnode->volume->cell;
+@@ -361,7 +361,7 @@ static const struct xattr_handler afs_xattr_afs_cell_handler = {
+ static int afs_xattr_get_fid(const struct xattr_handler *handler,
+ 			     struct dentry *dentry,
+ 			     struct inode *inode, const char *name,
+-			     void *buffer, size_t size)
++			     void *buffer, size_t size, int flags)
+ {
+ 	struct afs_vnode *vnode = AFS_FS_I(inode);
+ 	char text[16 + 1 + 24 + 1 + 8 + 1];
+@@ -399,7 +399,7 @@ static const struct xattr_handler afs_xattr_afs_fid_handler = {
+ static int afs_xattr_get_volume(const struct xattr_handler *handler,
+ 			      struct dentry *dentry,
+ 			      struct inode *inode, const char *name,
+-			      void *buffer, size_t size)
++			      void *buffer, size_t size, int flags)
+ {
+ 	struct afs_vnode *vnode = AFS_FS_I(inode);
+ 	const char *volname = vnode->volume->name;
+diff --git a/fs/btrfs/xattr.c b/fs/btrfs/xattr.c
+index 95d9aebff2c4..1e522e145344 100644
+--- a/fs/btrfs/xattr.c
++++ b/fs/btrfs/xattr.c
+@@ -353,7 +353,8 @@ ssize_t btrfs_listxattr(struct dentry *dentry, char *buffer, size_t size)
+ 
+ static int btrfs_xattr_handler_get(const struct xattr_handler *handler,
+ 				   struct dentry *unused, struct inode *inode,
+-				   const char *name, void *buffer, size_t size)
++				   const char *name, void *buffer, size_t size,
++				   int flags)
+ {
+ 	name = xattr_full_name(handler, name);
+ 	return btrfs_getxattr(inode, name, buffer, size);
+diff --git a/fs/ceph/xattr.c b/fs/ceph/xattr.c
+index cb18ee637cb7..a789f1e802b7 100644
+--- a/fs/ceph/xattr.c
++++ b/fs/ceph/xattr.c
+@@ -1153,7 +1153,8 @@ int __ceph_setxattr(struct inode *inode, const char *name,
+ 
+ static int ceph_get_xattr_handler(const struct xattr_handler *handler,
+ 				  struct dentry *dentry, struct inode *inode,
+-				  const char *name, void *value, size_t size)
++				  const char *name, void *value, size_t size,
++				  int flags)
+ {
+ 	if (!ceph_is_valid_xattr(name))
+ 		return -EOPNOTSUPP;
+diff --git a/fs/cifs/xattr.c b/fs/cifs/xattr.c
+index db4ba8f6077e..e44e562c46fb 100644
+--- a/fs/cifs/xattr.c
++++ b/fs/cifs/xattr.c
+@@ -199,7 +199,7 @@ static int cifs_creation_time_get(struct dentry *dentry, struct inode *inode,
+ 
+ static int cifs_xattr_get(const struct xattr_handler *handler,
+ 			  struct dentry *dentry, struct inode *inode,
+-			  const char *name, void *value, size_t size)
++			  const char *name, void *value, size_t size, int flags)
+ {
+ 	ssize_t rc = -EOPNOTSUPP;
+ 	unsigned int xid;
+diff --git a/fs/ecryptfs/inode.c b/fs/ecryptfs/inode.c
+index 18426f4855f1..c710c7533729 100644
+--- a/fs/ecryptfs/inode.c
++++ b/fs/ecryptfs/inode.c
+@@ -1018,7 +1018,8 @@ ecryptfs_getxattr_lower(struct dentry *lower_dentry, struct inode *lower_inode,
+ 		goto out;
+ 	}
+ 	inode_lock(lower_inode);
+-	rc = __vfs_getxattr(lower_dentry, lower_inode, name, value, size);
++	rc = __vfs_getxattr(lower_dentry, lower_inode, name, value, size,
++			    XATTR_NOSECURITY);
+ 	inode_unlock(lower_inode);
+ out:
+ 	return rc;
+@@ -1103,7 +1104,8 @@ const struct inode_operations ecryptfs_main_iops = {
+ 
+ static int ecryptfs_xattr_get(const struct xattr_handler *handler,
+ 			      struct dentry *dentry, struct inode *inode,
+-			      const char *name, void *buffer, size_t size)
++			      const char *name, void *buffer, size_t size,
++			      int flags)
+ {
+ 	return ecryptfs_getxattr(dentry, inode, name, buffer, size);
+ }
+diff --git a/fs/ecryptfs/mmap.c b/fs/ecryptfs/mmap.c
+index cffa0c1ec829..2362be3e3b4d 100644
+--- a/fs/ecryptfs/mmap.c
++++ b/fs/ecryptfs/mmap.c
+@@ -422,7 +422,7 @@ static int ecryptfs_write_inode_size_to_xattr(struct inode *ecryptfs_inode)
+ 	}
+ 	inode_lock(lower_inode);
+ 	size = __vfs_getxattr(lower_dentry, lower_inode, ECRYPTFS_XATTR_NAME,
+-			      xattr_virt, PAGE_SIZE);
++			      xattr_virt, PAGE_SIZE, XATTR_NOSECURITY);
+ 	if (size < 0)
+ 		size = 8;
+ 	put_unaligned_be64(i_size_read(ecryptfs_inode), xattr_virt);
+diff --git a/fs/erofs/xattr.c b/fs/erofs/xattr.c
+index a13a78725c57..144b1713ebab 100644
+--- a/fs/erofs/xattr.c
++++ b/fs/erofs/xattr.c
+@@ -463,7 +463,8 @@ int erofs_getxattr(struct inode *inode, int index,
+ 
+ static int erofs_xattr_generic_get(const struct xattr_handler *handler,
+ 				   struct dentry *unused, struct inode *inode,
+-				   const char *name, void *buffer, size_t size)
++				   const char *name, void *buffer, size_t size,
++				   int flags)
+ {
+ 	struct erofs_sb_info *const sbi = EROFS_I_SB(inode);
+ 
+diff --git a/fs/ext2/xattr_security.c b/fs/ext2/xattr_security.c
+index 9a682e440acb..d5f6eb0b487b 100644
+--- a/fs/ext2/xattr_security.c
++++ b/fs/ext2/xattr_security.c
+@@ -11,7 +11,7 @@
+ static int
+ ext2_xattr_security_get(const struct xattr_handler *handler,
+ 			struct dentry *unused, struct inode *inode,
+-			const char *name, void *buffer, size_t size)
++			const char *name, void *buffer, size_t size, int flags)
+ {
+ 	return ext2_xattr_get(inode, EXT2_XATTR_INDEX_SECURITY, name,
+ 			      buffer, size);
+diff --git a/fs/ext2/xattr_trusted.c b/fs/ext2/xattr_trusted.c
+index 49add1107850..8d313664f0fa 100644
+--- a/fs/ext2/xattr_trusted.c
++++ b/fs/ext2/xattr_trusted.c
+@@ -18,7 +18,7 @@ ext2_xattr_trusted_list(struct dentry *dentry)
+ static int
+ ext2_xattr_trusted_get(const struct xattr_handler *handler,
+ 		       struct dentry *unused, struct inode *inode,
+-		       const char *name, void *buffer, size_t size)
++		       const char *name, void *buffer, size_t size, int flags)
+ {
+ 	return ext2_xattr_get(inode, EXT2_XATTR_INDEX_TRUSTED, name,
+ 			      buffer, size);
+diff --git a/fs/ext2/xattr_user.c b/fs/ext2/xattr_user.c
+index c243a3b4d69d..712b7c95cc64 100644
+--- a/fs/ext2/xattr_user.c
++++ b/fs/ext2/xattr_user.c
+@@ -20,7 +20,7 @@ ext2_xattr_user_list(struct dentry *dentry)
+ static int
+ ext2_xattr_user_get(const struct xattr_handler *handler,
+ 		    struct dentry *unused, struct inode *inode,
+-		    const char *name, void *buffer, size_t size)
++		    const char *name, void *buffer, size_t size, int flags)
+ {
+ 	if (!test_opt(inode->i_sb, XATTR_USER))
+ 		return -EOPNOTSUPP;
+diff --git a/fs/ext4/xattr_security.c b/fs/ext4/xattr_security.c
+index 197a9d8a15ef..50fb71393fb6 100644
+--- a/fs/ext4/xattr_security.c
++++ b/fs/ext4/xattr_security.c
+@@ -15,7 +15,7 @@
+ static int
+ ext4_xattr_security_get(const struct xattr_handler *handler,
+ 			struct dentry *unused, struct inode *inode,
+-			const char *name, void *buffer, size_t size)
++			const char *name, void *buffer, size_t size, int flags)
+ {
+ 	return ext4_xattr_get(inode, EXT4_XATTR_INDEX_SECURITY,
+ 			      name, buffer, size);
+diff --git a/fs/ext4/xattr_trusted.c b/fs/ext4/xattr_trusted.c
+index e9389e5d75c3..64bd8f86c1f1 100644
+--- a/fs/ext4/xattr_trusted.c
++++ b/fs/ext4/xattr_trusted.c
+@@ -22,7 +22,7 @@ ext4_xattr_trusted_list(struct dentry *dentry)
+ static int
+ ext4_xattr_trusted_get(const struct xattr_handler *handler,
+ 		       struct dentry *unused, struct inode *inode,
+-		       const char *name, void *buffer, size_t size)
++		       const char *name, void *buffer, size_t size, int flags)
+ {
+ 	return ext4_xattr_get(inode, EXT4_XATTR_INDEX_TRUSTED,
+ 			      name, buffer, size);
+diff --git a/fs/ext4/xattr_user.c b/fs/ext4/xattr_user.c
+index d4546184b34b..b7301373820e 100644
+--- a/fs/ext4/xattr_user.c
++++ b/fs/ext4/xattr_user.c
+@@ -21,7 +21,7 @@ ext4_xattr_user_list(struct dentry *dentry)
+ static int
+ ext4_xattr_user_get(const struct xattr_handler *handler,
+ 		    struct dentry *unused, struct inode *inode,
+-		    const char *name, void *buffer, size_t size)
++		    const char *name, void *buffer, size_t size, int flags)
+ {
+ 	if (!test_opt(inode->i_sb, XATTR_USER))
+ 		return -EOPNOTSUPP;
+diff --git a/fs/f2fs/xattr.c b/fs/f2fs/xattr.c
+index 181900af2576..95cfcf1589df 100644
+--- a/fs/f2fs/xattr.c
++++ b/fs/f2fs/xattr.c
+@@ -25,7 +25,7 @@
+ 
+ static int f2fs_xattr_generic_get(const struct xattr_handler *handler,
+ 		struct dentry *unused, struct inode *inode,
+-		const char *name, void *buffer, size_t size)
++		const char *name, void *buffer, size_t size, int flags)
+ {
+ 	struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb);
+ 
+@@ -80,7 +80,7 @@ static bool f2fs_xattr_trusted_list(struct dentry *dentry)
+ 
+ static int f2fs_xattr_advise_get(const struct xattr_handler *handler,
+ 		struct dentry *unused, struct inode *inode,
+-		const char *name, void *buffer, size_t size)
++		const char *name, void *buffer, size_t size, int flags)
+ {
+ 	if (buffer)
+ 		*((char *)buffer) = F2FS_I(inode)->i_advise;
+diff --git a/fs/fuse/xattr.c b/fs/fuse/xattr.c
+index 20d052e08b3b..414718a51c25 100644
+--- a/fs/fuse/xattr.c
++++ b/fs/fuse/xattr.c
+@@ -176,7 +176,7 @@ int fuse_removexattr(struct inode *inode, const char *name)
+ 
+ static int fuse_xattr_get(const struct xattr_handler *handler,
+ 			 struct dentry *dentry, struct inode *inode,
+-			 const char *name, void *value, size_t size)
++			 const char *name, void *value, size_t size, int flags)
+ {
+ 	return fuse_getxattr(inode, name, value, size);
+ }
+@@ -199,7 +199,7 @@ static bool no_xattr_list(struct dentry *dentry)
+ 
+ static int no_xattr_get(const struct xattr_handler *handler,
+ 			struct dentry *dentry, struct inode *inode,
+-			const char *name, void *value, size_t size)
++			const char *name, void *value, size_t size, int flags)
+ {
+ 	return -EOPNOTSUPP;
+ }
+diff --git a/fs/gfs2/xattr.c b/fs/gfs2/xattr.c
+index bbe593d16bea..a9db067a99c1 100644
+--- a/fs/gfs2/xattr.c
++++ b/fs/gfs2/xattr.c
+@@ -588,7 +588,8 @@ static int __gfs2_xattr_get(struct inode *inode, const char *name,
+ 
+ static int gfs2_xattr_get(const struct xattr_handler *handler,
+ 			  struct dentry *unused, struct inode *inode,
+-			  const char *name, void *buffer, size_t size)
++			  const char *name, void *buffer, size_t size,
++			  int flags)
+ {
+ 	struct gfs2_inode *ip = GFS2_I(inode);
+ 	struct gfs2_holder gh;
+diff --git a/fs/hfs/attr.c b/fs/hfs/attr.c
+index 74fa62643136..08222a9c5d31 100644
+--- a/fs/hfs/attr.c
++++ b/fs/hfs/attr.c
+@@ -115,7 +115,7 @@ static ssize_t __hfs_getxattr(struct inode *inode, enum hfs_xattr_type type,
+ 
+ static int hfs_xattr_get(const struct xattr_handler *handler,
+ 			 struct dentry *unused, struct inode *inode,
+-			 const char *name, void *value, size_t size)
++			 const char *name, void *value, size_t size, int flags)
+ {
+ 	return __hfs_getxattr(inode, handler->flags, value, size);
+ }
+diff --git a/fs/hfsplus/xattr.c b/fs/hfsplus/xattr.c
+index bb0b27d88e50..381c2aaedbc8 100644
+--- a/fs/hfsplus/xattr.c
++++ b/fs/hfsplus/xattr.c
+@@ -839,7 +839,8 @@ static int hfsplus_removexattr(struct inode *inode, const char *name)
+ 
+ static int hfsplus_osx_getxattr(const struct xattr_handler *handler,
+ 				struct dentry *unused, struct inode *inode,
+-				const char *name, void *buffer, size_t size)
++				const char *name, void *buffer, size_t size,
++				int flags)
+ {
+ 	/*
+ 	 * Don't allow retrieving properly prefixed attributes
+diff --git a/fs/hfsplus/xattr_security.c b/fs/hfsplus/xattr_security.c
+index cfbe6a3bfb1e..43e28b3a716d 100644
+--- a/fs/hfsplus/xattr_security.c
++++ b/fs/hfsplus/xattr_security.c
+@@ -15,7 +15,8 @@
+ 
+ static int hfsplus_security_getxattr(const struct xattr_handler *handler,
+ 				     struct dentry *unused, struct inode *inode,
+-				     const char *name, void *buffer, size_t size)
++				     const char *name, void *buffer,
++				     size_t size, int flags)
+ {
+ 	return hfsplus_getxattr(inode, name, buffer, size,
+ 				XATTR_SECURITY_PREFIX,
+diff --git a/fs/hfsplus/xattr_trusted.c b/fs/hfsplus/xattr_trusted.c
+index fbad91e1dada..54d926314f8c 100644
+--- a/fs/hfsplus/xattr_trusted.c
++++ b/fs/hfsplus/xattr_trusted.c
+@@ -14,7 +14,8 @@
+ 
+ static int hfsplus_trusted_getxattr(const struct xattr_handler *handler,
+ 				    struct dentry *unused, struct inode *inode,
+-				    const char *name, void *buffer, size_t size)
++				    const char *name, void *buffer,
++				    size_t size, int flags)
+ {
+ 	return hfsplus_getxattr(inode, name, buffer, size,
+ 				XATTR_TRUSTED_PREFIX,
+diff --git a/fs/hfsplus/xattr_user.c b/fs/hfsplus/xattr_user.c
+index 74d19faf255e..4d2b1ffff887 100644
+--- a/fs/hfsplus/xattr_user.c
++++ b/fs/hfsplus/xattr_user.c
+@@ -14,7 +14,8 @@
+ 
+ static int hfsplus_user_getxattr(const struct xattr_handler *handler,
+ 				 struct dentry *unused, struct inode *inode,
+-				 const char *name, void *buffer, size_t size)
++				 const char *name, void *buffer, size_t size,
++				 int flags)
+ {
+ 
+ 	return hfsplus_getxattr(inode, name, buffer, size,
+diff --git a/fs/jffs2/security.c b/fs/jffs2/security.c
+index c2332e30f218..e6f42fe435af 100644
+--- a/fs/jffs2/security.c
++++ b/fs/jffs2/security.c
+@@ -50,7 +50,8 @@ int jffs2_init_security(struct inode *inode, struct inode *dir,
+ /* ---- XATTR Handler for "security.*" ----------------- */
+ static int jffs2_security_getxattr(const struct xattr_handler *handler,
+ 				   struct dentry *unused, struct inode *inode,
+-				   const char *name, void *buffer, size_t size)
++				   const char *name, void *buffer, size_t size,
++				   int flags)
+ {
+ 	return do_jffs2_getxattr(inode, JFFS2_XPREFIX_SECURITY,
+ 				 name, buffer, size);
+diff --git a/fs/jffs2/xattr_trusted.c b/fs/jffs2/xattr_trusted.c
+index 5d6030826c52..9dccaae549f5 100644
+--- a/fs/jffs2/xattr_trusted.c
++++ b/fs/jffs2/xattr_trusted.c
+@@ -18,7 +18,8 @@
+ 
+ static int jffs2_trusted_getxattr(const struct xattr_handler *handler,
+ 				  struct dentry *unused, struct inode *inode,
+-				  const char *name, void *buffer, size_t size)
++				  const char *name, void *buffer, size_t size,
++				  int flags)
+ {
+ 	return do_jffs2_getxattr(inode, JFFS2_XPREFIX_TRUSTED,
+ 				 name, buffer, size);
+diff --git a/fs/jffs2/xattr_user.c b/fs/jffs2/xattr_user.c
+index 9d027b4abcf9..c0983a3e810b 100644
+--- a/fs/jffs2/xattr_user.c
++++ b/fs/jffs2/xattr_user.c
+@@ -18,7 +18,8 @@
+ 
+ static int jffs2_user_getxattr(const struct xattr_handler *handler,
+ 			       struct dentry *unused, struct inode *inode,
+-			       const char *name, void *buffer, size_t size)
++			       const char *name, void *buffer, size_t size,
++			       int flags)
+ {
+ 	return do_jffs2_getxattr(inode, JFFS2_XPREFIX_USER,
+ 				 name, buffer, size);
+diff --git a/fs/jfs/xattr.c b/fs/jfs/xattr.c
+index db41e7803163..5c79a35bf62f 100644
+--- a/fs/jfs/xattr.c
++++ b/fs/jfs/xattr.c
+@@ -925,7 +925,7 @@ static int __jfs_xattr_set(struct inode *inode, const char *name,
+ 
+ static int jfs_xattr_get(const struct xattr_handler *handler,
+ 			 struct dentry *unused, struct inode *inode,
+-			 const char *name, void *value, size_t size)
++			 const char *name, void *value, size_t size, int flags)
+ {
+ 	name = xattr_full_name(handler, name);
+ 	return __jfs_getxattr(inode, name, value, size);
+@@ -942,7 +942,8 @@ static int jfs_xattr_set(const struct xattr_handler *handler,
+ 
+ static int jfs_xattr_get_os2(const struct xattr_handler *handler,
+ 			     struct dentry *unused, struct inode *inode,
+-			     const char *name, void *value, size_t size)
++			     const char *name, void *value, size_t size,
++			     int flags)
+ {
+ 	if (is_known_namespace(name))
+ 		return -EOPNOTSUPP;
+diff --git a/fs/kernfs/inode.c b/fs/kernfs/inode.c
+index f3eaa8869f42..22357c69a82b 100644
+--- a/fs/kernfs/inode.c
++++ b/fs/kernfs/inode.c
+@@ -308,7 +308,8 @@ int kernfs_xattr_set(struct kernfs_node *kn, const char *name,
+ 
+ static int kernfs_vfs_xattr_get(const struct xattr_handler *handler,
+ 				struct dentry *unused, struct inode *inode,
+-				const char *suffix, void *value, size_t size)
++				const char *suffix, void *value, size_t size,
++				int flags)
+ {
+ 	const char *name = xattr_full_name(handler, suffix);
+ 	struct kernfs_node *kn = inode->i_private;
+diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
+index caacf5e7f5e1..f77ddd31b57a 100644
+--- a/fs/nfs/nfs4proc.c
++++ b/fs/nfs/nfs4proc.c
+@@ -7283,7 +7283,8 @@ static int nfs4_xattr_set_nfs4_acl(const struct xattr_handler *handler,
+ 
+ static int nfs4_xattr_get_nfs4_acl(const struct xattr_handler *handler,
+ 				   struct dentry *unused, struct inode *inode,
+-				   const char *key, void *buf, size_t buflen)
++				   const char *key, void *buf, size_t buflen,
++				   int flags)
+ {
+ 	return nfs4_proc_get_acl(inode, buf, buflen);
+ }
+@@ -7308,7 +7309,8 @@ static int nfs4_xattr_set_nfs4_label(const struct xattr_handler *handler,
+ 
+ static int nfs4_xattr_get_nfs4_label(const struct xattr_handler *handler,
+ 				     struct dentry *unused, struct inode *inode,
+-				     const char *key, void *buf, size_t buflen)
++				     const char *key, void *buf, size_t buflen,
++				     int flags)
+ {
+ 	if (security_ismaclabel(key))
+ 		return nfs4_get_security_label(inode, buf, buflen);
+diff --git a/fs/ocfs2/xattr.c b/fs/ocfs2/xattr.c
+index d8507972ee13..85df32e0f851 100644
+--- a/fs/ocfs2/xattr.c
++++ b/fs/ocfs2/xattr.c
+@@ -7232,7 +7232,8 @@ int ocfs2_init_security_and_acl(struct inode *dir,
+  */
+ static int ocfs2_xattr_security_get(const struct xattr_handler *handler,
+ 				    struct dentry *unused, struct inode *inode,
+-				    const char *name, void *buffer, size_t size)
++				    const char *name, void *buffer, size_t size,
++				    int flags)
+ {
+ 	return ocfs2_xattr_get(inode, OCFS2_XATTR_INDEX_SECURITY,
+ 			       name, buffer, size);
+@@ -7304,7 +7305,8 @@ const struct xattr_handler ocfs2_xattr_security_handler = {
+  */
+ static int ocfs2_xattr_trusted_get(const struct xattr_handler *handler,
+ 				   struct dentry *unused, struct inode *inode,
+-				   const char *name, void *buffer, size_t size)
++				   const char *name, void *buffer, size_t size,
++				   int flags)
+ {
+ 	return ocfs2_xattr_get(inode, OCFS2_XATTR_INDEX_TRUSTED,
+ 			       name, buffer, size);
+@@ -7330,7 +7332,8 @@ const struct xattr_handler ocfs2_xattr_trusted_handler = {
+  */
+ static int ocfs2_xattr_user_get(const struct xattr_handler *handler,
+ 				struct dentry *unused, struct inode *inode,
+-				const char *name, void *buffer, size_t size)
++				const char *name, void *buffer, size_t size,
++				int flags)
+ {
+ 	struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
+ 
+diff --git a/fs/orangefs/xattr.c b/fs/orangefs/xattr.c
+index bdc285aea360..ef4180bff7bb 100644
+--- a/fs/orangefs/xattr.c
++++ b/fs/orangefs/xattr.c
+@@ -541,7 +541,8 @@ static int orangefs_xattr_get_default(const struct xattr_handler *handler,
+ 				      struct inode *inode,
+ 				      const char *name,
+ 				      void *buffer,
+-				      size_t size)
++				      size_t size,
++				      int flags)
+ {
+ 	return orangefs_inode_getxattr(inode, name, buffer, size);
+ 
+diff --git a/fs/overlayfs/super.c b/fs/overlayfs/super.c
+index afbcb116a7f1..57f5f948ae0a 100644
+--- a/fs/overlayfs/super.c
++++ b/fs/overlayfs/super.c
+@@ -855,7 +855,7 @@ static unsigned int ovl_split_lowerdirs(char *str)
+ static int __maybe_unused
+ ovl_posix_acl_xattr_get(const struct xattr_handler *handler,
+ 			struct dentry *dentry, struct inode *inode,
+-			const char *name, void *buffer, size_t size)
++			const char *name, void *buffer, size_t size, int flags)
+ {
+ 	return ovl_xattr_get(dentry, inode, handler->name, buffer, size);
+ }
+@@ -920,7 +920,8 @@ ovl_posix_acl_xattr_set(const struct xattr_handler *handler,
+ 
+ static int ovl_own_xattr_get(const struct xattr_handler *handler,
+ 			     struct dentry *dentry, struct inode *inode,
+-			     const char *name, void *buffer, size_t size)
++			     const char *name, void *buffer, size_t size,
++			     int flags)
+ {
+ 	return -EOPNOTSUPP;
+ }
+@@ -935,7 +936,8 @@ static int ovl_own_xattr_set(const struct xattr_handler *handler,
+ 
+ static int ovl_other_xattr_get(const struct xattr_handler *handler,
+ 			       struct dentry *dentry, struct inode *inode,
+-			       const char *name, void *buffer, size_t size)
++			       const char *name, void *buffer, size_t size,
++			       int flags)
+ {
+ 	return ovl_xattr_get(dentry, inode, name, buffer, size);
+ }
+diff --git a/fs/posix_acl.c b/fs/posix_acl.c
+index 84ad1c90d535..cd55621e570b 100644
+--- a/fs/posix_acl.c
++++ b/fs/posix_acl.c
+@@ -832,7 +832,7 @@ EXPORT_SYMBOL (posix_acl_to_xattr);
+ static int
+ posix_acl_xattr_get(const struct xattr_handler *handler,
+ 		    struct dentry *unused, struct inode *inode,
+-		    const char *name, void *value, size_t size)
++		    const char *name, void *value, size_t size, int flags)
+ {
+ 	struct posix_acl *acl;
+ 	int error;
+diff --git a/fs/reiserfs/xattr_security.c b/fs/reiserfs/xattr_security.c
+index 20be9a0e5870..eedfa07a4fd0 100644
+--- a/fs/reiserfs/xattr_security.c
++++ b/fs/reiserfs/xattr_security.c
+@@ -11,7 +11,8 @@
+ 
+ static int
+ security_get(const struct xattr_handler *handler, struct dentry *unused,
+-	     struct inode *inode, const char *name, void *buffer, size_t size)
++	     struct inode *inode, const char *name, void *buffer, size_t size,
++	     int flags)
+ {
+ 	if (IS_PRIVATE(inode))
+ 		return -EPERM;
+diff --git a/fs/reiserfs/xattr_trusted.c b/fs/reiserfs/xattr_trusted.c
+index 5ed48da3d02b..2d11d98605dd 100644
+--- a/fs/reiserfs/xattr_trusted.c
++++ b/fs/reiserfs/xattr_trusted.c
+@@ -10,7 +10,8 @@
+ 
+ static int
+ trusted_get(const struct xattr_handler *handler, struct dentry *unused,
+-	    struct inode *inode, const char *name, void *buffer, size_t size)
++	    struct inode *inode, const char *name, void *buffer, size_t size,
++	    int flags)
+ {
+ 	if (!capable(CAP_SYS_ADMIN) || IS_PRIVATE(inode))
+ 		return -EPERM;
+diff --git a/fs/reiserfs/xattr_user.c b/fs/reiserfs/xattr_user.c
+index a573ca45bacc..2a59d85c69c9 100644
+--- a/fs/reiserfs/xattr_user.c
++++ b/fs/reiserfs/xattr_user.c
+@@ -9,7 +9,8 @@
+ 
+ static int
+ user_get(const struct xattr_handler *handler, struct dentry *unused,
+-	 struct inode *inode, const char *name, void *buffer, size_t size)
++	 struct inode *inode, const char *name, void *buffer, size_t size,
++	 int flags)
+ {
+ 	if (!reiserfs_xattrs_user(inode->i_sb))
+ 		return -EOPNOTSUPP;
+diff --git a/fs/squashfs/xattr.c b/fs/squashfs/xattr.c
+index e1e3f3dd5a06..d8d58c990652 100644
+--- a/fs/squashfs/xattr.c
++++ b/fs/squashfs/xattr.c
+@@ -204,7 +204,7 @@ static int squashfs_xattr_handler_get(const struct xattr_handler *handler,
+ 				      struct dentry *unused,
+ 				      struct inode *inode,
+ 				      const char *name,
+-				      void *buffer, size_t size)
++				      void *buffer, size_t size, int flags)
+ {
+ 	return squashfs_xattr_get(inode, handler->flags, name,
+ 		buffer, size);
+diff --git a/fs/ubifs/xattr.c b/fs/ubifs/xattr.c
+index 9aefbb60074f..26e1a74f178e 100644
+--- a/fs/ubifs/xattr.c
++++ b/fs/ubifs/xattr.c
+@@ -669,7 +669,8 @@ int ubifs_init_security(struct inode *dentry, struct inode *inode,
+ 
+ static int xattr_get(const struct xattr_handler *handler,
+ 			   struct dentry *dentry, struct inode *inode,
+-			   const char *name, void *buffer, size_t size)
++			   const char *name, void *buffer, size_t size,
++			   int flags)
+ {
+ 	dbg_gen("xattr '%s', ino %lu ('%pd'), buf size %zd", name,
+ 		inode->i_ino, dentry, size);
+diff --git a/fs/xattr.c b/fs/xattr.c
+index 142fa44fa587..9520365195cf 100644
+--- a/fs/xattr.c
++++ b/fs/xattr.c
+@@ -281,7 +281,7 @@ vfs_getxattr_alloc(struct dentry *dentry, const char *name, char **xattr_value,
+ 		return PTR_ERR(handler);
+ 	if (!handler->get)
+ 		return -EOPNOTSUPP;
+-	error = handler->get(handler, dentry, inode, name, NULL, 0);
++	error = handler->get(handler, dentry, inode, name, NULL, 0, 0);
+ 	if (error < 0)
+ 		return error;
+ 
+@@ -292,32 +292,20 @@ vfs_getxattr_alloc(struct dentry *dentry, const char *name, char **xattr_value,
+ 		memset(value, 0, error + 1);
+ 	}
+ 
+-	error = handler->get(handler, dentry, inode, name, value, error);
++	error = handler->get(handler, dentry, inode, name, value, error, 0);
+ 	*xattr_value = value;
+ 	return error;
+ }
+ 
+ ssize_t
+ __vfs_getxattr(struct dentry *dentry, struct inode *inode, const char *name,
+-	       void *value, size_t size)
++	       void *value, size_t size, int flags)
+ {
+ 	const struct xattr_handler *handler;
+-
+-	handler = xattr_resolve_name(inode, &name);
+-	if (IS_ERR(handler))
+-		return PTR_ERR(handler);
+-	if (!handler->get)
+-		return -EOPNOTSUPP;
+-	return handler->get(handler, dentry, inode, name, value, size);
+-}
+-EXPORT_SYMBOL(__vfs_getxattr);
+-
+-ssize_t
+-vfs_getxattr(struct dentry *dentry, const char *name, void *value, size_t size)
+-{
+-	struct inode *inode = dentry->d_inode;
+ 	int error;
+ 
++	if (flags & XATTR_NOSECURITY)
++		goto nolsm;
+ 	error = xattr_permission(inode, name, MAY_READ);
+ 	if (error)
+ 		return error;
+@@ -339,7 +327,19 @@ vfs_getxattr(struct dentry *dentry, const char *name, void *value, size_t size)
+ 		return ret;
+ 	}
+ nolsm:
+-	return __vfs_getxattr(dentry, inode, name, value, size);
++	handler = xattr_resolve_name(inode, &name);
++	if (IS_ERR(handler))
++		return PTR_ERR(handler);
++	if (!handler->get)
++		return -EOPNOTSUPP;
++	return handler->get(handler, dentry, inode, name, value, size, flags);
++}
++EXPORT_SYMBOL(__vfs_getxattr);
++
++ssize_t
++vfs_getxattr(struct dentry *dentry, const char *name, void *value, size_t size)
++{
++	return __vfs_getxattr(dentry, dentry->d_inode, name, value, size, 0);
+ }
+ EXPORT_SYMBOL_GPL(vfs_getxattr);
+ 
+diff --git a/fs/xfs/xfs_xattr.c b/fs/xfs/xfs_xattr.c
+index cb895b1df5e4..9d2030e02a37 100644
+--- a/fs/xfs/xfs_xattr.c
++++ b/fs/xfs/xfs_xattr.c
+@@ -18,7 +18,8 @@
+ 
+ static int
+ xfs_xattr_get(const struct xattr_handler *handler, struct dentry *unused,
+-		struct inode *inode, const char *name, void *value, size_t size)
++		struct inode *inode, const char *name, void *value, size_t size,
++		int flags)
+ {
+ 	int xflags = handler->flags;
+ 	struct xfs_inode *ip = XFS_I(inode);
+diff --git a/include/linux/xattr.h b/include/linux/xattr.h
+index 6dad031be3c2..4df9dcdc48c5 100644
+--- a/include/linux/xattr.h
++++ b/include/linux/xattr.h
+@@ -30,10 +30,10 @@ struct xattr_handler {
+ 	const char *prefix;
+ 	int flags;      /* fs private flags */
+ 	bool (*list)(struct dentry *dentry);
+-	int (*get)(const struct xattr_handler *, struct dentry *dentry,
++	int (*get)(const struct xattr_handler *handler, struct dentry *dentry,
+ 		   struct inode *inode, const char *name, void *buffer,
+-		   size_t size);
+-	int (*set)(const struct xattr_handler *, struct dentry *dentry,
++		   size_t size, int flags);
++	int (*set)(const struct xattr_handler *handler, struct dentry *dentry,
+ 		   struct inode *inode, const char *name, const void *buffer,
+ 		   size_t size, int flags);
+ };
+@@ -46,7 +46,8 @@ struct xattr {
+ 	size_t value_len;
+ };
+ 
+-ssize_t __vfs_getxattr(struct dentry *, struct inode *, const char *, void *, size_t);
++ssize_t __vfs_getxattr(struct dentry *dentry, struct inode *inode,
++		       const char *name, void *buffer, size_t size, int flags);
+ ssize_t vfs_getxattr(struct dentry *, const char *, void *, size_t);
+ ssize_t vfs_listxattr(struct dentry *d, char *list, size_t size);
+ int __vfs_setxattr(struct dentry *, struct inode *, const char *, const void *, size_t, int);
+diff --git a/include/uapi/linux/xattr.h b/include/uapi/linux/xattr.h
+index c1395b5bd432..1eba02616274 100644
+--- a/include/uapi/linux/xattr.h
++++ b/include/uapi/linux/xattr.h
+@@ -17,8 +17,11 @@
+ #if __UAPI_DEF_XATTR
+ #define __USE_KERNEL_XATTR_DEFS
+ 
+-#define XATTR_CREATE	0x1	/* set value, fail if attr already exists */
+-#define XATTR_REPLACE	0x2	/* set value, fail if attr does not exist */
++#define XATTR_CREATE	 0x1	/* set value, fail if attr already exists */
++#define XATTR_REPLACE	 0x2	/* set value, fail if attr does not exist */
++#ifdef __KERNEL__ /* following is kernel internal, colocated for maintenance */
++#define XATTR_NOSECURITY 0x4	/* get value, do not involve security check */
++#endif
+ #endif
+ 
+ /* Namespaces */
+diff --git a/mm/shmem.c b/mm/shmem.c
+index 220be9fa2c41..641570ee1c10 100644
+--- a/mm/shmem.c
++++ b/mm/shmem.c
+@@ -3221,7 +3221,8 @@ static int shmem_initxattrs(struct inode *inode,
+ 
+ static int shmem_xattr_handler_get(const struct xattr_handler *handler,
+ 				   struct dentry *unused, struct inode *inode,
+-				   const char *name, void *buffer, size_t size)
++				   const char *name, void *buffer, size_t size,
++				   int flags)
+ {
+ 	struct shmem_inode_info *info = SHMEM_I(inode);
+ 
+diff --git a/net/socket.c b/net/socket.c
+index 6a9ab7a8b1d2..6b0fea92dd02 100644
+--- a/net/socket.c
++++ b/net/socket.c
+@@ -300,7 +300,8 @@ static const struct dentry_operations sockfs_dentry_operations = {
+ 
+ static int sockfs_xattr_get(const struct xattr_handler *handler,
+ 			    struct dentry *dentry, struct inode *inode,
+-			    const char *suffix, void *value, size_t size)
++			    const char *suffix, void *value, size_t size,
++			    int flags)
+ {
+ 	if (value) {
+ 		if (dentry->d_name.len + 1 > size)
+diff --git a/security/commoncap.c b/security/commoncap.c
+index f4ee0ae106b2..378a2f66a73d 100644
+--- a/security/commoncap.c
++++ b/security/commoncap.c
+@@ -297,7 +297,8 @@ int cap_inode_need_killpriv(struct dentry *dentry)
+ 	struct inode *inode = d_backing_inode(dentry);
+ 	int error;
+ 
+-	error = __vfs_getxattr(dentry, inode, XATTR_NAME_CAPS, NULL, 0);
++	error = __vfs_getxattr(dentry, inode, XATTR_NAME_CAPS, NULL, 0,
++			       XATTR_NOSECURITY);
+ 	return error > 0;
+ }
+ 
+@@ -586,7 +587,8 @@ int get_vfs_caps_from_disk(const struct dentry *dentry, struct cpu_vfs_cap_data
+ 
+ 	fs_ns = inode->i_sb->s_user_ns;
+ 	size = __vfs_getxattr((struct dentry *)dentry, inode,
+-			      XATTR_NAME_CAPS, &data, XATTR_CAPS_SZ);
++			      XATTR_NAME_CAPS, &data, XATTR_CAPS_SZ,
++			      XATTR_NOSECURITY);
+ 	if (size == -ENODATA || size == -EOPNOTSUPP)
+ 		/* no data, that's ok */
+ 		return -ENODATA;
+diff --git a/security/integrity/evm/evm_main.c b/security/integrity/evm/evm_main.c
+index f9a81b187fae..921c8f2afcaf 100644
+--- a/security/integrity/evm/evm_main.c
++++ b/security/integrity/evm/evm_main.c
+@@ -100,7 +100,8 @@ static int evm_find_protected_xattrs(struct dentry *dentry)
+ 		return -EOPNOTSUPP;
+ 
+ 	list_for_each_entry_rcu(xattr, &evm_config_xattrnames, list) {
+-		error = __vfs_getxattr(dentry, inode, xattr->name, NULL, 0);
++		error = __vfs_getxattr(dentry, inode, xattr->name, NULL, 0,
++				       XATTR_NOSECURITY);
+ 		if (error < 0) {
+ 			if (error == -ENODATA)
+ 				continue;
+diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
+index 9625b99e677f..60cd34d25878 100644
+--- a/security/selinux/hooks.c
++++ b/security/selinux/hooks.c
+@@ -554,7 +554,8 @@ static int sb_finish_set_opts(struct super_block *sb)
+ 			goto out;
+ 		}
+ 
+-		rc = __vfs_getxattr(root, root_inode, XATTR_NAME_SELINUX, NULL, 0);
++		rc = __vfs_getxattr(root, root_inode, XATTR_NAME_SELINUX, NULL,
++				    0, XATTR_NOSECURITY);
+ 		if (rc < 0 && rc != -ENODATA) {
+ 			if (rc == -EOPNOTSUPP)
+ 				pr_warn("SELinux: (dev %s, type "
+@@ -1380,12 +1381,14 @@ static int inode_doinit_use_xattr(struct inode *inode, struct dentry *dentry,
+ 		return -ENOMEM;
+ 
+ 	context[len] = '\0';
+-	rc = __vfs_getxattr(dentry, inode, XATTR_NAME_SELINUX, context, len);
++	rc = __vfs_getxattr(dentry, inode, XATTR_NAME_SELINUX, context, len,
++			    XATTR_NOSECURITY);
+ 	if (rc == -ERANGE) {
+ 		kfree(context);
+ 
+ 		/* Need a larger buffer.  Query for the right size. */
+-		rc = __vfs_getxattr(dentry, inode, XATTR_NAME_SELINUX, NULL, 0);
++		rc = __vfs_getxattr(dentry, inode, XATTR_NAME_SELINUX, NULL, 0,
++				    XATTR_NOSECURITY);
+ 		if (rc < 0)
+ 			return rc;
+ 
+@@ -1396,7 +1399,7 @@ static int inode_doinit_use_xattr(struct inode *inode, struct dentry *dentry,
+ 
+ 		context[len] = '\0';
+ 		rc = __vfs_getxattr(dentry, inode, XATTR_NAME_SELINUX,
+-				    context, len);
++				    context, len, XATTR_NOSECURITY);
+ 	}
+ 	if (rc < 0) {
+ 		kfree(context);
+diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c
+index abeb09c30633..73009d3d902a 100644
+--- a/security/smack/smack_lsm.c
++++ b/security/smack/smack_lsm.c
+@@ -292,7 +292,8 @@ static struct smack_known *smk_fetch(const char *name, struct inode *ip,
+ 	if (buffer == NULL)
+ 		return ERR_PTR(-ENOMEM);
+ 
+-	rc = __vfs_getxattr(dp, ip, name, buffer, SMK_LONGLABEL);
++	rc = __vfs_getxattr(dp, ip, name, buffer, SMK_LONGLABEL,
++			    XATTR_NOSECURITY);
+ 	if (rc < 0)
+ 		skp = ERR_PTR(rc);
+ 	else if (rc == 0)
+@@ -3440,7 +3441,7 @@ static void smack_d_instantiate(struct dentry *opt_dentry, struct inode *inode)
+ 			} else {
+ 				rc = __vfs_getxattr(dp, inode,
+ 					XATTR_NAME_SMACKTRANSMUTE, trattr,
+-					TRANS_TRUE_SIZE);
++					TRANS_TRUE_SIZE, XATTR_NOSECURITY);
+ 				if (rc >= 0 && strncmp(trattr, TRANS_TRUE,
+ 						       TRANS_TRUE_SIZE) != 0)
+ 					rc = -EINVAL;
diff --git a/android-mainline/FROMLIST-afs-xattr-use-scnprintf.patch b/android-mainline/FROMLIST-afs-xattr-use-scnprintf.patch
new file mode 100644
index 0000000..b17ff70
--- /dev/null
+++ b/android-mainline/FROMLIST-afs-xattr-use-scnprintf.patch
@@ -0,0 +1,65 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Mark Salyzyn <salyzyn@android.com>
+Date: Tue, 5 Nov 2019 07:43:49 -0800
+Subject: FROMLIST: afs: xattr: use scnprintf
+
+sprintf and snprintf are fragile in future maintenance, switch to
+using scnprintf to ensure no accidental Use After Free conditions
+are introduced.
+
+Signed-off-by: Mark Salyzyn <salyzyn@android.com>
+Cc: linux-kernel@vger.kernel.org
+Cc: linux-fsdevel@vger.kernel.org
+Cc: David Howells <dhowells@redhat.com>
+Cc: linux-afs@lists.infradead.org
+Cc: Jan Kara <jack@suse.cz>
+
+(cherry picked from https://lore.kernel.org/lkml/20191105154850.187723-1-salyzyn@android.com/)
+Signed-off-by: Mark Salyzyn <salyzyn@google.com>
+Bug: 133515582
+Bug: 136124883
+Bug: 129319403
+Change-Id: I6fca97f90f60472c1a7737898b4629b20c04c495
+---
+ fs/afs/xattr.c | 16 +++++++++-------
+ 1 file changed, 9 insertions(+), 7 deletions(-)
+
+diff --git a/fs/afs/xattr.c b/fs/afs/xattr.c
+index 5552d034090a..7af41fd5f3ee 100644
+--- a/fs/afs/xattr.c
++++ b/fs/afs/xattr.c
+@@ -228,11 +228,11 @@ static int afs_xattr_get_yfs(const struct xattr_handler *handler,
+ 		break;
+ 	case 1:
+ 		data = buf;
+-		dsize = snprintf(buf, sizeof(buf), "%u", yacl->inherit_flag);
++		dsize = scnprintf(buf, sizeof(buf), "%u", yacl->inherit_flag);
+ 		break;
+ 	case 2:
+ 		data = buf;
+-		dsize = snprintf(buf, sizeof(buf), "%u", yacl->num_cleaned);
++		dsize = scnprintf(buf, sizeof(buf), "%u", yacl->num_cleaned);
+ 		break;
+ 	case 3:
+ 		data = yacl->vol_acl->data;
+@@ -370,13 +370,15 @@ static int afs_xattr_get_fid(const struct xattr_handler *handler,
+ 	/* The volume ID is 64-bit, the vnode ID is 96-bit and the
+ 	 * uniquifier is 32-bit.
+ 	 */
+-	len = sprintf(text, "%llx:", vnode->fid.vid);
++	len = scnprintf(text, sizeof(text), "%llx:", vnode->fid.vid);
+ 	if (vnode->fid.vnode_hi)
+-		len += sprintf(text + len, "%x%016llx",
+-			       vnode->fid.vnode_hi, vnode->fid.vnode);
++		len += scnprintf(text + len, sizeof(text) - len, "%x%016llx",
++				vnode->fid.vnode_hi, vnode->fid.vnode);
+ 	else
+-		len += sprintf(text + len, "%llx", vnode->fid.vnode);
+-	len += sprintf(text + len, ":%x", vnode->fid.unique);
++		len += scnprintf(text + len, sizeof(text) - len, "%llx",
++				 vnode->fid.vnode);
++	len += scnprintf(text + len, sizeof(text) - len, ":%x",
++			 vnode->fid.unique);
+ 
+ 	if (size == 0)
+ 		return len;
diff --git a/android-mainline/FROMLIST-overlayfs-handle-XATTR_NOSECURITY-flag-for-get-xattr-method.patch b/android-mainline/FROMLIST-overlayfs-handle-XATTR_NOSECURITY-flag-for-get-xattr-method.patch
new file mode 100644
index 0000000..36a4b41
--- /dev/null
+++ b/android-mainline/FROMLIST-overlayfs-handle-XATTR_NOSECURITY-flag-for-get-xattr-method.patch
@@ -0,0 +1,115 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Mark Salyzyn <salyzyn@android.com>
+Date: Mon, 15 Jul 2019 15:46:45 -0700
+Subject: FROMLIST: overlayfs: handle XATTR_NOSECURITY flag for get xattr
+ method
+
+Because of the overlayfs getxattr recursion, the incoming inode fails
+to update the selinux sid resulting in avc denials being reported
+against a target context of u:object_r:unlabeled:s0.
+
+Solution is to respond to the XATTR_NOSECURITY flag in get xattr
+method that calls the __vfs_getxattr handler instead so that the
+context can be read in, rather than being denied with an -EACCES
+when vfs_getxattr handler is called.
+
+For the use case where access is to be blocked by the security layer.
+
+The path then would be security(dentry) ->
+__vfs_getxattr({dentry...XATTR_NOSECURITY}) ->
+handler->get({dentry...XATTR_NOSECURITY}) ->
+__vfs_getxattr({realdentry...XATTR_NOSECURITY}) ->
+lower_handler->get({realdentry...XATTR_NOSECURITY}) which
+would report back through the chain data and success as expected,
+the logging security layer at the top would have the data to
+determine the access permissions and report back to the logs and
+the caller that the target context was blocked.
+
+For selinux this would solve the cosmetic issue of the selinux log
+and allow audit2allow to correctly report the rule needed to address
+the access problem.
+
+Signed-off-by: Mark Salyzyn <salyzyn@android.com>
+Cc: Miklos Szeredi <miklos@szeredi.hu>
+Cc: Jonathan Corbet <corbet@lwn.net>
+Cc: Vivek Goyal <vgoyal@redhat.com>
+Cc: Eric W. Biederman <ebiederm@xmission.com>
+Cc: Amir Goldstein <amir73il@gmail.com>
+Cc: Randy Dunlap <rdunlap@infradead.org>
+Cc: Stephen Smalley <sds@tycho.nsa.gov>
+Cc: linux-unionfs@vger.kernel.org
+Cc: linux-doc@vger.kernel.org
+Cc: linux-kernel@vger.kernel.org
+Cc: kernel-team@android.com
+Cc: linux-security-module@vger.kernel.org
+
+(cherry pick from https://lore.kernel.org/lkml/20191104215253.141818-3-salyzyn@android.com/)
+Signed-off-by: Mark Salyzyn <salyzyn@google.com>
+Bug: 133515582
+Bug: 136124883
+Bug: 129319403
+Change-Id: Ia39543c5ce617976f14d790fb88e471d575ffd65
+---
+ fs/overlayfs/inode.c     | 5 +++--
+ fs/overlayfs/overlayfs.h | 2 +-
+ fs/overlayfs/super.c     | 4 ++--
+ 3 files changed, 6 insertions(+), 5 deletions(-)
+
+diff --git a/fs/overlayfs/inode.c b/fs/overlayfs/inode.c
+index bc14781886bf..c057e51057f7 100644
+--- a/fs/overlayfs/inode.c
++++ b/fs/overlayfs/inode.c
+@@ -363,7 +363,7 @@ int ovl_xattr_set(struct dentry *dentry, struct inode *inode, const char *name,
+ }
+ 
+ int ovl_xattr_get(struct dentry *dentry, struct inode *inode, const char *name,
+-		  void *value, size_t size)
++		  void *value, size_t size, int flags)
+ {
+ 	ssize_t res;
+ 	const struct cred *old_cred;
+@@ -371,7 +371,8 @@ int ovl_xattr_get(struct dentry *dentry, struct inode *inode, const char *name,
+ 		ovl_i_dentry_upper(inode) ?: ovl_dentry_lower(dentry);
+ 
+ 	old_cred = ovl_override_creds(dentry->d_sb);
+-	res = vfs_getxattr(realdentry, name, value, size);
++	res = __vfs_getxattr(realdentry, d_inode(realdentry), name,
++			     value, size, flags);
+ 	revert_creds(old_cred);
+ 	return res;
+ }
+diff --git a/fs/overlayfs/overlayfs.h b/fs/overlayfs/overlayfs.h
+index 6934bcf030f0..ab3d031c422b 100644
+--- a/fs/overlayfs/overlayfs.h
++++ b/fs/overlayfs/overlayfs.h
+@@ -356,7 +356,7 @@ int ovl_permission(struct inode *inode, int mask);
+ int ovl_xattr_set(struct dentry *dentry, struct inode *inode, const char *name,
+ 		  const void *value, size_t size, int flags);
+ int ovl_xattr_get(struct dentry *dentry, struct inode *inode, const char *name,
+-		  void *value, size_t size);
++		  void *value, size_t size, int flags);
+ ssize_t ovl_listxattr(struct dentry *dentry, char *list, size_t size);
+ struct posix_acl *ovl_get_acl(struct inode *inode, int type);
+ int ovl_update_time(struct inode *inode, struct timespec64 *ts, int flags);
+diff --git a/fs/overlayfs/super.c b/fs/overlayfs/super.c
+index 57f5f948ae0a..c91e7b604631 100644
+--- a/fs/overlayfs/super.c
++++ b/fs/overlayfs/super.c
+@@ -857,7 +857,7 @@ ovl_posix_acl_xattr_get(const struct xattr_handler *handler,
+ 			struct dentry *dentry, struct inode *inode,
+ 			const char *name, void *buffer, size_t size, int flags)
+ {
+-	return ovl_xattr_get(dentry, inode, handler->name, buffer, size);
++	return ovl_xattr_get(dentry, inode, handler->name, buffer, size, flags);
+ }
+ 
+ static int __maybe_unused
+@@ -939,7 +939,7 @@ static int ovl_other_xattr_get(const struct xattr_handler *handler,
+ 			       const char *name, void *buffer, size_t size,
+ 			       int flags)
+ {
+-	return ovl_xattr_get(dentry, inode, name, buffer, size);
++	return ovl_xattr_get(dentry, inode, name, buffer, size, flags);
+ }
+ 
+ static int ovl_other_xattr_set(const struct xattr_handler *handler,
diff --git a/android-mainline/FROMLIST-overlayfs-internal-getxattr-operations-without-sepolicy-checking.patch b/android-mainline/FROMLIST-overlayfs-internal-getxattr-operations-without-sepolicy-checking.patch
new file mode 100644
index 0000000..4bf2ed8
--- /dev/null
+++ b/android-mainline/FROMLIST-overlayfs-internal-getxattr-operations-without-sepolicy-checking.patch
@@ -0,0 +1,192 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Mark Salyzyn <salyzyn@android.com>
+Date: Tue, 23 Jul 2019 13:53:48 -0700
+Subject: FROMLIST: overlayfs: internal getxattr operations without sepolicy
+ checking
+
+Check impure, opaque, origin & meta xattr with no sepolicy audit
+(using __vfs_getxattr) since these operations are internal to
+overlayfs operations and do not disclose any data.  This became
+an issue for credential override off since sys_admin would have
+been required by the caller; whereas would have been inherently
+present for the creator since it performed the mount.
+
+This is a change in operations since we do not check in the new
+ovl_do_vfs_getxattr function if the credential override is off or
+not.  Reasoning is that the sepolicy check is unnecessary overhead,
+especially since the check can be expensive.
+
+Because for override credentials off, this affects _everyone_ that
+underneath performs private xattr calls without the appropriate
+sepolicy permissions and sys_admin capability.  Providing blanket
+support for sys_admin would be bad for all possible callers.
+
+For the override credentials on, this will affect only the mounter,
+should it lack sepolicy permissions. Not considered a security
+problem since mounting by definition has sys_admin capabilities,
+but sepolicy contexts would still need to be crafted.
+
+It should be noted that there is precedence, __vfs_getxattr is used
+in other filesystems for their own internal trusted xattr management.
+
+Signed-off-by: Mark Salyzyn <salyzyn@android.com>
+Cc: Miklos Szeredi <miklos@szeredi.hu>
+Cc: Jonathan Corbet <corbet@lwn.net>
+Cc: Vivek Goyal <vgoyal@redhat.com>
+Cc: Eric W. Biederman <ebiederm@xmission.com>
+Cc: Amir Goldstein <amir73il@gmail.com>
+Cc: Randy Dunlap <rdunlap@infradead.org>
+Cc: Stephen Smalley <sds@tycho.nsa.gov>
+Cc: linux-unionfs@vger.kernel.org
+Cc: linux-doc@vger.kernel.org
+Cc: linux-kernel@vger.kernel.org
+Cc: kernel-team@android.com
+Cc: linux-security-module@vger.kernel.org
+
+(cherry picked from https://lore.kernel.org/lkml/20191104215253.141818-4-salyzyn@android.com/)
+Signed-off-by: Mark Salyzyn <salyzyn@google.com>
+Bug: 133515582
+Bug: 136124883
+Bug: 129319403
+Change-Id: I34d99cc46e9e87a79efc8d05f85980bbc137f7eb
+---
+ fs/overlayfs/namei.c     | 12 +++++++-----
+ fs/overlayfs/overlayfs.h |  8 ++++++++
+ fs/overlayfs/util.c      | 18 +++++++++---------
+ 3 files changed, 24 insertions(+), 14 deletions(-)
+
+diff --git a/fs/overlayfs/namei.c b/fs/overlayfs/namei.c
+index e9717c2f7d45..f5aba0a0767b 100644
+--- a/fs/overlayfs/namei.c
++++ b/fs/overlayfs/namei.c
+@@ -106,10 +106,11 @@ int ovl_check_fh_len(struct ovl_fh *fh, int fh_len)
+ 
+ static struct ovl_fh *ovl_get_fh(struct dentry *dentry, const char *name)
+ {
+-	int res, err;
++	ssize_t res;
++	int err;
+ 	struct ovl_fh *fh = NULL;
+ 
+-	res = vfs_getxattr(dentry, name, NULL, 0);
++	res = ovl_do_vfs_getxattr(dentry, name, NULL, 0);
+ 	if (res < 0) {
+ 		if (res == -ENODATA || res == -EOPNOTSUPP)
+ 			return NULL;
+@@ -123,7 +124,7 @@ static struct ovl_fh *ovl_get_fh(struct dentry *dentry, const char *name)
+ 	if (!fh)
+ 		return ERR_PTR(-ENOMEM);
+ 
+-	res = vfs_getxattr(dentry, name, fh, res);
++	res = ovl_do_vfs_getxattr(dentry, name, fh, res);
+ 	if (res < 0)
+ 		goto fail;
+ 
+@@ -141,10 +142,11 @@ static struct ovl_fh *ovl_get_fh(struct dentry *dentry, const char *name)
+ 	return NULL;
+ 
+ fail:
+-	pr_warn_ratelimited("overlayfs: failed to get origin (%i)\n", res);
++	pr_warn_ratelimited("overlayfs: failed to get origin (%zi)\n", res);
+ 	goto out;
+ invalid:
+-	pr_warn_ratelimited("overlayfs: invalid origin (%*phN)\n", res, fh);
++	pr_warn_ratelimited("overlayfs: invalid origin (%*phN)\n",
++			    (int)res, fh);
+ 	goto out;
+ }
+ 
+diff --git a/fs/overlayfs/overlayfs.h b/fs/overlayfs/overlayfs.h
+index ab3d031c422b..55b872c28bf9 100644
+--- a/fs/overlayfs/overlayfs.h
++++ b/fs/overlayfs/overlayfs.h
+@@ -200,6 +200,14 @@ static inline bool ovl_open_flags_need_copy_up(int flags)
+ 	return ((OPEN_FMODE(flags) & FMODE_WRITE) || (flags & O_TRUNC));
+ }
+ 
++static inline ssize_t ovl_do_vfs_getxattr(struct dentry *dentry,
++					  const char *name, void *buf,
++					  size_t size)
++{
++	return __vfs_getxattr(dentry, d_inode(dentry), name, buf, size,
++			      XATTR_NOSECURITY);
++}
++
+ /* util.c */
+ int ovl_want_write(struct dentry *dentry);
+ void ovl_drop_write(struct dentry *dentry);
+diff --git a/fs/overlayfs/util.c b/fs/overlayfs/util.c
+index f5678a3f8350..2050c5084a82 100644
+--- a/fs/overlayfs/util.c
++++ b/fs/overlayfs/util.c
+@@ -537,9 +537,9 @@ void ovl_copy_up_end(struct dentry *dentry)
+ 
+ bool ovl_check_origin_xattr(struct dentry *dentry)
+ {
+-	int res;
++	ssize_t res;
+ 
+-	res = vfs_getxattr(dentry, OVL_XATTR_ORIGIN, NULL, 0);
++	res = ovl_do_vfs_getxattr(dentry, OVL_XATTR_ORIGIN, NULL, 0);
+ 
+ 	/* Zero size value means "copied up but origin unknown" */
+ 	if (res >= 0)
+@@ -550,13 +550,13 @@ bool ovl_check_origin_xattr(struct dentry *dentry)
+ 
+ bool ovl_check_dir_xattr(struct dentry *dentry, const char *name)
+ {
+-	int res;
++	ssize_t res;
+ 	char val;
+ 
+ 	if (!d_is_dir(dentry))
+ 		return false;
+ 
+-	res = vfs_getxattr(dentry, name, &val, 1);
++	res = ovl_do_vfs_getxattr(dentry, name, &val, 1);
+ 	if (res == 1 && val == 'y')
+ 		return true;
+ 
+@@ -837,13 +837,13 @@ int ovl_lock_rename_workdir(struct dentry *workdir, struct dentry *upperdir)
+ /* err < 0, 0 if no metacopy xattr, 1 if metacopy xattr found */
+ int ovl_check_metacopy_xattr(struct dentry *dentry)
+ {
+-	int res;
++	ssize_t res;
+ 
+ 	/* Only regular files can have metacopy xattr */
+ 	if (!S_ISREG(d_inode(dentry)->i_mode))
+ 		return 0;
+ 
+-	res = vfs_getxattr(dentry, OVL_XATTR_METACOPY, NULL, 0);
++	res = ovl_do_vfs_getxattr(dentry, OVL_XATTR_METACOPY, NULL, 0);
+ 	if (res < 0) {
+ 		if (res == -ENODATA || res == -EOPNOTSUPP)
+ 			return 0;
+@@ -852,7 +852,7 @@ int ovl_check_metacopy_xattr(struct dentry *dentry)
+ 
+ 	return 1;
+ out:
+-	pr_warn_ratelimited("overlayfs: failed to get metacopy (%i)\n", res);
++	pr_warn_ratelimited("overlayfs: failed to get metacopy (%zi)\n", res);
+ 	return res;
+ }
+ 
+@@ -878,7 +878,7 @@ ssize_t ovl_getxattr(struct dentry *dentry, char *name, char **value,
+ 	ssize_t res;
+ 	char *buf = NULL;
+ 
+-	res = vfs_getxattr(dentry, name, NULL, 0);
++	res = ovl_do_vfs_getxattr(dentry, name, NULL, 0);
+ 	if (res < 0) {
+ 		if (res == -ENODATA || res == -EOPNOTSUPP)
+ 			return -ENODATA;
+@@ -890,7 +890,7 @@ ssize_t ovl_getxattr(struct dentry *dentry, char *name, char **value,
+ 		if (!buf)
+ 			return -ENOMEM;
+ 
+-		res = vfs_getxattr(dentry, name, buf, res);
++		res = ovl_do_vfs_getxattr(dentry, name, buf, res);
+ 		if (res < 0)
+ 			goto fail;
+ 	}
diff --git a/android-mainline/FROMLIST-overlayfs-override_creds-off-option-bypass-creator_cred.patch b/android-mainline/FROMLIST-overlayfs-override_creds-off-option-bypass-creator_cred.patch
new file mode 100644
index 0000000..8c0fe2f
--- /dev/null
+++ b/android-mainline/FROMLIST-overlayfs-override_creds-off-option-bypass-creator_cred.patch
@@ -0,0 +1,557 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Mark Salyzyn <salyzyn@android.com>
+Date: Thu, 14 Jun 2018 11:15:22 -0700
+Subject: FROMLIST: overlayfs: override_creds=off option bypass creator_cred
+
+By default, all access to the upper, lower and work directories is the
+recorded mounter's MAC and DAC credentials.  The incoming accesses are
+checked against the caller's credentials.
+
+If the principles of least privilege are applied, the mounter's
+credentials might not overlap the credentials of the caller's when
+accessing the overlayfs filesystem.  For example, a file that a lower
+DAC privileged caller can execute, is MAC denied to the generally
+higher DAC privileged mounter, to prevent an attack vector.
+
+We add the option to turn off override_creds in the mount options; all
+subsequent operations after mount on the filesystem will be only the
+caller's credentials.  The module boolean parameter and mount option
+override_creds is also added as a presence check for this "feature",
+existence of /sys/module/overlay/parameters/override_creds.
+
+It was not always this way.  Circa 4.6 there was no recorded mounter's
+credentials, instead privileged access to upper or work directories
+were temporarily increased to perform the operations.  The MAC
+(selinux) policies were caller's in all cases.  override_creds=off
+partially returns us to this older access model minus the insecure
+temporary credential increases.  This is to permit use in a system
+with non-overlapping security models for each executable including
+the agent that mounts the overlayfs filesystem.  In Android
+this is the case since init, which performs the mount operations,
+has a minimal MAC set of privileges to reduce any attack surface,
+and services that use the content have a different set of MAC
+privileges (eg: read, for vendor labelled configuration, execute for
+vendor libraries and modules).  The caveats are not a problem in
+the Android usage model, however they should be fixed for
+completeness and for general use in time.
+
+Signed-off-by: Mark Salyzyn <salyzyn@android.com>
+Cc: Miklos Szeredi <miklos@szeredi.hu>
+Cc: Jonathan Corbet <corbet@lwn.net>
+Cc: Vivek Goyal <vgoyal@redhat.com>
+Cc: Eric W. Biederman <ebiederm@xmission.com>
+Cc: Amir Goldstein <amir73il@gmail.com>
+Cc: Randy Dunlap <rdunlap@infradead.org>
+Cc: Stephen Smalley <sds@tycho.nsa.gov>
+Cc: linux-unionfs@vger.kernel.org
+Cc: linux-doc@vger.kernel.org
+Cc: linux-kernel@vger.kernel.org
+Cc: kernel-team@android.com
+
+(cherry picked from https://lore.kernel.org/lkml/20191104215253.141818-5-salyzyn@android.com/)
+Signed-off-by: Mark Salyzyn <salyzyn@google.com>
+Bug: 133515582
+Bug: 136124883
+Bug: 129319403
+Change-Id: I6a82338fcb8b30b8e6f5d4c26b473730bdfd4488
+---
+ Documentation/filesystems/overlayfs.txt | 23 +++++++++++++++++++++++
+ fs/overlayfs/copy_up.c                  |  2 +-
+ fs/overlayfs/dir.c                      | 17 ++++++++++-------
+ fs/overlayfs/file.c                     | 20 ++++++++++----------
+ fs/overlayfs/inode.c                    | 18 +++++++++---------
+ fs/overlayfs/namei.c                    |  6 +++---
+ fs/overlayfs/overlayfs.h                |  1 +
+ fs/overlayfs/ovl_entry.h                |  1 +
+ fs/overlayfs/readdir.c                  |  4 ++--
+ fs/overlayfs/super.c                    | 22 +++++++++++++++++++++-
+ fs/overlayfs/util.c                     | 12 ++++++++++--
+ 11 files changed, 91 insertions(+), 35 deletions(-)
+
+diff --git a/Documentation/filesystems/overlayfs.txt b/Documentation/filesystems/overlayfs.txt
+index 845d689e0fd7..c7ab389571e5 100644
+--- a/Documentation/filesystems/overlayfs.txt
++++ b/Documentation/filesystems/overlayfs.txt
+@@ -102,6 +102,29 @@ Only the lists of names from directories are merged.  Other content
+ such as metadata and extended attributes are reported for the upper
+ directory only.  These attributes of the lower directory are hidden.
+ 
++credentials
++-----------
++
++By default, all access to the upper, lower and work directories is the
++recorded mounter's MAC and DAC credentials.  The incoming accesses are
++checked against the caller's credentials.
++
++In the case where caller MAC or DAC credentials do not overlap, a
++use case available in older versions of the driver, the
++override_creds mount flag can be turned off and help when the use
++pattern has caller with legitimate credentials where the mounter
++does not.  Several unintended side effects will occur though.  The
++caller without certain key capabilities or lower privilege will not
++always be able to delete files or directories, create nodes, or
++search some restricted directories.  The ability to search and read
++a directory entry is spotty as a result of the cache mechanism not
++retesting the credentials because of the assumption, a privileged
++caller can fill cache, then a lower privilege can read the directory
++cache.  The uneven security model where cache, upperdir and workdir
++are opened at privilege, but accessed without creating a form of
++privilege escalation, should only be used with strict understanding
++of the side effects and of the security policies.
++
+ whiteouts and opaque directories
+ --------------------------------
+ 
+diff --git a/fs/overlayfs/copy_up.c b/fs/overlayfs/copy_up.c
+index b801c6353100..1c1b9415e533 100644
+--- a/fs/overlayfs/copy_up.c
++++ b/fs/overlayfs/copy_up.c
+@@ -886,7 +886,7 @@ int ovl_copy_up_flags(struct dentry *dentry, int flags)
+ 		dput(parent);
+ 		dput(next);
+ 	}
+-	revert_creds(old_cred);
++	ovl_revert_creds(dentry->d_sb, old_cred);
+ 
+ 	return err;
+ }
+diff --git a/fs/overlayfs/dir.c b/fs/overlayfs/dir.c
+index 702aa63f6774..f4e6e6b6629a 100644
+--- a/fs/overlayfs/dir.c
++++ b/fs/overlayfs/dir.c
+@@ -536,7 +536,7 @@ static int ovl_create_or_link(struct dentry *dentry, struct inode *inode,
+ 			      struct ovl_cattr *attr, bool origin)
+ {
+ 	int err;
+-	const struct cred *old_cred;
++	const struct cred *old_cred, *hold_cred = NULL;
+ 	struct cred *override_cred;
+ 	struct dentry *parent = dentry->d_parent;
+ 
+@@ -563,14 +563,15 @@ static int ovl_create_or_link(struct dentry *dentry, struct inode *inode,
+ 		override_cred->fsgid = inode->i_gid;
+ 		if (!attr->hardlink) {
+ 			err = security_dentry_create_files_as(dentry,
+-					attr->mode, &dentry->d_name, old_cred,
++					attr->mode, &dentry->d_name,
++					old_cred ? old_cred : current_cred(),
+ 					override_cred);
+ 			if (err) {
+ 				put_cred(override_cred);
+ 				goto out_revert_creds;
+ 			}
+ 		}
+-		put_cred(override_creds(override_cred));
++		hold_cred = override_creds(override_cred);
+ 		put_cred(override_cred);
+ 
+ 		if (!ovl_dentry_is_whiteout(dentry))
+@@ -579,7 +580,9 @@ static int ovl_create_or_link(struct dentry *dentry, struct inode *inode,
+ 			err = ovl_create_over_whiteout(dentry, inode, attr);
+ 	}
+ out_revert_creds:
+-	revert_creds(old_cred);
++	ovl_revert_creds(dentry->d_sb, old_cred ?: hold_cred);
++	if (old_cred && hold_cred)
++		put_cred(hold_cred);
+ 	return err;
+ }
+ 
+@@ -655,7 +658,7 @@ static int ovl_set_link_redirect(struct dentry *dentry)
+ 
+ 	old_cred = ovl_override_creds(dentry->d_sb);
+ 	err = ovl_set_redirect(dentry, false);
+-	revert_creds(old_cred);
++	ovl_revert_creds(dentry->d_sb, old_cred);
+ 
+ 	return err;
+ }
+@@ -851,7 +854,7 @@ static int ovl_do_remove(struct dentry *dentry, bool is_dir)
+ 		err = ovl_remove_upper(dentry, is_dir, &list);
+ 	else
+ 		err = ovl_remove_and_whiteout(dentry, &list);
+-	revert_creds(old_cred);
++	ovl_revert_creds(dentry->d_sb, old_cred);
+ 	if (!err) {
+ 		if (is_dir)
+ 			clear_nlink(dentry->d_inode);
+@@ -1221,7 +1224,7 @@ static int ovl_rename(struct inode *olddir, struct dentry *old,
+ out_unlock:
+ 	unlock_rename(new_upperdir, old_upperdir);
+ out_revert_creds:
+-	revert_creds(old_cred);
++	ovl_revert_creds(old->d_sb, old_cred);
+ 	if (update_nlink)
+ 		ovl_nlink_end(new);
+ out_drop_write:
+diff --git a/fs/overlayfs/file.c b/fs/overlayfs/file.c
+index e235a635d9ec..d94d6ec785a7 100644
+--- a/fs/overlayfs/file.c
++++ b/fs/overlayfs/file.c
+@@ -32,7 +32,7 @@ static struct file *ovl_open_realfile(const struct file *file,
+ 	old_cred = ovl_override_creds(inode->i_sb);
+ 	realfile = open_with_fake_path(&file->f_path, flags, realinode,
+ 				       current_cred());
+-	revert_creds(old_cred);
++	ovl_revert_creds(inode->i_sb, old_cred);
+ 
+ 	pr_debug("open(%p[%pD2/%c], 0%o) -> (%p, 0%o)\n",
+ 		 file, file, ovl_whatisit(inode, realinode), file->f_flags,
+@@ -176,7 +176,7 @@ static loff_t ovl_llseek(struct file *file, loff_t offset, int whence)
+ 
+ 	old_cred = ovl_override_creds(inode->i_sb);
+ 	ret = vfs_llseek(real.file, offset, whence);
+-	revert_creds(old_cred);
++	ovl_revert_creds(inode->i_sb, old_cred);
+ 
+ 	file->f_pos = real.file->f_pos;
+ 	inode_unlock(inode);
+@@ -242,7 +242,7 @@ static ssize_t ovl_read_iter(struct kiocb *iocb, struct iov_iter *iter)
+ 	old_cred = ovl_override_creds(file_inode(file)->i_sb);
+ 	ret = vfs_iter_read(real.file, iter, &iocb->ki_pos,
+ 			    ovl_iocb_to_rwf(iocb));
+-	revert_creds(old_cred);
++	ovl_revert_creds(file_inode(file)->i_sb, old_cred);
+ 
+ 	ovl_file_accessed(file);
+ 
+@@ -278,7 +278,7 @@ static ssize_t ovl_write_iter(struct kiocb *iocb, struct iov_iter *iter)
+ 	ret = vfs_iter_write(real.file, iter, &iocb->ki_pos,
+ 			     ovl_iocb_to_rwf(iocb));
+ 	file_end_write(real.file);
+-	revert_creds(old_cred);
++	ovl_revert_creds(file_inode(file)->i_sb, old_cred);
+ 
+ 	/* Update size */
+ 	ovl_copyattr(ovl_inode_real(inode), inode);
+@@ -305,7 +305,7 @@ static int ovl_fsync(struct file *file, loff_t start, loff_t end, int datasync)
+ 	if (file_inode(real.file) == ovl_inode_upper(file_inode(file))) {
+ 		old_cred = ovl_override_creds(file_inode(file)->i_sb);
+ 		ret = vfs_fsync_range(real.file, start, end, datasync);
+-		revert_creds(old_cred);
++		ovl_revert_creds(file_inode(file)->i_sb, old_cred);
+ 	}
+ 
+ 	fdput(real);
+@@ -329,7 +329,7 @@ static int ovl_mmap(struct file *file, struct vm_area_struct *vma)
+ 
+ 	old_cred = ovl_override_creds(file_inode(file)->i_sb);
+ 	ret = call_mmap(vma->vm_file, vma);
+-	revert_creds(old_cred);
++	ovl_revert_creds(file_inode(file)->i_sb, old_cred);
+ 
+ 	if (ret) {
+ 		/* Drop reference count from new vm_file value */
+@@ -357,7 +357,7 @@ static long ovl_fallocate(struct file *file, int mode, loff_t offset, loff_t len
+ 
+ 	old_cred = ovl_override_creds(file_inode(file)->i_sb);
+ 	ret = vfs_fallocate(real.file, mode, offset, len);
+-	revert_creds(old_cred);
++	ovl_revert_creds(file_inode(file)->i_sb, old_cred);
+ 
+ 	/* Update size */
+ 	ovl_copyattr(ovl_inode_real(inode), inode);
+@@ -379,7 +379,7 @@ static int ovl_fadvise(struct file *file, loff_t offset, loff_t len, int advice)
+ 
+ 	old_cred = ovl_override_creds(file_inode(file)->i_sb);
+ 	ret = vfs_fadvise(real.file, offset, len, advice);
+-	revert_creds(old_cred);
++	ovl_revert_creds(file_inode(file)->i_sb, old_cred);
+ 
+ 	fdput(real);
+ 
+@@ -399,7 +399,7 @@ static long ovl_real_ioctl(struct file *file, unsigned int cmd,
+ 
+ 	old_cred = ovl_override_creds(file_inode(file)->i_sb);
+ 	ret = vfs_ioctl(real.file, cmd, arg);
+-	revert_creds(old_cred);
++	ovl_revert_creds(file_inode(file)->i_sb, old_cred);
+ 
+ 	fdput(real);
+ 
+@@ -589,7 +589,7 @@ static loff_t ovl_copyfile(struct file *file_in, loff_t pos_in,
+ 						flags);
+ 		break;
+ 	}
+-	revert_creds(old_cred);
++	ovl_revert_creds(file_inode(file_out)->i_sb, old_cred);
+ 
+ 	/* Update size */
+ 	ovl_copyattr(ovl_inode_real(inode_out), inode_out);
+diff --git a/fs/overlayfs/inode.c b/fs/overlayfs/inode.c
+index c057e51057f7..3f2474fe8574 100644
+--- a/fs/overlayfs/inode.c
++++ b/fs/overlayfs/inode.c
+@@ -61,7 +61,7 @@ int ovl_setattr(struct dentry *dentry, struct iattr *attr)
+ 		inode_lock(upperdentry->d_inode);
+ 		old_cred = ovl_override_creds(dentry->d_sb);
+ 		err = notify_change(upperdentry, attr, NULL);
+-		revert_creds(old_cred);
++		ovl_revert_creds(dentry->d_sb, old_cred);
+ 		if (!err)
+ 			ovl_copyattr(upperdentry->d_inode, dentry->d_inode);
+ 		inode_unlock(upperdentry->d_inode);
+@@ -257,7 +257,7 @@ int ovl_getattr(const struct path *path, struct kstat *stat,
+ 		stat->nlink = dentry->d_inode->i_nlink;
+ 
+ out:
+-	revert_creds(old_cred);
++	ovl_revert_creds(dentry->d_sb, old_cred);
+ 
+ 	return err;
+ }
+@@ -291,7 +291,7 @@ int ovl_permission(struct inode *inode, int mask)
+ 		mask |= MAY_READ;
+ 	}
+ 	err = inode_permission(realinode, mask);
+-	revert_creds(old_cred);
++	ovl_revert_creds(inode->i_sb, old_cred);
+ 
+ 	return err;
+ }
+@@ -308,7 +308,7 @@ static const char *ovl_get_link(struct dentry *dentry,
+ 
+ 	old_cred = ovl_override_creds(dentry->d_sb);
+ 	p = vfs_get_link(ovl_dentry_real(dentry), done);
+-	revert_creds(old_cred);
++	ovl_revert_creds(dentry->d_sb, old_cred);
+ 	return p;
+ }
+ 
+@@ -351,7 +351,7 @@ int ovl_xattr_set(struct dentry *dentry, struct inode *inode, const char *name,
+ 		WARN_ON(flags != XATTR_REPLACE);
+ 		err = vfs_removexattr(realdentry, name);
+ 	}
+-	revert_creds(old_cred);
++	ovl_revert_creds(dentry->d_sb, old_cred);
+ 
+ 	/* copy c/mtime */
+ 	ovl_copyattr(d_inode(realdentry), inode);
+@@ -373,7 +373,7 @@ int ovl_xattr_get(struct dentry *dentry, struct inode *inode, const char *name,
+ 	old_cred = ovl_override_creds(dentry->d_sb);
+ 	res = __vfs_getxattr(realdentry, d_inode(realdentry), name,
+ 			     value, size, flags);
+-	revert_creds(old_cred);
++	ovl_revert_creds(dentry->d_sb, old_cred);
+ 	return res;
+ }
+ 
+@@ -398,7 +398,7 @@ ssize_t ovl_listxattr(struct dentry *dentry, char *list, size_t size)
+ 
+ 	old_cred = ovl_override_creds(dentry->d_sb);
+ 	res = vfs_listxattr(realdentry, list, size);
+-	revert_creds(old_cred);
++	ovl_revert_creds(dentry->d_sb, old_cred);
+ 	if (res <= 0 || size == 0)
+ 		return res;
+ 
+@@ -433,7 +433,7 @@ struct posix_acl *ovl_get_acl(struct inode *inode, int type)
+ 
+ 	old_cred = ovl_override_creds(inode->i_sb);
+ 	acl = get_acl(realinode, type);
+-	revert_creds(old_cred);
++	ovl_revert_creds(inode->i_sb, old_cred);
+ 
+ 	return acl;
+ }
+@@ -471,7 +471,7 @@ static int ovl_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo,
+ 		filemap_write_and_wait(realinode->i_mapping);
+ 
+ 	err = realinode->i_op->fiemap(realinode, fieinfo, start, len);
+-	revert_creds(old_cred);
++	ovl_revert_creds(inode->i_sb, old_cred);
+ 
+ 	return err;
+ }
+diff --git a/fs/overlayfs/namei.c b/fs/overlayfs/namei.c
+index f5aba0a0767b..e9f989a2d57b 100644
+--- a/fs/overlayfs/namei.c
++++ b/fs/overlayfs/namei.c
+@@ -1076,7 +1076,7 @@ struct dentry *ovl_lookup(struct inode *dir, struct dentry *dentry,
+ 			goto out_free_oe;
+ 	}
+ 
+-	revert_creds(old_cred);
++	ovl_revert_creds(dentry->d_sb, old_cred);
+ 	if (origin_path) {
+ 		dput(origin_path->dentry);
+ 		kfree(origin_path);
+@@ -1103,7 +1103,7 @@ struct dentry *ovl_lookup(struct inode *dir, struct dentry *dentry,
+ 	kfree(upperredirect);
+ out:
+ 	kfree(d.redirect);
+-	revert_creds(old_cred);
++	ovl_revert_creds(dentry->d_sb, old_cred);
+ 	return ERR_PTR(err);
+ }
+ 
+@@ -1157,7 +1157,7 @@ bool ovl_lower_positive(struct dentry *dentry)
+ 			dput(this);
+ 		}
+ 	}
+-	revert_creds(old_cred);
++	ovl_revert_creds(dentry->d_sb, old_cred);
+ 
+ 	return positive;
+ }
+diff --git a/fs/overlayfs/overlayfs.h b/fs/overlayfs/overlayfs.h
+index 55b872c28bf9..ab9802242857 100644
+--- a/fs/overlayfs/overlayfs.h
++++ b/fs/overlayfs/overlayfs.h
+@@ -213,6 +213,7 @@ int ovl_want_write(struct dentry *dentry);
+ void ovl_drop_write(struct dentry *dentry);
+ struct dentry *ovl_workdir(struct dentry *dentry);
+ const struct cred *ovl_override_creds(struct super_block *sb);
++void ovl_revert_creds(struct super_block *sb, const struct cred *oldcred);
+ struct super_block *ovl_same_sb(struct super_block *sb);
+ int ovl_can_decode_fh(struct super_block *sb);
+ struct dentry *ovl_indexdir(struct super_block *sb);
+diff --git a/fs/overlayfs/ovl_entry.h b/fs/overlayfs/ovl_entry.h
+index a8279280e88d..e847d7564999 100644
+--- a/fs/overlayfs/ovl_entry.h
++++ b/fs/overlayfs/ovl_entry.h
+@@ -17,6 +17,7 @@ struct ovl_config {
+ 	bool nfs_export;
+ 	int xino;
+ 	bool metacopy;
++	bool override_creds;
+ };
+ 
+ struct ovl_sb {
+diff --git a/fs/overlayfs/readdir.c b/fs/overlayfs/readdir.c
+index 47a91c9733a5..874a1b3ff99a 100644
+--- a/fs/overlayfs/readdir.c
++++ b/fs/overlayfs/readdir.c
+@@ -286,7 +286,7 @@ static int ovl_check_whiteouts(struct dentry *dir, struct ovl_readdir_data *rdd)
+ 		}
+ 		inode_unlock(dir->d_inode);
+ 	}
+-	revert_creds(old_cred);
++	ovl_revert_creds(rdd->dentry->d_sb, old_cred);
+ 
+ 	return err;
+ }
+@@ -918,7 +918,7 @@ int ovl_check_empty_dir(struct dentry *dentry, struct list_head *list)
+ 
+ 	old_cred = ovl_override_creds(dentry->d_sb);
+ 	err = ovl_dir_read_merged(dentry, list, &root);
+-	revert_creds(old_cred);
++	ovl_revert_creds(dentry->d_sb, old_cred);
+ 	if (err)
+ 		return err;
+ 
+diff --git a/fs/overlayfs/super.c b/fs/overlayfs/super.c
+index c91e7b604631..1e70914f2bb4 100644
+--- a/fs/overlayfs/super.c
++++ b/fs/overlayfs/super.c
+@@ -53,6 +53,11 @@ module_param_named(xino_auto, ovl_xino_auto_def, bool, 0644);
+ MODULE_PARM_DESC(xino_auto,
+ 		 "Auto enable xino feature");
+ 
++static bool __read_mostly ovl_override_creds_def = true;
++module_param_named(override_creds, ovl_override_creds_def, bool, 0644);
++MODULE_PARM_DESC(ovl_override_creds_def,
++		 "Use mounter's credentials for accesses");
++
+ static void ovl_entry_stack_free(struct ovl_entry *oe)
+ {
+ 	unsigned int i;
+@@ -363,6 +368,9 @@ static int ovl_show_options(struct seq_file *m, struct dentry *dentry)
+ 	if (ofs->config.metacopy != ovl_metacopy_def)
+ 		seq_printf(m, ",metacopy=%s",
+ 			   ofs->config.metacopy ? "on" : "off");
++	if (ofs->config.override_creds != ovl_override_creds_def)
++		seq_show_option(m, "override_creds",
++				ofs->config.override_creds ? "on" : "off");
+ 	return 0;
+ }
+ 
+@@ -403,6 +411,8 @@ enum {
+ 	OPT_XINO_AUTO,
+ 	OPT_METACOPY_ON,
+ 	OPT_METACOPY_OFF,
++	OPT_OVERRIDE_CREDS_ON,
++	OPT_OVERRIDE_CREDS_OFF,
+ 	OPT_ERR,
+ };
+ 
+@@ -421,6 +431,8 @@ static const match_table_t ovl_tokens = {
+ 	{OPT_XINO_AUTO,			"xino=auto"},
+ 	{OPT_METACOPY_ON,		"metacopy=on"},
+ 	{OPT_METACOPY_OFF,		"metacopy=off"},
++	{OPT_OVERRIDE_CREDS_ON,		"override_creds=on"},
++	{OPT_OVERRIDE_CREDS_OFF,	"override_creds=off"},
+ 	{OPT_ERR,			NULL}
+ };
+ 
+@@ -479,6 +491,7 @@ static int ovl_parse_opt(char *opt, struct ovl_config *config)
+ 	config->redirect_mode = kstrdup(ovl_redirect_mode_def(), GFP_KERNEL);
+ 	if (!config->redirect_mode)
+ 		return -ENOMEM;
++	config->override_creds = ovl_override_creds_def;
+ 
+ 	while ((p = ovl_next_opt(&opt)) != NULL) {
+ 		int token;
+@@ -559,6 +572,14 @@ static int ovl_parse_opt(char *opt, struct ovl_config *config)
+ 			config->metacopy = false;
+ 			break;
+ 
++		case OPT_OVERRIDE_CREDS_ON:
++			config->override_creds = true;
++			break;
++
++		case OPT_OVERRIDE_CREDS_OFF:
++			config->override_creds = false;
++			break;
++
+ 		default:
+ 			pr_err("overlayfs: unrecognized mount option \"%s\" or missing value\n", p);
+ 			return -EINVAL;
+@@ -1695,7 +1716,6 @@ static int ovl_fill_super(struct super_block *sb, void *data, int silent)
+ 		       ovl_dentry_lower(root_dentry), NULL);
+ 
+ 	sb->s_root = root_dentry;
+-
+ 	return 0;
+ 
+ out_free_oe:
+diff --git a/fs/overlayfs/util.c b/fs/overlayfs/util.c
+index 2050c5084a82..e1fd97fe37cc 100644
+--- a/fs/overlayfs/util.c
++++ b/fs/overlayfs/util.c
+@@ -37,9 +37,17 @@ const struct cred *ovl_override_creds(struct super_block *sb)
+ {
+ 	struct ovl_fs *ofs = sb->s_fs_info;
+ 
++	if (!ofs->config.override_creds)
++		return NULL;
+ 	return override_creds(ofs->creator_cred);
+ }
+ 
++void ovl_revert_creds(struct super_block *sb, const struct cred *old_cred)
++{
++	if (old_cred)
++		revert_creds(old_cred);
++}
++
+ struct super_block *ovl_same_sb(struct super_block *sb)
+ {
+ 	struct ovl_fs *ofs = sb->s_fs_info;
+@@ -791,7 +799,7 @@ int ovl_nlink_start(struct dentry *dentry)
+ 	 * value relative to the upper inode nlink in an upper inode xattr.
+ 	 */
+ 	err = ovl_set_nlink_upper(dentry);
+-	revert_creds(old_cred);
++	ovl_revert_creds(dentry->d_sb, old_cred);
+ 
+ out:
+ 	if (err)
+@@ -809,7 +817,7 @@ void ovl_nlink_end(struct dentry *dentry)
+ 
+ 		old_cred = ovl_override_creds(dentry->d_sb);
+ 		ovl_cleanup_index(dentry);
+-		revert_creds(old_cred);
++		ovl_revert_creds(dentry->d_sb, old_cred);
+ 	}
+ 
+ 	ovl_inode_unlock(inode);
diff --git a/android-mainline/series b/android-mainline/series
index bf735a3..47a97f4 100644
--- a/android-mainline/series
+++ b/android-mainline/series
@@ -2,7 +2,7 @@
 # android-mainline patches
 #
 # Applies onto mainline a99d8080aaf3 Linux v5.4-rc6
-# Matches android-mainline c5634733fa58 ("FROMGIT: of: property: Skip adding device links to suppliers that aren't devices")
+# Matches android-mainline 0ee40e0e58eb ("FROMLIST: overlayfs: override_creds=off option bypass creator_cred")
 #
 ANDROID-Kbuild-LLVMLinux-allow-overriding-clang-target-triple.patch
 ANDROID-net-xfrm-make-PF_KEY-SHA256-use-RFC-compliant-truncation.patch
@@ -230,3 +230,8 @@
 FROMGIT-scsi-core-allow-auto-suspend-override-by-low-level-driver.patch
 FROMGIT-scsi-ufs-override-auto-suspend-tunables-for-ufs.patch
 FROMGIT-of-property-Skip-adding-device-links-to-suppliers-that-aren-t-devices.patch
+FROMLIST-afs-xattr-use-scnprintf.patch
+FROMLIST-Add-flags-option-to-get-xattr-method-paired-to-__vfs_getxattr.patch
+FROMLIST-overlayfs-handle-XATTR_NOSECURITY-flag-for-get-xattr-method.patch
+FROMLIST-overlayfs-internal-getxattr-operations-without-sepolicy-checking.patch
+FROMLIST-overlayfs-override_creds-off-option-bypass-creator_cred.patch