void get_derived_permission(struct dentry *parent, struct dentry *dentry) { struct sdcardfs_sb_info *sbi = SDCARDFS_SB(dentry->d_sb); struct sdcardfs_inode_info *info = SDCARDFS_I(dentry->d_inode); struct sdcardfs_inode_info *parent_info= SDCARDFS_I(parent->d_inode); appid_t appid; /* By default, each inode inherits from its parent. * the properties are maintained on its private fields * because the inode attributes will be modified with that of * its lower inode. * The derived state will be updated on the last * stage of each system call by fix_derived_permission(inode). */ inherit_derived_state(parent->d_inode, dentry->d_inode); /* Derive custom permissions based on parent and current node */ switch (parent_info->perm) { case PERM_INHERIT: /* Already inherited above */ break; case PERM_PRE_ROOT: /* Legacy internal layout places users at top level */ info->perm = PERM_ROOT; info->userid = simple_strtoul(dentry->d_name.name, NULL, 10); if (sbi->options.sdfs_gid == AID_SDCARD_RW) info->d_gid = sbi->options.sdfs_gid; else info->d_gid = multiuser_get_uid(info->userid, sbi->options.sdfs_gid); break; case PERM_ROOT: /* Assume masked off by default. */ if (!strcasecmp(dentry->d_name.name, "Android")) { /* App-specific directories inside; let anyone traverse */ info->perm = PERM_ANDROID; info->d_under_android = true; } break; case PERM_ANDROID: if (!strcasecmp(dentry->d_name.name, "data")) { /* App-specific directories inside; let anyone traverse */ info->perm = PERM_ANDROID_DATA; } else if (!strcasecmp(dentry->d_name.name, "obb")) { /* App-specific directories inside; let anyone traverse */ info->perm = PERM_ANDROID_OBB; // FIXME : this feature will be implemented later. /* Single OBB directory is always shared */ // ex. Fuse daemon.. // node->graft_path = fuse->obb_path; // node->graft_pathlen = strlen(fuse->obb_path); } else if (!strcasecmp(dentry->d_name.name, "media")) { /* App-specific directories inside; let anyone traverse */ info->perm = PERM_ANDROID_MEDIA; } break; /* same policy will be applied on PERM_ANDROID_DATA * and PERM_ANDROID_OBB */ case PERM_ANDROID_DATA: case PERM_ANDROID_OBB: case PERM_ANDROID_MEDIA: appid = get_appid(sbi->pkgl_id, dentry->d_name.name); if (appid != 0) { info->d_uid = multiuser_get_uid(parent_info->userid, appid); } break; } }
void get_derived_permission_lollipop(struct dentry *parent, struct dentry *dentry) { struct sdcardfslp_sb_info *sbi = SDCARDFSLP_SB(dentry->d_sb); struct sdcardfslp_inode_info *info = SDCARDFSLP_I(dentry->d_inode); struct sdcardfslp_inode_info *parent_info= SDCARDFSLP_I(parent->d_inode); appid_t appid; /* By default, each inode inherits from its parent. * the properties are maintained on its private fields * because the inode attributes will be modified with that of * its lower inode. * The derived state will be updated on the last * stage of each system call by fix_derived_permission(inode). */ inherit_derived_state(parent->d_inode, dentry->d_inode); //printk(KERN_INFO "sdcardfslp: derived: %s, %s, %d\n", parent->d_name.name, // dentry->d_name.name, parent_info->perm); if (sbi->options.derive == DERIVE_NONE) { return; } /* Derive custom permissions based on parent and current node */ switch (parent_info->perm) { case PERM_INHERIT: /* Already inherited above */ break; case PERM_LEGACY_PRE_ROOT: /* Legacy internal layout places users at top level */ info->perm = PERM_ROOT; info->userid = simple_strtoul(dentry->d_name.name, NULL, 10); break; case PERM_ROOT: /* Assume masked off by default. */ info->d_mode = 00770; if (!strcasecmp(dentry->d_name.name, "Android")) { /* App-specific directories inside; let anyone traverse */ info->perm = PERM_ANDROID; info->d_mode = 00771; } else if (sbi->options.split_perms) { if (!strcasecmp(dentry->d_name.name, "DCIM") || !strcasecmp(dentry->d_name.name, "Pictures")) { info->d_gid = AID_SDCARD_PICS; } else if (!strcasecmp(dentry->d_name.name, "Alarms") || !strcasecmp(dentry->d_name.name, "Movies") || !strcasecmp(dentry->d_name.name, "Music") || !strcasecmp(dentry->d_name.name, "Notifications") || !strcasecmp(dentry->d_name.name, "Podcasts") || !strcasecmp(dentry->d_name.name, "Ringtones")) { info->d_gid = AID_SDCARD_AV; } } break; case PERM_ANDROID: if (!strcasecmp(dentry->d_name.name, "data")) { /* App-specific directories inside; let anyone traverse */ info->perm = PERM_ANDROID_DATA; info->d_mode = 00771; } else if (!strcasecmp(dentry->d_name.name, "obb")) { /* App-specific directories inside; let anyone traverse */ info->perm = PERM_ANDROID_OBB; info->d_mode = 00771; // FIXME : this feature will be implemented later. /* Single OBB directory is always shared */ } else if (!strcasecmp(dentry->d_name.name, "media")) { /* App-specific directories inside; let anyone traverse */ info->perm = PERM_ANDROID_MEDIA; info->d_mode = 00771; } else if (!strcasecmp(dentry->d_name.name, "user")) { /* User directories must only be accessible to system, protected * by sdcard_all. Zygote will bind mount the appropriate user- * specific path. */ info->perm = PERM_ANDROID_USER; info->d_gid = AID_SDCARD_ALL; info->d_mode = 00770; } break; /* same policy will be applied on PERM_ANDROID_DATA * and PERM_ANDROID_OBB */ case PERM_ANDROID_DATA: case PERM_ANDROID_OBB: case PERM_ANDROID_MEDIA: appid = get_appid_lollipop(sbi->pkgl_id, dentry->d_name.name); if (appid != 0) { info->d_uid = multiuser_get_uid(parent_info->userid, appid); } info->d_mode = 00770; break; case PERM_ANDROID_USER: /* Root of a secondary user */ info->perm = PERM_ROOT; info->userid = simple_strtoul(dentry->d_name.name, NULL, 10); info->d_gid = AID_SDCARD_R; info->d_mode = 00771; break; } }