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>
This commit is contained in:
Daniel Rosenberg 2016-12-27 12:36:29 -08:00 committed by Artem Borisov
parent ac0146e438
commit cd769ec65b
1 changed files with 15 additions and 21 deletions

View File

@ -141,32 +141,26 @@ void fixup_perms_recursive(struct dentry *dentry, const char* name, size_t len)
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);
}