Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 83f714f9 authored by Daniel Rosenberg's avatar Daniel Rosenberg
Browse files

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: default avatarDaniel Rosenberg <drosen@google.com>
parent 6eb8f1f5
Loading
Loading
Loading
Loading
+15 −21
Original line number Diff line number Diff line
@@ -141,32 +141,26 @@ void fixup_perms_recursive(struct dentry *dentry, const char* name, size_t len)
	info = SDCARDFS_I(d_inode(dentry));

	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(&d_inode(dentry)->i_mutex);
		child = lookup_one_len2(name, &fakemnt, dentry, len);
		mutex_unlock(&d_inode(dentry)->i_mutex);
		if (!IS_ERR(child)) {
			if (d_inode(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(d_inode(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(&d_inode(dentry)->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(&d_inode(dentry)->i_mutex);
		spin_unlock(&dentry->d_lock);
	}
	dput(dentry);
}