summaryrefslogtreecommitdiff
path: root/fs/sdcardfs/main.c
diff options
context:
space:
mode:
authorDaniel Rosenberg <drosen@google.com>2016-02-03 21:08:21 -0800
committerAmit Pundir <amit.pundir@linaro.org>2016-04-07 16:50:02 +0530
commitb0f3f87bc1533c64aa1b1a86dd583c92919462ca (patch)
tree488564049eac63720cf598554d98ca51ef7022d8 /fs/sdcardfs/main.c
parentef5f9857ff64f07f41bc7fca9b1f402e4638f9a5 (diff)
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
Diffstat (limited to 'fs/sdcardfs/main.c')
-rw-r--r--fs/sdcardfs/main.c141
1 files changed, 61 insertions, 80 deletions
diff --git a/fs/sdcardfs/main.c b/fs/sdcardfs/main.c
index 9d04ae8ceb46..80aa355d801e 100644
--- a/fs/sdcardfs/main.c
+++ b/fs/sdcardfs/main.c
@@ -24,25 +24,27 @@
#include <linux/parser.h>
enum {
- Opt_uid,
+ Opt_fsuid,
+ Opt_fsgid,
Opt_gid,
- Opt_wgid,
Opt_debug,
- Opt_split,
- Opt_derive,
Opt_lower_fs,
+ Opt_mask,
+ Opt_multiuser, // May need?
+ Opt_userid,
Opt_reserved_mb,
Opt_err,
};
static const match_table_t sdcardfs_tokens = {
- {Opt_uid, "uid=%u"},
+ {Opt_fsuid, "fsuid=%u"},
+ {Opt_fsgid, "fsgid=%u"},
{Opt_gid, "gid=%u"},
- {Opt_wgid, "wgid=%u"},
{Opt_debug, "debug"},
- {Opt_split, "split"},
- {Opt_derive, "derive=%s"},
{Opt_lower_fs, "lower_fs=%s"},
+ {Opt_mask, "mask=%u"},
+ {Opt_userid, "userid=%d"},
+ {Opt_multiuser, "multiuser"},
{Opt_reserved_mb, "reserved_mb=%u"},
{Opt_err, NULL}
};
@@ -58,12 +60,10 @@ static int parse_options(struct super_block *sb, char *options, int silent,
/* by default, we use AID_MEDIA_RW as uid, gid */
opts->fs_low_uid = AID_MEDIA_RW;
opts->fs_low_gid = AID_MEDIA_RW;
- /* by default, we use AID_SDCARD_RW as write_gid */
- opts->write_gid = AID_SDCARD_RW;
- /* default permission policy
- * (DERIVE_NONE | DERIVE_LEGACY | DERIVE_UNIFIED) */
- opts->derive = DERIVE_NONE;
- opts->split_perms = 0;
+ opts->mask = 0;
+ opts->multiuser = false;
+ opts->fs_user_id = 0;
+ opts->gid = 0;
/* by default, we use LOWER_FS_EXT4 as lower fs type */
opts->lower_fs = LOWER_FS_EXT4;
/* by default, 0MB is reserved */
@@ -85,37 +85,33 @@ static int parse_options(struct super_block *sb, char *options, int silent,
case Opt_debug:
*debug = 1;
break;
- case Opt_uid:
+ case Opt_fsuid:
if (match_int(&args[0], &option))
return 0;
opts->fs_low_uid = option;
break;
- case Opt_gid:
+ case Opt_fsgid:
if (match_int(&args[0], &option))
return 0;
opts->fs_low_gid = option;
break;
- case Opt_wgid:
+ case Opt_gid:
if (match_int(&args[0], &option))
return 0;
- opts->write_gid = option;
+ opts->gid = option;
break;
- case Opt_split:
- opts->split_perms=1;
+ case Opt_userid:
+ if (match_int(&args[0], &option))
+ return 0;
+ opts->fs_user_id = option;
break;
- case Opt_derive:
- string_option = match_strdup(&args[0]);
- if (!strcmp("none", string_option)) {
- opts->derive = DERIVE_NONE;
- } else if (!strcmp("legacy", string_option)) {
- opts->derive = DERIVE_LEGACY;
- } else if (!strcmp("unified", string_option)) {
- opts->derive = DERIVE_UNIFIED;
- } else {
- kfree(string_option);
- goto invalid_option;
- }
- kfree(string_option);
+ case Opt_mask:
+ if (match_int(&args[0], &option))
+ return 0;
+ opts->mask = option;
+ break;
+ case Opt_multiuser:
+ opts->multiuser = true;
break;
case Opt_lower_fs:
string_option = match_strdup(&args[0]);
@@ -184,6 +180,11 @@ static struct dentry *sdcardfs_d_alloc_root(struct super_block *sb)
}
#endif
+DEFINE_MUTEX(sdcardfs_super_list_lock);
+LIST_HEAD(sdcardfs_super_list);
+EXPORT_SYMBOL_GPL(sdcardfs_super_list_lock);
+EXPORT_SYMBOL_GPL(sdcardfs_super_list);
+
/*
* There is no need to lock the sdcardfs_super_info's rwsem as there is no
* way anyone can have a reference to the superblock at this point in time.
@@ -196,7 +197,6 @@ static int sdcardfs_read_super(struct super_block *sb, const char *dev_name,
struct super_block *lower_sb;
struct path lower_path;
struct sdcardfs_sb_info *sb_info;
- void *pkgl_id;
struct inode *inode;
printk(KERN_INFO "sdcardfs version 2.0\n");
@@ -215,8 +215,7 @@ static int sdcardfs_read_super(struct super_block *sb, const char *dev_name,
err = kern_path(dev_name, LOOKUP_FOLLOW | LOOKUP_DIRECTORY,
&lower_path);
if (err) {
- printk(KERN_ERR "sdcardfs: error accessing "
- "lower directory '%s'\n", dev_name);
+ printk(KERN_ERR "sdcardfs: error accessing lower directory '%s'\n", dev_name);
goto out;
}
@@ -229,7 +228,6 @@ static int sdcardfs_read_super(struct super_block *sb, const char *dev_name,
}
sb_info = sb->s_fs_info;
-
/* parse options */
err = parse_options(sb, raw_data, silent, &debug, &sb_info->options);
if (err) {
@@ -237,14 +235,6 @@ static int sdcardfs_read_super(struct super_block *sb, const char *dev_name,
goto out_freesbi;
}
- if (sb_info->options.derive != DERIVE_NONE) {
- pkgl_id = packagelist_create(sb_info->options.write_gid);
- if(IS_ERR(pkgl_id))
- goto out_freesbi;
- else
- sb_info->pkgl_id = pkgl_id;
- }
-
/* set the lower superblock field of upper superblock */
lower_sb = lower_path.dentry->d_sb;
atomic_inc(&lower_sb->s_active);
@@ -263,7 +253,7 @@ static int sdcardfs_read_super(struct super_block *sb, const char *dev_name,
sb->s_op = &sdcardfs_sops;
/* get a new inode and allocate our root dentry */
- inode = sdcardfs_iget(sb, lower_path.dentry->d_inode);
+ inode = sdcardfs_iget(sb, lower_path.dentry->d_inode, 0);
if (IS_ERR(inode)) {
err = PTR_ERR(inode);
goto out_sput;
@@ -292,41 +282,22 @@ static int sdcardfs_read_super(struct super_block *sb, const char *dev_name,
d_rehash(sb->s_root);
/* setup permission policy */
- switch(sb_info->options.derive) {
- case DERIVE_NONE:
- setup_derived_state(sb->s_root->d_inode,
- PERM_ROOT, 0, AID_ROOT, AID_SDCARD_RW, 00775);
- sb_info->obbpath_s = NULL;
- break;
- case DERIVE_LEGACY:
- /* Legacy behavior used to support internal multiuser layout which
- * places user_id at the top directory level, with the actual roots
- * just below that. Shared OBB path is also at top level. */
- setup_derived_state(sb->s_root->d_inode,
- PERM_LEGACY_PRE_ROOT, 0, AID_ROOT, AID_SDCARD_R, 00771);
- /* initialize the obbpath string and lookup the path
- * sb_info->obb_path will be deactivated by path_put
- * on sdcardfs_put_super */
- sb_info->obbpath_s = kzalloc(PATH_MAX, GFP_KERNEL);
- snprintf(sb_info->obbpath_s, PATH_MAX, "%s/obb", dev_name);
- err = prepare_dir(sb_info->obbpath_s,
+ sb_info->obbpath_s = kzalloc(PATH_MAX, GFP_KERNEL);
+ mutex_lock(&sdcardfs_super_list_lock);
+ if(sb_info->options.multiuser) {
+ setup_derived_state(sb->s_root->d_inode, PERM_PRE_ROOT, sb_info->options.fs_user_id, AID_ROOT, false);
+ snprintf(sb_info->obbpath_s, PATH_MAX, "%s/obb", dev_name);
+ /*err = prepare_dir(sb_info->obbpath_s,
sb_info->options.fs_low_uid,
- sb_info->options.fs_low_gid, 00755);
- if(err)
- printk(KERN_ERR "sdcardfs: %s: %d, error on creating %s\n",
- __func__,__LINE__, sb_info->obbpath_s);
- break;
- case DERIVE_UNIFIED:
- /* Unified multiuser layout which places secondary user_id under
- * /Android/user and shared OBB path under /Android/obb. */
- setup_derived_state(sb->s_root->d_inode,
- PERM_ROOT, 0, AID_ROOT, AID_SDCARD_R, 00771);
-
- sb_info->obbpath_s = kzalloc(PATH_MAX, GFP_KERNEL);
- snprintf(sb_info->obbpath_s, PATH_MAX, "%s/Android/obb", dev_name);
- break;
+ sb_info->options.fs_low_gid, 00755);*/
+ } else {
+ setup_derived_state(sb->s_root->d_inode, PERM_ROOT, sb_info->options.fs_low_uid, AID_ROOT, false);
+ snprintf(sb_info->obbpath_s, PATH_MAX, "%s/Android/obb", dev_name);
}
fix_derived_permission(sb->s_root->d_inode);
+ sb_info->sb = sb;
+ list_add(&sb_info->list, &sdcardfs_super_list);
+ mutex_unlock(&sdcardfs_super_list_lock);
if (!silent)
printk(KERN_INFO "sdcardfs: mounted on top of %s type %s\n",
@@ -341,7 +312,6 @@ out_iput:
out_sput:
/* drop refs we took earlier */
atomic_dec(&lower_sb->s_active);
- packagelist_destroy(sb_info->pkgl_id);
out_freesbi:
kfree(SDCARDFS_SB(sb));
sb->s_fs_info = NULL;
@@ -386,11 +356,22 @@ struct dentry *sdcardfs_mount(struct file_system_type *fs_type, int flags,
raw_data, sdcardfs_read_super);
}
+void sdcardfs_kill_sb(struct super_block *sb) {
+ struct sdcardfs_sb_info *sbi;
+ if (sb->s_magic == SDCARDFS_SUPER_MAGIC) {
+ sbi = SDCARDFS_SB(sb);
+ mutex_lock(&sdcardfs_super_list_lock);
+ list_del(&sbi->list);
+ mutex_unlock(&sdcardfs_super_list_lock);
+ }
+ generic_shutdown_super(sb);
+}
+
static struct file_system_type sdcardfs_fs_type = {
.owner = THIS_MODULE,
.name = SDCARDFS_NAME,
.mount = sdcardfs_mount,
- .kill_sb = generic_shutdown_super,
+ .kill_sb = sdcardfs_kill_sb,
.fs_flags = 0,
};