ANDROID: sdcardfs: add support for user permission isolation
This allows you to hide the existence of a package from
a user by adding them to an exclude list. If a user
creates that package's folder and is on the exclude list,
they will not see that package's id.
Signed-off-by: Daniel Rosenberg <drosen@google.com>
Bug: 34542611
Change-Id: I9eb82e0bf2457d7eb81ee56153b9c7d2f6646323
diff --git a/fs/sdcardfs/derived_perm.c b/fs/sdcardfs/derived_perm.c
index 9408a54..a6d87d9 100644
--- a/fs/sdcardfs/derived_perm.c
+++ b/fs/sdcardfs/derived_perm.c
@@ -103,7 +103,7 @@
case PERM_ANDROID_OBB:
case PERM_ANDROID_MEDIA:
appid = get_appid(newdentry->d_name.name);
- if (appid != 0) {
+ if (appid != 0 && !is_excluded(newdentry->d_name.name, parent_info->userid)) {
info->d_uid = multiuser_get_uid(parent_info->userid, appid);
}
set_top(info, &info->vfs_inode);
@@ -116,8 +116,11 @@
get_derived_permission_new(parent, dentry, dentry);
}
-static int descendant_may_need_fixup(perm_t perm) {
- if (perm == PERM_PRE_ROOT || perm == PERM_ROOT || perm == PERM_ANDROID)
+static int descendant_may_need_fixup(struct sdcardfs_inode_info *info, struct limit_search *limit)
+{
+ if (info->perm == PERM_ROOT)
+ return (limit->flags & BY_USERID)?info->userid == limit->userid:1;
+ if (info->perm == PERM_PRE_ROOT || info->perm == PERM_ANDROID)
return 1;
return 0;
}
@@ -129,7 +132,8 @@
return 0;
}
-void fixup_perms_recursive(struct dentry *dentry, const char* name, size_t len) {
+void fixup_perms_recursive(struct dentry *dentry, struct limit_search *limit)
+{
struct dentry *child;
struct sdcardfs_inode_info *info;
if (!dget(dentry))
@@ -143,22 +147,22 @@
if (needs_fixup(info->perm)) {
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 (child->d_inode) {
- get_derived_permission(dentry, child);
- fixup_tmp_permissions(child->d_inode);
- dput(child);
- break;
- }
+ dget(child);
+ if (!(limit->flags & BY_NAME) || !strncasecmp(child->d_name.name, limit->name, limit->length)) {
+ if (d_inode(child)) {
+ get_derived_permission(dentry, child);
+ fixup_tmp_permissions(d_inode(child));
+ dput(child);
+ break;
}
- dput(child);
+ }
+ dput(child);
}
spin_unlock(&dentry->d_lock);
- } else if (descendant_may_need_fixup(info->perm)) {
+ } else if (descendant_may_need_fixup(info, limit)) {
spin_lock(&dentry->d_lock);
list_for_each_entry(child, &dentry->d_subdirs, d_child) {
- fixup_perms_recursive(child, name, len);
+ fixup_perms_recursive(child, limit);
}
spin_unlock(&dentry->d_lock);
}