ANDROID: sdcardfs: Fix locking issue with permision fix up

Don't use lookup_one_len so we can grab the spinlock that
protects d_subdirs.

Bug: 30954918
Change-Id: I0c6a393252db7beb467e0d563739a3a14e1b5115
Signed-off-by: Daniel Rosenberg <drosen@google.com>
Signed-off-by: Kevin F. Haggerty <haggertk@lineageos.org>
diff --git a/fs/sdcardfs/derived_perm.c b/fs/sdcardfs/derived_perm.c
index 05955b0..b10194b 100644
--- a/fs/sdcardfs/derived_perm.c
+++ b/fs/sdcardfs/derived_perm.c
@@ -141,32 +141,26 @@
 	info = SDCARDFS_I(dentry->d_inode);
 
 	if (needs_fixup(info->perm)) {
-		/* We need permission to fix up these values.
-		 * Since permissions are based of of the mount, and
-		 * we are accessing without the mount point, we create
-		 * a fake mount with the permissions we will be using.
-		 */
-		struct vfsmount fakemnt;
-		struct sdcardfs_vfsmount_options opts;
-		fakemnt.data = &opts;
-		opts.gid = AID_SDCARD_RW;
-		opts.mask = 0;
-		mutex_lock(&dentry->d_inode->i_mutex);
-		child = lookup_one_len2(name, &fakemnt, dentry, len);
-		mutex_unlock(&dentry->d_inode->i_mutex);
-		if (!IS_ERR(child)) {
-			if (child->d_inode) {
-				get_derived_permission(dentry, child);
-				fixup_tmp_permissions(child->d_inode);
-			}
-			dput(child);
+		spin_lock(&dentry->d_lock);
+		list_for_each_entry(child, &dentry->d_subdirs, d_child) {
+				dget(child);
+				if (!strncasecmp(child->d_name.name, name, len)) {
+					if (child->d_inode) {
+						get_derived_permission(dentry, child);
+						fixup_tmp_permissions(child->d_inode);
+						dput(child);
+						break;
+					}
+				}
+				dput(child);
 		}
+		spin_unlock(&dentry->d_lock);
 	} else 	if (descendant_may_need_fixup(info->perm)) {
-		mutex_lock(&dentry->d_inode->i_mutex);
+		spin_lock(&dentry->d_lock);
 		list_for_each_entry(child, &dentry->d_subdirs, d_child) {
 				fixup_perms_recursive(child, name, len);
 		}
-		mutex_unlock(&dentry->d_inode->i_mutex);
+		spin_unlock(&dentry->d_lock);
 	}
 	dput(dentry);
 }