diff options
| author | Daniel Rosenberg <drosen@google.com> | 2016-12-27 12:36:29 -0800 |
|---|---|---|
| committer | Mister Oyster <oysterized@gmail.com> | 2017-04-13 12:32:16 +0200 |
| commit | d9a574a77cb3cde863ed3f954610d691f9753f59 (patch) | |
| tree | 1b312fff1c9cb856682274dcfa1b58d37422e424 | |
| parent | 572dce50cc0c7a348af9c35290669b5bb8761011 (diff) | |
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>
| -rwxr-xr-x | fs/sdcardfs/derived_perm.c | 36 |
1 files changed, 15 insertions, 21 deletions
diff --git a/fs/sdcardfs/derived_perm.c b/fs/sdcardfs/derived_perm.c index 48380e0ce..4b876455d 100755 --- a/fs/sdcardfs/derived_perm.c +++ b/fs/sdcardfs/derived_perm.c @@ -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_u.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_u.d_child) { fixup_perms_recursive(child, name, len); } - mutex_unlock(&dentry->d_inode->i_mutex); + spin_unlock(&dentry->d_lock); } dput(dentry); } |
