summaryrefslogtreecommitdiff
path: root/fs
diff options
context:
space:
mode:
authorDaniel Rosenberg <drosen@google.com>2016-12-27 12:36:29 -0800
committerAmit Pundir <amit.pundir@linaro.org>2017-02-03 15:04:29 +0530
commitdfa46aa6a92fe69cd50d84f4226f001c82bbdb98 (patch)
treec35e0633be578eb753353909f52727598573e1fa /fs
parent9e6375eaa2b37d0c4edcc7941f1653f974ed39bd (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>
Diffstat (limited to 'fs')
-rw-r--r--fs/sdcardfs/derived_perm.c36
1 files changed, 15 insertions, 21 deletions
diff --git a/fs/sdcardfs/derived_perm.c b/fs/sdcardfs/derived_perm.c
index 066edbbb6ad6..c77695c8f729 100644
--- 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(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)) {
- get_derived_permission(dentry, child);
- fixup_tmp_permissions(d_inode(child));
- }
- 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 (d_inode(child)) {
+ get_derived_permission(dentry, child);
+ fixup_tmp_permissions(d_inode(child));
+ 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);
}