From b0f3f87bc1533c64aa1b1a86dd583c92919462ca Mon Sep 17 00:00:00 2001 From: Daniel Rosenberg Date: Wed, 3 Feb 2016 21:08:21 -0800 Subject: 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 --- fs/sdcardfs/main.c | 141 +++++++++++++++++++++++------------------------------ 1 file changed, 61 insertions(+), 80 deletions(-) (limited to 'fs/sdcardfs/main.c') 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 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, }; -- cgit v1.2.3