diff --git a/sdcard/sdcard.c b/sdcard/sdcard.c index ba4d70c0c..41bf0454f 100644 --- a/sdcard/sdcard.c +++ b/sdcard/sdcard.c @@ -151,7 +151,7 @@ struct node { perm_t perm; userid_t userid; uid_t uid; - mode_t mode; + bool under_android; struct node *next; /* per-dir sibling list */ struct node *child; /* first contained file by this dir */ @@ -419,11 +419,20 @@ static void attr_from_stat(struct fuse* fuse, struct fuse_attr *attr, attr->gid = multiuser_get_uid(node->userid, fuse->gid); } - /* Filter requested mode based on underlying file, and - * pass through file type. */ - int visible_mode = node->mode; - if (node->perm != PERM_PRE_ROOT) { - visible_mode = visible_mode & ~fuse->mask; + int visible_mode = 0775 & ~fuse->mask; + if (node->perm == PERM_PRE_ROOT) { + /* Top of multi-user view should always be visible to ensure + * secondary users can traverse inside. */ + visible_mode = 0711; + } else if (node->under_android) { + /* Block "other" access to Android directories, since only apps + * belonging to a specific user should be in there; we still + * leave +x open for the default view. */ + if (fuse->gid == AID_SDCARD_RW) { + visible_mode = visible_mode & ~0006; + } else { + visible_mode = visible_mode & ~0007; + } } int owner_mode = s->st_mode & 0700; int filtered_mode = visible_mode & (owner_mode | (owner_mode >> 3) | (owner_mode >> 6)); @@ -452,7 +461,7 @@ static void derive_permissions_locked(struct fuse* fuse, struct node *parent, node->perm = PERM_INHERIT; node->userid = parent->userid; node->uid = parent->uid; - node->mode = parent->mode; + node->under_android = parent->under_android; /* Derive custom permissions based on parent and current node */ switch (parent->perm) { @@ -463,33 +472,28 @@ static void derive_permissions_locked(struct fuse* fuse, struct node *parent, /* Legacy internal layout places users at top level */ node->perm = PERM_ROOT; node->userid = strtoul(node->name, NULL, 10); - node->mode = 0771; break; case PERM_ROOT: /* Assume masked off by default. */ - node->mode = 0770; if (!strcasecmp(node->name, "Android")) { /* App-specific directories inside; let anyone traverse */ node->perm = PERM_ANDROID; - node->mode = 0771; + node->under_android = true; } break; case PERM_ANDROID: if (!strcasecmp(node->name, "data")) { /* App-specific directories inside; let anyone traverse */ node->perm = PERM_ANDROID_DATA; - node->mode = 0771; } else if (!strcasecmp(node->name, "obb")) { /* App-specific directories inside; let anyone traverse */ node->perm = PERM_ANDROID_OBB; - node->mode = 0771; /* Single OBB directory is always shared */ node->graft_path = fuse->global->obb_path; node->graft_pathlen = strlen(fuse->global->obb_path); } else if (!strcasecmp(node->name, "media")) { /* App-specific directories inside; let anyone traverse */ node->perm = PERM_ANDROID_MEDIA; - node->mode = 0771; } break; case PERM_ANDROID_DATA: @@ -499,7 +503,6 @@ static void derive_permissions_locked(struct fuse* fuse, struct node *parent, if (appid != 0) { node->uid = multiuser_get_uid(parent->userid, appid); } - node->mode = 0770; break; } } @@ -1730,6 +1733,7 @@ static int usage() { ERROR("usage: sdcard [OPTIONS]