ANDROID: sdcardfs: Bring up to date with Android M permissions:
In M, the workings of sdcardfs were changed significantly.
This brings sdcardfs into line with the changes.
Change-Id: I10e91a84a884c838feef7aa26c0a2b21f02e052e
diff --git a/fs/sdcardfs/lookup.c b/fs/sdcardfs/lookup.c
index a4b94df..f80abcb 100644
--- a/fs/sdcardfs/lookup.c
+++ b/fs/sdcardfs/lookup.c
@@ -64,10 +64,17 @@
return 0;
}
-static int sdcardfs_inode_test(struct inode *inode, void *candidate_lower_inode)
+struct inode_data {
+ struct inode *lower_inode;
+ userid_t id;
+};
+
+static int sdcardfs_inode_test(struct inode *inode, void *candidate_data/*void *candidate_lower_inode*/)
{
struct inode *current_lower_inode = sdcardfs_lower_inode(inode);
- if (current_lower_inode == (struct inode *)candidate_lower_inode)
+ userid_t current_userid = SDCARDFS_I(inode)->userid;
+ if (current_lower_inode == ((struct inode_data *)candidate_data)->lower_inode &&
+ current_userid == ((struct inode_data *)candidate_data)->id)
return 1; /* found a match */
else
return 0; /* no match */
@@ -79,12 +86,15 @@
return 0;
}
-struct inode *sdcardfs_iget(struct super_block *sb, struct inode *lower_inode)
+struct inode *sdcardfs_iget(struct super_block *sb, struct inode *lower_inode, userid_t id)
{
struct sdcardfs_inode_info *info;
+ struct inode_data data;
struct inode *inode; /* the new inode to return */
int err;
+ data.id = id;
+ data.lower_inode = lower_inode;
inode = iget5_locked(sb, /* our superblock */
/*
* hashval: we use inode number, but we can
@@ -94,7 +104,7 @@
lower_inode->i_ino, /* hashval */
sdcardfs_inode_test, /* inode comparison function */
sdcardfs_inode_set, /* inode init function */
- lower_inode); /* data passed to test+set fxns */
+ &data); /* data passed to test+set fxns */
if (!inode) {
err = -EACCES;
iput(lower_inode);
@@ -146,11 +156,9 @@
lower_inode->i_rdev);
/* all well, copy inode attributes */
- fsstack_copy_attr_all(inode, lower_inode);
+ sdcardfs_copy_and_fix_attrs(inode, lower_inode);
fsstack_copy_inode_size(inode, lower_inode);
- fix_derived_permission(inode);
-
unlock_new_inode(inode);
return inode;
}
@@ -164,7 +172,7 @@
* @lower_path: the lower path (caller does path_get/put)
*/
int sdcardfs_interpose(struct dentry *dentry, struct super_block *sb,
- struct path *lower_path)
+ struct path *lower_path, userid_t id)
{
int err = 0;
struct inode *inode;
@@ -186,14 +194,14 @@
*/
/* inherit lower inode number for sdcardfs's inode */
- inode = sdcardfs_iget(sb, lower_inode);
+ inode = sdcardfs_iget(sb, lower_inode, id);
if (IS_ERR(inode)) {
err = PTR_ERR(inode);
goto out;
}
d_add(dentry, inode);
- update_derived_permission(dentry);
+ update_derived_permission_lock(dentry);
out:
return err;
}
@@ -205,7 +213,7 @@
* Fills in lower_parent_path with <dentry,mnt> on success.
*/
static struct dentry *__sdcardfs_lookup(struct dentry *dentry,
- unsigned int flags, struct path *lower_parent_path)
+ unsigned int flags, struct path *lower_parent_path, userid_t id)
{
int err = 0;
struct vfsmount *lower_dir_mnt;
@@ -266,7 +274,7 @@
}
sdcardfs_set_lower_path(dentry, &lower_path);
- err = sdcardfs_interpose(dentry, dentry->d_sb, &lower_path);
+ err = sdcardfs_interpose(dentry, dentry->d_sb, &lower_path, id);
if (err) /* path_put underlying path on error */
sdcardfs_put_reset_lower_path(dentry);
goto out;
@@ -328,13 +336,11 @@
struct dentry *ret = NULL, *parent;
struct path lower_parent_path;
int err = 0;
- struct sdcardfs_sb_info *sbi = SDCARDFS_SB(dentry->d_sb);
const struct cred *saved_cred = NULL;
parent = dget_parent(dentry);
- if(!check_caller_access_to_name(parent->d_inode, dentry->d_name.name,
- sbi->options.derive, 0, 0)) {
+ if(!check_caller_access_to_name(parent->d_inode, dentry->d_name.name)) {
ret = ERR_PTR(-EACCES);
printk(KERN_INFO "%s: need to check the caller's gid in packages.list\n"
" dentry: %s, task:%s\n",
@@ -354,7 +360,7 @@
goto out;
}
- ret = __sdcardfs_lookup(dentry, flags, &lower_parent_path);
+ ret = __sdcardfs_lookup(dentry, flags, &lower_parent_path, SDCARDFS_I(dir)->userid);
if (IS_ERR(ret))
{
goto out;
@@ -365,8 +371,10 @@
fsstack_copy_attr_times(dentry->d_inode,
sdcardfs_lower_inode(dentry->d_inode));
/* get drived permission */
+ mutex_lock(&dentry->d_inode->i_mutex);
get_derived_permission(parent, dentry);
fix_derived_permission(dentry->d_inode);
+ mutex_unlock(&dentry->d_inode->i_mutex);
}
/* update parent directory's atime */
fsstack_copy_attr_atime(parent->d_inode,