Home | History | Annotate | Download | only in sdcard
      1 /*
      2  * Copyright (C) 2010 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #define LOG_TAG "sdcard"
     18 
     19 #include <ctype.h>
     20 #include <dirent.h>
     21 #include <errno.h>
     22 #include <fcntl.h>
     23 #include <inttypes.h>
     24 #include <limits.h>
     25 #include <linux/fuse.h>
     26 #include <pthread.h>
     27 #include <stdio.h>
     28 #include <stdlib.h>
     29 #include <string.h>
     30 #include <sys/inotify.h>
     31 #include <sys/mount.h>
     32 #include <sys/resource.h>
     33 #include <sys/stat.h>
     34 #include <sys/statfs.h>
     35 #include <sys/time.h>
     36 #include <sys/uio.h>
     37 #include <unistd.h>
     38 
     39 #include <cutils/fs.h>
     40 #include <cutils/hashmap.h>
     41 #include <cutils/log.h>
     42 #include <cutils/multiuser.h>
     43 
     44 #include <private/android_filesystem_config.h>
     45 
     46 /* README
     47  *
     48  * What is this?
     49  *
     50  * sdcard is a program that uses FUSE to emulate FAT-on-sdcard style
     51  * directory permissions (all files are given fixed owner, group, and
     52  * permissions at creation, owner, group, and permissions are not
     53  * changeable, symlinks and hardlinks are not createable, etc.
     54  *
     55  * See usage() for command line options.
     56  *
     57  * It must be run as root, but will drop to requested UID/GID as soon as it
     58  * mounts a filesystem.  It will refuse to run if requested UID/GID are zero.
     59  *
     60  * Things I believe to be true:
     61  *
     62  * - ops that return a fuse_entry (LOOKUP, MKNOD, MKDIR, LINK, SYMLINK,
     63  * CREAT) must bump that node's refcount
     64  * - don't forget that FORGET can forget multiple references (req->nlookup)
     65  * - if an op that returns a fuse_entry fails writing the reply to the
     66  * kernel, you must rollback the refcount to reflect the reference the
     67  * kernel did not actually acquire
     68  *
     69  * This daemon can also derive custom filesystem permissions based on directory
     70  * structure when requested. These custom permissions support several features:
     71  *
     72  * - Apps can access their own files in /Android/data/com.example/ without
     73  * requiring any additional GIDs.
     74  * - Separate permissions for protecting directories like Pictures and Music.
     75  * - Multi-user separation on the same physical device.
     76  *
     77  * The derived permissions look like this:
     78  *
     79  * rwxrwx--x root:sdcard_rw     /
     80  * rwxrwx--- root:sdcard_pics   /Pictures
     81  * rwxrwx--- root:sdcard_av     /Music
     82  *
     83  * rwxrwx--x root:sdcard_rw     /Android
     84  * rwxrwx--x root:sdcard_rw     /Android/data
     85  * rwxrwx--- u0_a12:sdcard_rw   /Android/data/com.example
     86  * rwxrwx--x root:sdcard_rw     /Android/obb/
     87  * rwxrwx--- u0_a12:sdcard_rw   /Android/obb/com.example
     88  *
     89  * rwxrwx--- root:sdcard_all    /Android/user
     90  * rwxrwx--x root:sdcard_rw     /Android/user/10
     91  * rwxrwx--- u10_a12:sdcard_rw  /Android/user/10/Android/data/com.example
     92  */
     93 
     94 #define FUSE_TRACE 0
     95 
     96 #if FUSE_TRACE
     97 #define TRACE(x...) ALOGD(x)
     98 #else
     99 #define TRACE(x...) do {} while (0)
    100 #endif
    101 
    102 #define ERROR(x...) ALOGE(x)
    103 
    104 #define FUSE_UNKNOWN_INO 0xffffffff
    105 
    106 /* Maximum number of bytes to write in one request. */
    107 #define MAX_WRITE (256 * 1024)
    108 
    109 /* Maximum number of bytes to read in one request. */
    110 #define MAX_READ (128 * 1024)
    111 
    112 /* Largest possible request.
    113  * The request size is bounded by the maximum size of a FUSE_WRITE request because it has
    114  * the largest possible data payload. */
    115 #define MAX_REQUEST_SIZE (sizeof(struct fuse_in_header) + sizeof(struct fuse_write_in) + MAX_WRITE)
    116 
    117 /* Default number of threads. */
    118 #define DEFAULT_NUM_THREADS 2
    119 
    120 /* Pseudo-error constant used to indicate that no fuse status is needed
    121  * or that a reply has already been written. */
    122 #define NO_STATUS 1
    123 
    124 /* Path to system-provided mapping of package name to appIds */
    125 static const char* const kPackagesListFile = "/data/system/packages.list";
    126 
    127 /* Supplementary groups to execute with */
    128 static const gid_t kGroups[1] = { AID_PACKAGE_INFO };
    129 
    130 /* Permission mode for a specific node. Controls how file permissions
    131  * are derived for children nodes. */
    132 typedef enum {
    133     /* Nothing special; this node should just inherit from its parent. */
    134     PERM_INHERIT,
    135     /* This node is one level above a normal root; used for legacy layouts
    136      * which use the first level to represent user_id. */
    137     PERM_LEGACY_PRE_ROOT,
    138     /* This node is "/" */
    139     PERM_ROOT,
    140     /* This node is "/Android" */
    141     PERM_ANDROID,
    142     /* This node is "/Android/data" */
    143     PERM_ANDROID_DATA,
    144     /* This node is "/Android/obb" */
    145     PERM_ANDROID_OBB,
    146     /* This node is "/Android/media" */
    147     PERM_ANDROID_MEDIA,
    148     /* This node is "/Android/user" */
    149     PERM_ANDROID_USER,
    150 } perm_t;
    151 
    152 /* Permissions structure to derive */
    153 typedef enum {
    154     DERIVE_NONE,
    155     DERIVE_LEGACY,
    156     DERIVE_UNIFIED,
    157 } derive_t;
    158 
    159 struct handle {
    160     int fd;
    161 };
    162 
    163 struct dirhandle {
    164     DIR *d;
    165 };
    166 
    167 struct node {
    168     __u32 refcount;
    169     __u64 nid;
    170     __u64 gen;
    171     /*
    172      * The inode number for this FUSE node. Note that this isn't stable across
    173      * multiple invocations of the FUSE daemon.
    174      */
    175     __u32 ino;
    176 
    177     /* State derived based on current position in hierarchy. */
    178     perm_t perm;
    179     userid_t userid;
    180     uid_t uid;
    181     gid_t gid;
    182     mode_t mode;
    183 
    184     struct node *next;          /* per-dir sibling list */
    185     struct node *child;         /* first contained file by this dir */
    186     struct node *parent;        /* containing directory */
    187 
    188     size_t namelen;
    189     char *name;
    190     /* If non-null, this is the real name of the file in the underlying storage.
    191      * This may differ from the field "name" only by case.
    192      * strlen(actual_name) will always equal strlen(name), so it is safe to use
    193      * namelen for both fields.
    194      */
    195     char *actual_name;
    196 
    197     /* If non-null, an exact underlying path that should be grafted into this
    198      * position. Used to support things like OBB. */
    199     char* graft_path;
    200     size_t graft_pathlen;
    201 };
    202 
    203 static int str_hash(void *key) {
    204     return hashmapHash(key, strlen(key));
    205 }
    206 
    207 /** Test if two string keys are equal ignoring case */
    208 static bool str_icase_equals(void *keyA, void *keyB) {
    209     return strcasecmp(keyA, keyB) == 0;
    210 }
    211 
    212 static int int_hash(void *key) {
    213     return (int) (uintptr_t) key;
    214 }
    215 
    216 static bool int_equals(void *keyA, void *keyB) {
    217     return keyA == keyB;
    218 }
    219 
    220 /* Global data structure shared by all fuse handlers. */
    221 struct fuse {
    222     pthread_mutex_t lock;
    223 
    224     __u64 next_generation;
    225     int fd;
    226     derive_t derive;
    227     bool split_perms;
    228     gid_t write_gid;
    229     struct node root;
    230     char obbpath[PATH_MAX];
    231 
    232     /* Used to allocate unique inode numbers for fuse nodes. We use
    233      * a simple counter based scheme where inode numbers from deleted
    234      * nodes aren't reused. Note that inode allocations are not stable
    235      * across multiple invocation of the sdcard daemon, but that shouldn't
    236      * be a huge problem in practice.
    237      *
    238      * Note that we restrict inodes to 32 bit unsigned integers to prevent
    239      * truncation on 32 bit processes when unsigned long long stat.st_ino is
    240      * assigned to an unsigned long ino_t type in an LP32 process.
    241      *
    242      * Also note that fuse_attr and fuse_dirent inode values are 64 bits wide
    243      * on both LP32 and LP64, but the fuse kernel code doesn't squash 64 bit
    244      * inode numbers into 32 bit values on 64 bit kernels (see fuse_squash_ino
    245      * in fs/fuse/inode.c).
    246      *
    247      * Accesses must be guarded by |lock|.
    248      */
    249     __u32 inode_ctr;
    250 
    251     Hashmap* package_to_appid;
    252     Hashmap* appid_with_rw;
    253 };
    254 
    255 /* Private data used by a single fuse handler. */
    256 struct fuse_handler {
    257     struct fuse* fuse;
    258     int token;
    259 
    260     /* To save memory, we never use the contents of the request buffer and the read
    261      * buffer at the same time.  This allows us to share the underlying storage. */
    262     union {
    263         __u8 request_buffer[MAX_REQUEST_SIZE];
    264         __u8 read_buffer[MAX_READ + PAGESIZE];
    265     };
    266 };
    267 
    268 static inline void *id_to_ptr(__u64 nid)
    269 {
    270     return (void *) (uintptr_t) nid;
    271 }
    272 
    273 static inline __u64 ptr_to_id(void *ptr)
    274 {
    275     return (__u64) (uintptr_t) ptr;
    276 }
    277 
    278 static void acquire_node_locked(struct node* node)
    279 {
    280     node->refcount++;
    281     TRACE("ACQUIRE %p (%s) rc=%d\n", node, node->name, node->refcount);
    282 }
    283 
    284 static void remove_node_from_parent_locked(struct node* node);
    285 
    286 static void release_node_locked(struct node* node)
    287 {
    288     TRACE("RELEASE %p (%s) rc=%d\n", node, node->name, node->refcount);
    289     if (node->refcount > 0) {
    290         node->refcount--;
    291         if (!node->refcount) {
    292             TRACE("DESTROY %p (%s)\n", node, node->name);
    293             remove_node_from_parent_locked(node);
    294 
    295                 /* TODO: remove debugging - poison memory */
    296             memset(node->name, 0xef, node->namelen);
    297             free(node->name);
    298             free(node->actual_name);
    299             memset(node, 0xfc, sizeof(*node));
    300             free(node);
    301         }
    302     } else {
    303         ERROR("Zero refcnt %p\n", node);
    304     }
    305 }
    306 
    307 static void add_node_to_parent_locked(struct node *node, struct node *parent) {
    308     node->parent = parent;
    309     node->next = parent->child;
    310     parent->child = node;
    311     acquire_node_locked(parent);
    312 }
    313 
    314 static void remove_node_from_parent_locked(struct node* node)
    315 {
    316     if (node->parent) {
    317         if (node->parent->child == node) {
    318             node->parent->child = node->parent->child->next;
    319         } else {
    320             struct node *node2;
    321             node2 = node->parent->child;
    322             while (node2->next != node)
    323                 node2 = node2->next;
    324             node2->next = node->next;
    325         }
    326         release_node_locked(node->parent);
    327         node->parent = NULL;
    328         node->next = NULL;
    329     }
    330 }
    331 
    332 /* Gets the absolute path to a node into the provided buffer.
    333  *
    334  * Populates 'buf' with the path and returns the length of the path on success,
    335  * or returns -1 if the path is too long for the provided buffer.
    336  */
    337 static ssize_t get_node_path_locked(struct node* node, char* buf, size_t bufsize) {
    338     const char* name;
    339     size_t namelen;
    340     if (node->graft_path) {
    341         name = node->graft_path;
    342         namelen = node->graft_pathlen;
    343     } else if (node->actual_name) {
    344         name = node->actual_name;
    345         namelen = node->namelen;
    346     } else {
    347         name = node->name;
    348         namelen = node->namelen;
    349     }
    350 
    351     if (bufsize < namelen + 1) {
    352         return -1;
    353     }
    354 
    355     ssize_t pathlen = 0;
    356     if (node->parent && node->graft_path == NULL) {
    357         pathlen = get_node_path_locked(node->parent, buf, bufsize - namelen - 2);
    358         if (pathlen < 0) {
    359             return -1;
    360         }
    361         buf[pathlen++] = '/';
    362     }
    363 
    364     memcpy(buf + pathlen, name, namelen + 1); /* include trailing \0 */
    365     return pathlen + namelen;
    366 }
    367 
    368 /* Finds the absolute path of a file within a given directory.
    369  * Performs a case-insensitive search for the file and sets the buffer to the path
    370  * of the first matching file.  If 'search' is zero or if no match is found, sets
    371  * the buffer to the path that the file would have, assuming the name were case-sensitive.
    372  *
    373  * Populates 'buf' with the path and returns the actual name (within 'buf') on success,
    374  * or returns NULL if the path is too long for the provided buffer.
    375  */
    376 static char* find_file_within(const char* path, const char* name,
    377         char* buf, size_t bufsize, int search)
    378 {
    379     size_t pathlen = strlen(path);
    380     size_t namelen = strlen(name);
    381     size_t childlen = pathlen + namelen + 1;
    382     char* actual;
    383 
    384     if (bufsize <= childlen) {
    385         return NULL;
    386     }
    387 
    388     memcpy(buf, path, pathlen);
    389     buf[pathlen] = '/';
    390     actual = buf + pathlen + 1;
    391     memcpy(actual, name, namelen + 1);
    392 
    393     if (search && access(buf, F_OK)) {
    394         struct dirent* entry;
    395         DIR* dir = opendir(path);
    396         if (!dir) {
    397             ERROR("opendir %s failed: %s\n", path, strerror(errno));
    398             return actual;
    399         }
    400         while ((entry = readdir(dir))) {
    401             if (!strcasecmp(entry->d_name, name)) {
    402                 /* we have a match - replace the name, don't need to copy the null again */
    403                 memcpy(actual, entry->d_name, namelen);
    404                 break;
    405             }
    406         }
    407         closedir(dir);
    408     }
    409     return actual;
    410 }
    411 
    412 static void attr_from_stat(struct fuse_attr *attr, const struct stat *s, const struct node* node)
    413 {
    414     attr->ino = node->ino;
    415     attr->size = s->st_size;
    416     attr->blocks = s->st_blocks;
    417     attr->atime = s->st_atime;
    418     attr->mtime = s->st_mtime;
    419     attr->ctime = s->st_ctime;
    420     attr->atimensec = s->st_atime_nsec;
    421     attr->mtimensec = s->st_mtime_nsec;
    422     attr->ctimensec = s->st_ctime_nsec;
    423     attr->mode = s->st_mode;
    424     attr->nlink = s->st_nlink;
    425 
    426     attr->uid = node->uid;
    427     attr->gid = node->gid;
    428 
    429     /* Filter requested mode based on underlying file, and
    430      * pass through file type. */
    431     int owner_mode = s->st_mode & 0700;
    432     int filtered_mode = node->mode & (owner_mode | (owner_mode >> 3) | (owner_mode >> 6));
    433     attr->mode = (attr->mode & S_IFMT) | filtered_mode;
    434 }
    435 
    436 static int touch(char* path, mode_t mode) {
    437     int fd = open(path, O_RDWR | O_CREAT | O_EXCL | O_NOFOLLOW, mode);
    438     if (fd == -1) {
    439         if (errno == EEXIST) {
    440             return 0;
    441         } else {
    442             ERROR("Failed to open(%s): %s\n", path, strerror(errno));
    443             return -1;
    444         }
    445     }
    446     close(fd);
    447     return 0;
    448 }
    449 
    450 static void derive_permissions_locked(struct fuse* fuse, struct node *parent,
    451         struct node *node) {
    452     appid_t appid;
    453 
    454     /* By default, each node inherits from its parent */
    455     node->perm = PERM_INHERIT;
    456     node->userid = parent->userid;
    457     node->uid = parent->uid;
    458     node->gid = parent->gid;
    459     node->mode = parent->mode;
    460 
    461     if (fuse->derive == DERIVE_NONE) {
    462         return;
    463     }
    464 
    465     /* Derive custom permissions based on parent and current node */
    466     switch (parent->perm) {
    467     case PERM_INHERIT:
    468         /* Already inherited above */
    469         break;
    470     case PERM_LEGACY_PRE_ROOT:
    471         /* Legacy internal layout places users at top level */
    472         node->perm = PERM_ROOT;
    473         node->userid = strtoul(node->name, NULL, 10);
    474         break;
    475     case PERM_ROOT:
    476         /* Assume masked off by default. */
    477         node->mode = 0770;
    478         if (!strcasecmp(node->name, "Android")) {
    479             /* App-specific directories inside; let anyone traverse */
    480             node->perm = PERM_ANDROID;
    481             node->mode = 0771;
    482         } else if (fuse->split_perms) {
    483             if (!strcasecmp(node->name, "DCIM")
    484                     || !strcasecmp(node->name, "Pictures")) {
    485                 node->gid = AID_SDCARD_PICS;
    486             } else if (!strcasecmp(node->name, "Alarms")
    487                     || !strcasecmp(node->name, "Movies")
    488                     || !strcasecmp(node->name, "Music")
    489                     || !strcasecmp(node->name, "Notifications")
    490                     || !strcasecmp(node->name, "Podcasts")
    491                     || !strcasecmp(node->name, "Ringtones")) {
    492                 node->gid = AID_SDCARD_AV;
    493             }
    494         }
    495         break;
    496     case PERM_ANDROID:
    497         if (!strcasecmp(node->name, "data")) {
    498             /* App-specific directories inside; let anyone traverse */
    499             node->perm = PERM_ANDROID_DATA;
    500             node->mode = 0771;
    501         } else if (!strcasecmp(node->name, "obb")) {
    502             /* App-specific directories inside; let anyone traverse */
    503             node->perm = PERM_ANDROID_OBB;
    504             node->mode = 0771;
    505             /* Single OBB directory is always shared */
    506             node->graft_path = fuse->obbpath;
    507             node->graft_pathlen = strlen(fuse->obbpath);
    508         } else if (!strcasecmp(node->name, "media")) {
    509             /* App-specific directories inside; let anyone traverse */
    510             node->perm = PERM_ANDROID_MEDIA;
    511             node->mode = 0771;
    512         } else if (!strcasecmp(node->name, "user")) {
    513             /* User directories must only be accessible to system, protected
    514              * by sdcard_all. Zygote will bind mount the appropriate user-
    515              * specific path. */
    516             node->perm = PERM_ANDROID_USER;
    517             node->gid = AID_SDCARD_ALL;
    518             node->mode = 0770;
    519         }
    520         break;
    521     case PERM_ANDROID_DATA:
    522     case PERM_ANDROID_OBB:
    523     case PERM_ANDROID_MEDIA:
    524         appid = (appid_t) (uintptr_t) hashmapGet(fuse->package_to_appid, node->name);
    525         if (appid != 0) {
    526             node->uid = multiuser_get_uid(parent->userid, appid);
    527         }
    528         node->mode = 0770;
    529         break;
    530     case PERM_ANDROID_USER:
    531         /* Root of a secondary user */
    532         node->perm = PERM_ROOT;
    533         node->userid = strtoul(node->name, NULL, 10);
    534         node->gid = AID_SDCARD_R;
    535         node->mode = 0771;
    536         break;
    537     }
    538 }
    539 
    540 /* Return if the calling UID holds sdcard_rw. */
    541 static bool get_caller_has_rw_locked(struct fuse* fuse, const struct fuse_in_header *hdr) {
    542     /* No additional permissions enforcement */
    543     if (fuse->derive == DERIVE_NONE) {
    544         return true;
    545     }
    546 
    547     appid_t appid = multiuser_get_app_id(hdr->uid);
    548     return hashmapContainsKey(fuse->appid_with_rw, (void*) (uintptr_t) appid);
    549 }
    550 
    551 /* Kernel has already enforced everything we returned through
    552  * derive_permissions_locked(), so this is used to lock down access
    553  * even further, such as enforcing that apps hold sdcard_rw. */
    554 static bool check_caller_access_to_name(struct fuse* fuse,
    555         const struct fuse_in_header *hdr, const struct node* parent_node,
    556         const char* name, int mode, bool has_rw) {
    557     /* Always block security-sensitive files at root */
    558     if (parent_node && parent_node->perm == PERM_ROOT) {
    559         if (!strcasecmp(name, "autorun.inf")
    560                 || !strcasecmp(name, ".android_secure")
    561                 || !strcasecmp(name, "android_secure")) {
    562             return false;
    563         }
    564     }
    565 
    566     /* No additional permissions enforcement */
    567     if (fuse->derive == DERIVE_NONE) {
    568         return true;
    569     }
    570 
    571     /* Root always has access; access for any other UIDs should always
    572      * be controlled through packages.list. */
    573     if (hdr->uid == 0) {
    574         return true;
    575     }
    576 
    577     /* If asking to write, verify that caller either owns the
    578      * parent or holds sdcard_rw. */
    579     if (mode & W_OK) {
    580         if (parent_node && hdr->uid == parent_node->uid) {
    581             return true;
    582         }
    583 
    584         return has_rw;
    585     }
    586 
    587     /* No extra permissions to enforce */
    588     return true;
    589 }
    590 
    591 static bool check_caller_access_to_node(struct fuse* fuse,
    592         const struct fuse_in_header *hdr, const struct node* node, int mode, bool has_rw) {
    593     return check_caller_access_to_name(fuse, hdr, node->parent, node->name, mode, has_rw);
    594 }
    595 
    596 struct node *create_node_locked(struct fuse* fuse,
    597         struct node *parent, const char *name, const char* actual_name)
    598 {
    599     struct node *node;
    600     size_t namelen = strlen(name);
    601 
    602     // Detect overflows in the inode counter. "4 billion nodes should be enough
    603     // for everybody".
    604     if (fuse->inode_ctr == 0) {
    605         ERROR("No more inode numbers available");
    606         return NULL;
    607     }
    608 
    609     node = calloc(1, sizeof(struct node));
    610     if (!node) {
    611         return NULL;
    612     }
    613     node->name = malloc(namelen + 1);
    614     if (!node->name) {
    615         free(node);
    616         return NULL;
    617     }
    618     memcpy(node->name, name, namelen + 1);
    619     if (strcmp(name, actual_name)) {
    620         node->actual_name = malloc(namelen + 1);
    621         if (!node->actual_name) {
    622             free(node->name);
    623             free(node);
    624             return NULL;
    625         }
    626         memcpy(node->actual_name, actual_name, namelen + 1);
    627     }
    628     node->namelen = namelen;
    629     node->nid = ptr_to_id(node);
    630     node->ino = fuse->inode_ctr++;
    631     node->gen = fuse->next_generation++;
    632 
    633     derive_permissions_locked(fuse, parent, node);
    634     acquire_node_locked(node);
    635     add_node_to_parent_locked(node, parent);
    636     return node;
    637 }
    638 
    639 static int rename_node_locked(struct node *node, const char *name,
    640         const char* actual_name)
    641 {
    642     size_t namelen = strlen(name);
    643     int need_actual_name = strcmp(name, actual_name);
    644 
    645     /* make the storage bigger without actually changing the name
    646      * in case an error occurs part way */
    647     if (namelen > node->namelen) {
    648         char* new_name = realloc(node->name, namelen + 1);
    649         if (!new_name) {
    650             return -ENOMEM;
    651         }
    652         node->name = new_name;
    653         if (need_actual_name && node->actual_name) {
    654             char* new_actual_name = realloc(node->actual_name, namelen + 1);
    655             if (!new_actual_name) {
    656                 return -ENOMEM;
    657             }
    658             node->actual_name = new_actual_name;
    659         }
    660     }
    661 
    662     /* update the name, taking care to allocate storage before overwriting the old name */
    663     if (need_actual_name) {
    664         if (!node->actual_name) {
    665             node->actual_name = malloc(namelen + 1);
    666             if (!node->actual_name) {
    667                 return -ENOMEM;
    668             }
    669         }
    670         memcpy(node->actual_name, actual_name, namelen + 1);
    671     } else {
    672         free(node->actual_name);
    673         node->actual_name = NULL;
    674     }
    675     memcpy(node->name, name, namelen + 1);
    676     node->namelen = namelen;
    677     return 0;
    678 }
    679 
    680 static struct node *lookup_node_by_id_locked(struct fuse *fuse, __u64 nid)
    681 {
    682     if (nid == FUSE_ROOT_ID) {
    683         return &fuse->root;
    684     } else {
    685         return id_to_ptr(nid);
    686     }
    687 }
    688 
    689 static struct node* lookup_node_and_path_by_id_locked(struct fuse* fuse, __u64 nid,
    690         char* buf, size_t bufsize)
    691 {
    692     struct node* node = lookup_node_by_id_locked(fuse, nid);
    693     if (node && get_node_path_locked(node, buf, bufsize) < 0) {
    694         node = NULL;
    695     }
    696     return node;
    697 }
    698 
    699 static struct node *lookup_child_by_name_locked(struct node *node, const char *name)
    700 {
    701     for (node = node->child; node; node = node->next) {
    702         /* use exact string comparison, nodes that differ by case
    703          * must be considered distinct even if they refer to the same
    704          * underlying file as otherwise operations such as "mv x x"
    705          * will not work because the source and target nodes are the same. */
    706         if (!strcmp(name, node->name)) {
    707             return node;
    708         }
    709     }
    710     return 0;
    711 }
    712 
    713 static struct node* acquire_or_create_child_locked(
    714         struct fuse* fuse, struct node* parent,
    715         const char* name, const char* actual_name)
    716 {
    717     struct node* child = lookup_child_by_name_locked(parent, name);
    718     if (child) {
    719         acquire_node_locked(child);
    720     } else {
    721         child = create_node_locked(fuse, parent, name, actual_name);
    722     }
    723     return child;
    724 }
    725 
    726 static void fuse_init(struct fuse *fuse, int fd, const char *source_path,
    727         gid_t write_gid, derive_t derive, bool split_perms) {
    728     pthread_mutex_init(&fuse->lock, NULL);
    729 
    730     fuse->fd = fd;
    731     fuse->next_generation = 0;
    732     fuse->derive = derive;
    733     fuse->split_perms = split_perms;
    734     fuse->write_gid = write_gid;
    735     fuse->inode_ctr = 1;
    736 
    737     memset(&fuse->root, 0, sizeof(fuse->root));
    738     fuse->root.nid = FUSE_ROOT_ID; /* 1 */
    739     fuse->root.refcount = 2;
    740     fuse->root.namelen = strlen(source_path);
    741     fuse->root.name = strdup(source_path);
    742     fuse->root.userid = 0;
    743     fuse->root.uid = AID_ROOT;
    744 
    745     /* Set up root node for various modes of operation */
    746     switch (derive) {
    747     case DERIVE_NONE:
    748         /* Traditional behavior that treats entire device as being accessible
    749          * to sdcard_rw, and no permissions are derived. */
    750         fuse->root.perm = PERM_ROOT;
    751         fuse->root.mode = 0775;
    752         fuse->root.gid = AID_SDCARD_RW;
    753         break;
    754     case DERIVE_LEGACY:
    755         /* Legacy behavior used to support internal multiuser layout which
    756          * places user_id at the top directory level, with the actual roots
    757          * just below that. Shared OBB path is also at top level. */
    758         fuse->root.perm = PERM_LEGACY_PRE_ROOT;
    759         fuse->root.mode = 0771;
    760         fuse->root.gid = AID_SDCARD_R;
    761         fuse->package_to_appid = hashmapCreate(256, str_hash, str_icase_equals);
    762         fuse->appid_with_rw = hashmapCreate(128, int_hash, int_equals);
    763         snprintf(fuse->obbpath, sizeof(fuse->obbpath), "%s/obb", source_path);
    764         fs_prepare_dir(fuse->obbpath, 0775, getuid(), getgid());
    765         break;
    766     case DERIVE_UNIFIED:
    767         /* Unified multiuser layout which places secondary user_id under
    768          * /Android/user and shared OBB path under /Android/obb. */
    769         fuse->root.perm = PERM_ROOT;
    770         fuse->root.mode = 0771;
    771         fuse->root.gid = AID_SDCARD_R;
    772         fuse->package_to_appid = hashmapCreate(256, str_hash, str_icase_equals);
    773         fuse->appid_with_rw = hashmapCreate(128, int_hash, int_equals);
    774         snprintf(fuse->obbpath, sizeof(fuse->obbpath), "%s/Android/obb", source_path);
    775         break;
    776     }
    777 }
    778 
    779 static void fuse_status(struct fuse *fuse, __u64 unique, int err)
    780 {
    781     struct fuse_out_header hdr;
    782     hdr.len = sizeof(hdr);
    783     hdr.error = err;
    784     hdr.unique = unique;
    785     write(fuse->fd, &hdr, sizeof(hdr));
    786 }
    787 
    788 static void fuse_reply(struct fuse *fuse, __u64 unique, void *data, int len)
    789 {
    790     struct fuse_out_header hdr;
    791     struct iovec vec[2];
    792     int res;
    793 
    794     hdr.len = len + sizeof(hdr);
    795     hdr.error = 0;
    796     hdr.unique = unique;
    797 
    798     vec[0].iov_base = &hdr;
    799     vec[0].iov_len = sizeof(hdr);
    800     vec[1].iov_base = data;
    801     vec[1].iov_len = len;
    802 
    803     res = writev(fuse->fd, vec, 2);
    804     if (res < 0) {
    805         ERROR("*** REPLY FAILED *** %d\n", errno);
    806     }
    807 }
    808 
    809 static int fuse_reply_entry(struct fuse* fuse, __u64 unique,
    810         struct node* parent, const char* name, const char* actual_name,
    811         const char* path)
    812 {
    813     struct node* node;
    814     struct fuse_entry_out out;
    815     struct stat s;
    816 
    817     if (lstat(path, &s) < 0) {
    818         return -errno;
    819     }
    820 
    821     pthread_mutex_lock(&fuse->lock);
    822     node = acquire_or_create_child_locked(fuse, parent, name, actual_name);
    823     if (!node) {
    824         pthread_mutex_unlock(&fuse->lock);
    825         return -ENOMEM;
    826     }
    827     memset(&out, 0, sizeof(out));
    828     attr_from_stat(&out.attr, &s, node);
    829     out.attr_valid = 10;
    830     out.entry_valid = 10;
    831     out.nodeid = node->nid;
    832     out.generation = node->gen;
    833     pthread_mutex_unlock(&fuse->lock);
    834     fuse_reply(fuse, unique, &out, sizeof(out));
    835     return NO_STATUS;
    836 }
    837 
    838 static int fuse_reply_attr(struct fuse* fuse, __u64 unique, const struct node* node,
    839         const char* path)
    840 {
    841     struct fuse_attr_out out;
    842     struct stat s;
    843 
    844     if (lstat(path, &s) < 0) {
    845         return -errno;
    846     }
    847     memset(&out, 0, sizeof(out));
    848     attr_from_stat(&out.attr, &s, node);
    849     out.attr_valid = 10;
    850     fuse_reply(fuse, unique, &out, sizeof(out));
    851     return NO_STATUS;
    852 }
    853 
    854 static int handle_lookup(struct fuse* fuse, struct fuse_handler* handler,
    855         const struct fuse_in_header *hdr, const char* name)
    856 {
    857     struct node* parent_node;
    858     char parent_path[PATH_MAX];
    859     char child_path[PATH_MAX];
    860     const char* actual_name;
    861 
    862     pthread_mutex_lock(&fuse->lock);
    863     parent_node = lookup_node_and_path_by_id_locked(fuse, hdr->nodeid,
    864             parent_path, sizeof(parent_path));
    865     TRACE("[%d] LOOKUP %s @ %"PRIx64" (%s)\n", handler->token, name, hdr->nodeid,
    866         parent_node ? parent_node->name : "?");
    867     pthread_mutex_unlock(&fuse->lock);
    868 
    869     if (!parent_node || !(actual_name = find_file_within(parent_path, name,
    870             child_path, sizeof(child_path), 1))) {
    871         return -ENOENT;
    872     }
    873     if (!check_caller_access_to_name(fuse, hdr, parent_node, name, R_OK, false)) {
    874         return -EACCES;
    875     }
    876 
    877     return fuse_reply_entry(fuse, hdr->unique, parent_node, name, actual_name, child_path);
    878 }
    879 
    880 static int handle_forget(struct fuse* fuse, struct fuse_handler* handler,
    881         const struct fuse_in_header *hdr, const struct fuse_forget_in *req)
    882 {
    883     struct node* node;
    884 
    885     pthread_mutex_lock(&fuse->lock);
    886     node = lookup_node_by_id_locked(fuse, hdr->nodeid);
    887     TRACE("[%d] FORGET #%"PRIu64" @ %"PRIx64" (%s)\n", handler->token, req->nlookup,
    888             hdr->nodeid, node ? node->name : "?");
    889     if (node) {
    890         __u64 n = req->nlookup;
    891         while (n--) {
    892             release_node_locked(node);
    893         }
    894     }
    895     pthread_mutex_unlock(&fuse->lock);
    896     return NO_STATUS; /* no reply */
    897 }
    898 
    899 static int handle_getattr(struct fuse* fuse, struct fuse_handler* handler,
    900         const struct fuse_in_header *hdr, const struct fuse_getattr_in *req)
    901 {
    902     struct node* node;
    903     char path[PATH_MAX];
    904 
    905     pthread_mutex_lock(&fuse->lock);
    906     node = lookup_node_and_path_by_id_locked(fuse, hdr->nodeid, path, sizeof(path));
    907     TRACE("[%d] GETATTR flags=%x fh=%"PRIx64" @ %"PRIx64" (%s)\n", handler->token,
    908             req->getattr_flags, req->fh, hdr->nodeid, node ? node->name : "?");
    909     pthread_mutex_unlock(&fuse->lock);
    910 
    911     if (!node) {
    912         return -ENOENT;
    913     }
    914     if (!check_caller_access_to_node(fuse, hdr, node, R_OK, false)) {
    915         return -EACCES;
    916     }
    917 
    918     return fuse_reply_attr(fuse, hdr->unique, node, path);
    919 }
    920 
    921 static int handle_setattr(struct fuse* fuse, struct fuse_handler* handler,
    922         const struct fuse_in_header *hdr, const struct fuse_setattr_in *req)
    923 {
    924     bool has_rw;
    925     struct node* node;
    926     char path[PATH_MAX];
    927     struct timespec times[2];
    928 
    929     pthread_mutex_lock(&fuse->lock);
    930     has_rw = get_caller_has_rw_locked(fuse, hdr);
    931     node = lookup_node_and_path_by_id_locked(fuse, hdr->nodeid, path, sizeof(path));
    932     TRACE("[%d] SETATTR fh=%"PRIx64" valid=%x @ %"PRIx64" (%s)\n", handler->token,
    933             req->fh, req->valid, hdr->nodeid, node ? node->name : "?");
    934     pthread_mutex_unlock(&fuse->lock);
    935 
    936     if (!node) {
    937         return -ENOENT;
    938     }
    939     if (!check_caller_access_to_node(fuse, hdr, node, W_OK, has_rw)) {
    940         return -EACCES;
    941     }
    942 
    943     /* XXX: incomplete implementation on purpose.
    944      * chmod/chown should NEVER be implemented.*/
    945 
    946     if ((req->valid & FATTR_SIZE) && truncate64(path, req->size) < 0) {
    947         return -errno;
    948     }
    949 
    950     /* Handle changing atime and mtime.  If FATTR_ATIME_and FATTR_ATIME_NOW
    951      * are both set, then set it to the current time.  Else, set it to the
    952      * time specified in the request.  Same goes for mtime.  Use utimensat(2)
    953      * as it allows ATIME and MTIME to be changed independently, and has
    954      * nanosecond resolution which fuse also has.
    955      */
    956     if (req->valid & (FATTR_ATIME | FATTR_MTIME)) {
    957         times[0].tv_nsec = UTIME_OMIT;
    958         times[1].tv_nsec = UTIME_OMIT;
    959         if (req->valid & FATTR_ATIME) {
    960             if (req->valid & FATTR_ATIME_NOW) {
    961               times[0].tv_nsec = UTIME_NOW;
    962             } else {
    963               times[0].tv_sec = req->atime;
    964               times[0].tv_nsec = req->atimensec;
    965             }
    966         }
    967         if (req->valid & FATTR_MTIME) {
    968             if (req->valid & FATTR_MTIME_NOW) {
    969               times[1].tv_nsec = UTIME_NOW;
    970             } else {
    971               times[1].tv_sec = req->mtime;
    972               times[1].tv_nsec = req->mtimensec;
    973             }
    974         }
    975         TRACE("[%d] Calling utimensat on %s with atime %ld, mtime=%ld\n",
    976                 handler->token, path, times[0].tv_sec, times[1].tv_sec);
    977         if (utimensat(-1, path, times, 0) < 0) {
    978             return -errno;
    979         }
    980     }
    981     return fuse_reply_attr(fuse, hdr->unique, node, path);
    982 }
    983 
    984 static int handle_mknod(struct fuse* fuse, struct fuse_handler* handler,
    985         const struct fuse_in_header* hdr, const struct fuse_mknod_in* req, const char* name)
    986 {
    987     bool has_rw;
    988     struct node* parent_node;
    989     char parent_path[PATH_MAX];
    990     char child_path[PATH_MAX];
    991     const char* actual_name;
    992 
    993     pthread_mutex_lock(&fuse->lock);
    994     has_rw = get_caller_has_rw_locked(fuse, hdr);
    995     parent_node = lookup_node_and_path_by_id_locked(fuse, hdr->nodeid,
    996             parent_path, sizeof(parent_path));
    997     TRACE("[%d] MKNOD %s 0%o @ %"PRIx64" (%s)\n", handler->token,
    998             name, req->mode, hdr->nodeid, parent_node ? parent_node->name : "?");
    999     pthread_mutex_unlock(&fuse->lock);
   1000 
   1001     if (!parent_node || !(actual_name = find_file_within(parent_path, name,
   1002             child_path, sizeof(child_path), 1))) {
   1003         return -ENOENT;
   1004     }
   1005     if (!check_caller_access_to_name(fuse, hdr, parent_node, name, W_OK, has_rw)) {
   1006         return -EACCES;
   1007     }
   1008     __u32 mode = (req->mode & (~0777)) | 0664;
   1009     if (mknod(child_path, mode, req->rdev) < 0) {
   1010         return -errno;
   1011     }
   1012     return fuse_reply_entry(fuse, hdr->unique, parent_node, name, actual_name, child_path);
   1013 }
   1014 
   1015 static int handle_mkdir(struct fuse* fuse, struct fuse_handler* handler,
   1016         const struct fuse_in_header* hdr, const struct fuse_mkdir_in* req, const char* name)
   1017 {
   1018     bool has_rw;
   1019     struct node* parent_node;
   1020     char parent_path[PATH_MAX];
   1021     char child_path[PATH_MAX];
   1022     const char* actual_name;
   1023 
   1024     pthread_mutex_lock(&fuse->lock);
   1025     has_rw = get_caller_has_rw_locked(fuse, hdr);
   1026     parent_node = lookup_node_and_path_by_id_locked(fuse, hdr->nodeid,
   1027             parent_path, sizeof(parent_path));
   1028     TRACE("[%d] MKDIR %s 0%o @ %"PRIx64" (%s)\n", handler->token,
   1029             name, req->mode, hdr->nodeid, parent_node ? parent_node->name : "?");
   1030     pthread_mutex_unlock(&fuse->lock);
   1031 
   1032     if (!parent_node || !(actual_name = find_file_within(parent_path, name,
   1033             child_path, sizeof(child_path), 1))) {
   1034         return -ENOENT;
   1035     }
   1036     if (!check_caller_access_to_name(fuse, hdr, parent_node, name, W_OK, has_rw)) {
   1037         return -EACCES;
   1038     }
   1039     __u32 mode = (req->mode & (~0777)) | 0775;
   1040     if (mkdir(child_path, mode) < 0) {
   1041         return -errno;
   1042     }
   1043 
   1044     /* When creating /Android/data and /Android/obb, mark them as .nomedia */
   1045     if (parent_node->perm == PERM_ANDROID && !strcasecmp(name, "data")) {
   1046         char nomedia[PATH_MAX];
   1047         snprintf(nomedia, PATH_MAX, "%s/.nomedia", child_path);
   1048         if (touch(nomedia, 0664) != 0) {
   1049             ERROR("Failed to touch(%s): %s\n", nomedia, strerror(errno));
   1050             return -ENOENT;
   1051         }
   1052     }
   1053     if (parent_node->perm == PERM_ANDROID && !strcasecmp(name, "obb")) {
   1054         char nomedia[PATH_MAX];
   1055         snprintf(nomedia, PATH_MAX, "%s/.nomedia", fuse->obbpath);
   1056         if (touch(nomedia, 0664) != 0) {
   1057             ERROR("Failed to touch(%s): %s\n", nomedia, strerror(errno));
   1058             return -ENOENT;
   1059         }
   1060     }
   1061 
   1062     return fuse_reply_entry(fuse, hdr->unique, parent_node, name, actual_name, child_path);
   1063 }
   1064 
   1065 static int handle_unlink(struct fuse* fuse, struct fuse_handler* handler,
   1066         const struct fuse_in_header* hdr, const char* name)
   1067 {
   1068     bool has_rw;
   1069     struct node* parent_node;
   1070     char parent_path[PATH_MAX];
   1071     char child_path[PATH_MAX];
   1072 
   1073     pthread_mutex_lock(&fuse->lock);
   1074     has_rw = get_caller_has_rw_locked(fuse, hdr);
   1075     parent_node = lookup_node_and_path_by_id_locked(fuse, hdr->nodeid,
   1076             parent_path, sizeof(parent_path));
   1077     TRACE("[%d] UNLINK %s @ %"PRIx64" (%s)\n", handler->token,
   1078             name, hdr->nodeid, parent_node ? parent_node->name : "?");
   1079     pthread_mutex_unlock(&fuse->lock);
   1080 
   1081     if (!parent_node || !find_file_within(parent_path, name,
   1082             child_path, sizeof(child_path), 1)) {
   1083         return -ENOENT;
   1084     }
   1085     if (!check_caller_access_to_name(fuse, hdr, parent_node, name, W_OK, has_rw)) {
   1086         return -EACCES;
   1087     }
   1088     if (unlink(child_path) < 0) {
   1089         return -errno;
   1090     }
   1091     return 0;
   1092 }
   1093 
   1094 static int handle_rmdir(struct fuse* fuse, struct fuse_handler* handler,
   1095         const struct fuse_in_header* hdr, const char* name)
   1096 {
   1097     bool has_rw;
   1098     struct node* parent_node;
   1099     char parent_path[PATH_MAX];
   1100     char child_path[PATH_MAX];
   1101 
   1102     pthread_mutex_lock(&fuse->lock);
   1103     has_rw = get_caller_has_rw_locked(fuse, hdr);
   1104     parent_node = lookup_node_and_path_by_id_locked(fuse, hdr->nodeid,
   1105             parent_path, sizeof(parent_path));
   1106     TRACE("[%d] RMDIR %s @ %"PRIx64" (%s)\n", handler->token,
   1107             name, hdr->nodeid, parent_node ? parent_node->name : "?");
   1108     pthread_mutex_unlock(&fuse->lock);
   1109 
   1110     if (!parent_node || !find_file_within(parent_path, name,
   1111             child_path, sizeof(child_path), 1)) {
   1112         return -ENOENT;
   1113     }
   1114     if (!check_caller_access_to_name(fuse, hdr, parent_node, name, W_OK, has_rw)) {
   1115         return -EACCES;
   1116     }
   1117     if (rmdir(child_path) < 0) {
   1118         return -errno;
   1119     }
   1120     return 0;
   1121 }
   1122 
   1123 static int handle_rename(struct fuse* fuse, struct fuse_handler* handler,
   1124         const struct fuse_in_header* hdr, const struct fuse_rename_in* req,
   1125         const char* old_name, const char* new_name)
   1126 {
   1127     bool has_rw;
   1128     struct node* old_parent_node;
   1129     struct node* new_parent_node;
   1130     struct node* child_node;
   1131     char old_parent_path[PATH_MAX];
   1132     char new_parent_path[PATH_MAX];
   1133     char old_child_path[PATH_MAX];
   1134     char new_child_path[PATH_MAX];
   1135     const char* new_actual_name;
   1136     int res;
   1137 
   1138     pthread_mutex_lock(&fuse->lock);
   1139     has_rw = get_caller_has_rw_locked(fuse, hdr);
   1140     old_parent_node = lookup_node_and_path_by_id_locked(fuse, hdr->nodeid,
   1141             old_parent_path, sizeof(old_parent_path));
   1142     new_parent_node = lookup_node_and_path_by_id_locked(fuse, req->newdir,
   1143             new_parent_path, sizeof(new_parent_path));
   1144     TRACE("[%d] RENAME %s->%s @ %"PRIx64" (%s) -> %"PRIx64" (%s)\n", handler->token,
   1145             old_name, new_name,
   1146             hdr->nodeid, old_parent_node ? old_parent_node->name : "?",
   1147             req->newdir, new_parent_node ? new_parent_node->name : "?");
   1148     if (!old_parent_node || !new_parent_node) {
   1149         res = -ENOENT;
   1150         goto lookup_error;
   1151     }
   1152     if (!check_caller_access_to_name(fuse, hdr, old_parent_node, old_name, W_OK, has_rw)) {
   1153         res = -EACCES;
   1154         goto lookup_error;
   1155     }
   1156     if (!check_caller_access_to_name(fuse, hdr, new_parent_node, new_name, W_OK, has_rw)) {
   1157         res = -EACCES;
   1158         goto lookup_error;
   1159     }
   1160     child_node = lookup_child_by_name_locked(old_parent_node, old_name);
   1161     if (!child_node || get_node_path_locked(child_node,
   1162             old_child_path, sizeof(old_child_path)) < 0) {
   1163         res = -ENOENT;
   1164         goto lookup_error;
   1165     }
   1166     acquire_node_locked(child_node);
   1167     pthread_mutex_unlock(&fuse->lock);
   1168 
   1169     /* Special case for renaming a file where destination is same path
   1170      * differing only by case.  In this case we don't want to look for a case
   1171      * insensitive match.  This allows commands like "mv foo FOO" to work as expected.
   1172      */
   1173     int search = old_parent_node != new_parent_node
   1174             || strcasecmp(old_name, new_name);
   1175     if (!(new_actual_name = find_file_within(new_parent_path, new_name,
   1176             new_child_path, sizeof(new_child_path), search))) {
   1177         res = -ENOENT;
   1178         goto io_error;
   1179     }
   1180 
   1181     TRACE("[%d] RENAME %s->%s\n", handler->token, old_child_path, new_child_path);
   1182     res = rename(old_child_path, new_child_path);
   1183     if (res < 0) {
   1184         res = -errno;
   1185         goto io_error;
   1186     }
   1187 
   1188     pthread_mutex_lock(&fuse->lock);
   1189     res = rename_node_locked(child_node, new_name, new_actual_name);
   1190     if (!res) {
   1191         remove_node_from_parent_locked(child_node);
   1192         add_node_to_parent_locked(child_node, new_parent_node);
   1193     }
   1194     goto done;
   1195 
   1196 io_error:
   1197     pthread_mutex_lock(&fuse->lock);
   1198 done:
   1199     release_node_locked(child_node);
   1200 lookup_error:
   1201     pthread_mutex_unlock(&fuse->lock);
   1202     return res;
   1203 }
   1204 
   1205 static int open_flags_to_access_mode(int open_flags) {
   1206     if ((open_flags & O_ACCMODE) == O_RDONLY) {
   1207         return R_OK;
   1208     } else if ((open_flags & O_ACCMODE) == O_WRONLY) {
   1209         return W_OK;
   1210     } else {
   1211         /* Probably O_RDRW, but treat as default to be safe */
   1212         return R_OK | W_OK;
   1213     }
   1214 }
   1215 
   1216 static int handle_open(struct fuse* fuse, struct fuse_handler* handler,
   1217         const struct fuse_in_header* hdr, const struct fuse_open_in* req)
   1218 {
   1219     bool has_rw;
   1220     struct node* node;
   1221     char path[PATH_MAX];
   1222     struct fuse_open_out out;
   1223     struct handle *h;
   1224 
   1225     pthread_mutex_lock(&fuse->lock);
   1226     has_rw = get_caller_has_rw_locked(fuse, hdr);
   1227     node = lookup_node_and_path_by_id_locked(fuse, hdr->nodeid, path, sizeof(path));
   1228     TRACE("[%d] OPEN 0%o @ %"PRIx64" (%s)\n", handler->token,
   1229             req->flags, hdr->nodeid, node ? node->name : "?");
   1230     pthread_mutex_unlock(&fuse->lock);
   1231 
   1232     if (!node) {
   1233         return -ENOENT;
   1234     }
   1235     if (!check_caller_access_to_node(fuse, hdr, node,
   1236             open_flags_to_access_mode(req->flags), has_rw)) {
   1237         return -EACCES;
   1238     }
   1239     h = malloc(sizeof(*h));
   1240     if (!h) {
   1241         return -ENOMEM;
   1242     }
   1243     TRACE("[%d] OPEN %s\n", handler->token, path);
   1244     h->fd = open(path, req->flags);
   1245     if (h->fd < 0) {
   1246         free(h);
   1247         return -errno;
   1248     }
   1249     out.fh = ptr_to_id(h);
   1250     out.open_flags = 0;
   1251     out.padding = 0;
   1252     fuse_reply(fuse, hdr->unique, &out, sizeof(out));
   1253     return NO_STATUS;
   1254 }
   1255 
   1256 static int handle_read(struct fuse* fuse, struct fuse_handler* handler,
   1257         const struct fuse_in_header* hdr, const struct fuse_read_in* req)
   1258 {
   1259     struct handle *h = id_to_ptr(req->fh);
   1260     __u64 unique = hdr->unique;
   1261     __u32 size = req->size;
   1262     __u64 offset = req->offset;
   1263     int res;
   1264     __u8 *read_buffer = (__u8 *) ((uintptr_t)(handler->read_buffer + PAGESIZE) & ~((uintptr_t)PAGESIZE-1));
   1265 
   1266     /* Don't access any other fields of hdr or req beyond this point, the read buffer
   1267      * overlaps the request buffer and will clobber data in the request.  This
   1268      * saves us 128KB per request handler thread at the cost of this scary comment. */
   1269 
   1270     TRACE("[%d] READ %p(%d) %u@%"PRIu64"\n", handler->token,
   1271             h, h->fd, size, (uint64_t) offset);
   1272     if (size > MAX_READ) {
   1273         return -EINVAL;
   1274     }
   1275     res = pread64(h->fd, read_buffer, size, offset);
   1276     if (res < 0) {
   1277         return -errno;
   1278     }
   1279     fuse_reply(fuse, unique, read_buffer, res);
   1280     return NO_STATUS;
   1281 }
   1282 
   1283 static int handle_write(struct fuse* fuse, struct fuse_handler* handler,
   1284         const struct fuse_in_header* hdr, const struct fuse_write_in* req,
   1285         const void* buffer)
   1286 {
   1287     struct fuse_write_out out;
   1288     struct handle *h = id_to_ptr(req->fh);
   1289     int res;
   1290     __u8 aligned_buffer[req->size] __attribute__((__aligned__(PAGESIZE)));
   1291 
   1292     if (req->flags & O_DIRECT) {
   1293         memcpy(aligned_buffer, buffer, req->size);
   1294         buffer = (const __u8*) aligned_buffer;
   1295     }
   1296 
   1297     TRACE("[%d] WRITE %p(%d) %u@%"PRIu64"\n", handler->token,
   1298             h, h->fd, req->size, req->offset);
   1299     res = pwrite64(h->fd, buffer, req->size, req->offset);
   1300     if (res < 0) {
   1301         return -errno;
   1302     }
   1303     out.size = res;
   1304     fuse_reply(fuse, hdr->unique, &out, sizeof(out));
   1305     return NO_STATUS;
   1306 }
   1307 
   1308 static int handle_statfs(struct fuse* fuse, struct fuse_handler* handler,
   1309         const struct fuse_in_header* hdr)
   1310 {
   1311     char path[PATH_MAX];
   1312     struct statfs stat;
   1313     struct fuse_statfs_out out;
   1314     int res;
   1315 
   1316     pthread_mutex_lock(&fuse->lock);
   1317     TRACE("[%d] STATFS\n", handler->token);
   1318     res = get_node_path_locked(&fuse->root, path, sizeof(path));
   1319     pthread_mutex_unlock(&fuse->lock);
   1320     if (res < 0) {
   1321         return -ENOENT;
   1322     }
   1323     if (statfs(fuse->root.name, &stat) < 0) {
   1324         return -errno;
   1325     }
   1326     memset(&out, 0, sizeof(out));
   1327     out.st.blocks = stat.f_blocks;
   1328     out.st.bfree = stat.f_bfree;
   1329     out.st.bavail = stat.f_bavail;
   1330     out.st.files = stat.f_files;
   1331     out.st.ffree = stat.f_ffree;
   1332     out.st.bsize = stat.f_bsize;
   1333     out.st.namelen = stat.f_namelen;
   1334     out.st.frsize = stat.f_frsize;
   1335     fuse_reply(fuse, hdr->unique, &out, sizeof(out));
   1336     return NO_STATUS;
   1337 }
   1338 
   1339 static int handle_release(struct fuse* fuse, struct fuse_handler* handler,
   1340         const struct fuse_in_header* hdr, const struct fuse_release_in* req)
   1341 {
   1342     struct handle *h = id_to_ptr(req->fh);
   1343 
   1344     TRACE("[%d] RELEASE %p(%d)\n", handler->token, h, h->fd);
   1345     close(h->fd);
   1346     free(h);
   1347     return 0;
   1348 }
   1349 
   1350 static int handle_fsync(struct fuse* fuse, struct fuse_handler* handler,
   1351         const struct fuse_in_header* hdr, const struct fuse_fsync_in* req)
   1352 {
   1353     bool is_dir = (hdr->opcode == FUSE_FSYNCDIR);
   1354     bool is_data_sync = req->fsync_flags & 1;
   1355 
   1356     int fd = -1;
   1357     if (is_dir) {
   1358       struct dirhandle *dh = id_to_ptr(req->fh);
   1359       fd = dirfd(dh->d);
   1360     } else {
   1361       struct handle *h = id_to_ptr(req->fh);
   1362       fd = h->fd;
   1363     }
   1364 
   1365     TRACE("[%d] %s %p(%d) is_data_sync=%d\n", handler->token,
   1366             is_dir ? "FSYNCDIR" : "FSYNC",
   1367             id_to_ptr(req->fh), fd, is_data_sync);
   1368     int res = is_data_sync ? fdatasync(fd) : fsync(fd);
   1369     if (res == -1) {
   1370         return -errno;
   1371     }
   1372     return 0;
   1373 }
   1374 
   1375 static int handle_flush(struct fuse* fuse, struct fuse_handler* handler,
   1376         const struct fuse_in_header* hdr)
   1377 {
   1378     TRACE("[%d] FLUSH\n", handler->token);
   1379     return 0;
   1380 }
   1381 
   1382 static int handle_opendir(struct fuse* fuse, struct fuse_handler* handler,
   1383         const struct fuse_in_header* hdr, const struct fuse_open_in* req)
   1384 {
   1385     struct node* node;
   1386     char path[PATH_MAX];
   1387     struct fuse_open_out out;
   1388     struct dirhandle *h;
   1389 
   1390     pthread_mutex_lock(&fuse->lock);
   1391     node = lookup_node_and_path_by_id_locked(fuse, hdr->nodeid, path, sizeof(path));
   1392     TRACE("[%d] OPENDIR @ %"PRIx64" (%s)\n", handler->token,
   1393             hdr->nodeid, node ? node->name : "?");
   1394     pthread_mutex_unlock(&fuse->lock);
   1395 
   1396     if (!node) {
   1397         return -ENOENT;
   1398     }
   1399     if (!check_caller_access_to_node(fuse, hdr, node, R_OK, false)) {
   1400         return -EACCES;
   1401     }
   1402     h = malloc(sizeof(*h));
   1403     if (!h) {
   1404         return -ENOMEM;
   1405     }
   1406     TRACE("[%d] OPENDIR %s\n", handler->token, path);
   1407     h->d = opendir(path);
   1408     if (!h->d) {
   1409         free(h);
   1410         return -errno;
   1411     }
   1412     out.fh = ptr_to_id(h);
   1413     out.open_flags = 0;
   1414     out.padding = 0;
   1415     fuse_reply(fuse, hdr->unique, &out, sizeof(out));
   1416     return NO_STATUS;
   1417 }
   1418 
   1419 static int handle_readdir(struct fuse* fuse, struct fuse_handler* handler,
   1420         const struct fuse_in_header* hdr, const struct fuse_read_in* req)
   1421 {
   1422     char buffer[8192];
   1423     struct fuse_dirent *fde = (struct fuse_dirent*) buffer;
   1424     struct dirent *de;
   1425     struct dirhandle *h = id_to_ptr(req->fh);
   1426 
   1427     TRACE("[%d] READDIR %p\n", handler->token, h);
   1428     if (req->offset == 0) {
   1429         /* rewinddir() might have been called above us, so rewind here too */
   1430         TRACE("[%d] calling rewinddir()\n", handler->token);
   1431         rewinddir(h->d);
   1432     }
   1433     de = readdir(h->d);
   1434     if (!de) {
   1435         return 0;
   1436     }
   1437     fde->ino = FUSE_UNKNOWN_INO;
   1438     /* increment the offset so we can detect when rewinddir() seeks back to the beginning */
   1439     fde->off = req->offset + 1;
   1440     fde->type = de->d_type;
   1441     fde->namelen = strlen(de->d_name);
   1442     memcpy(fde->name, de->d_name, fde->namelen + 1);
   1443     fuse_reply(fuse, hdr->unique, fde,
   1444             FUSE_DIRENT_ALIGN(sizeof(struct fuse_dirent) + fde->namelen));
   1445     return NO_STATUS;
   1446 }
   1447 
   1448 static int handle_releasedir(struct fuse* fuse, struct fuse_handler* handler,
   1449         const struct fuse_in_header* hdr, const struct fuse_release_in* req)
   1450 {
   1451     struct dirhandle *h = id_to_ptr(req->fh);
   1452 
   1453     TRACE("[%d] RELEASEDIR %p\n", handler->token, h);
   1454     closedir(h->d);
   1455     free(h);
   1456     return 0;
   1457 }
   1458 
   1459 static int handle_init(struct fuse* fuse, struct fuse_handler* handler,
   1460         const struct fuse_in_header* hdr, const struct fuse_init_in* req)
   1461 {
   1462     struct fuse_init_out out;
   1463 
   1464     TRACE("[%d] INIT ver=%d.%d maxread=%d flags=%x\n",
   1465             handler->token, req->major, req->minor, req->max_readahead, req->flags);
   1466     out.major = FUSE_KERNEL_VERSION;
   1467     out.minor = FUSE_KERNEL_MINOR_VERSION;
   1468     out.max_readahead = req->max_readahead;
   1469     out.flags = FUSE_ATOMIC_O_TRUNC | FUSE_BIG_WRITES;
   1470     out.max_background = 32;
   1471     out.congestion_threshold = 32;
   1472     out.max_write = MAX_WRITE;
   1473     fuse_reply(fuse, hdr->unique, &out, sizeof(out));
   1474     return NO_STATUS;
   1475 }
   1476 
   1477 static int handle_fuse_request(struct fuse *fuse, struct fuse_handler* handler,
   1478         const struct fuse_in_header *hdr, const void *data, size_t data_len)
   1479 {
   1480     switch (hdr->opcode) {
   1481     case FUSE_LOOKUP: { /* bytez[] -> entry_out */
   1482         const char* name = data;
   1483         return handle_lookup(fuse, handler, hdr, name);
   1484     }
   1485 
   1486     case FUSE_FORGET: {
   1487         const struct fuse_forget_in *req = data;
   1488         return handle_forget(fuse, handler, hdr, req);
   1489     }
   1490 
   1491     case FUSE_GETATTR: { /* getattr_in -> attr_out */
   1492         const struct fuse_getattr_in *req = data;
   1493         return handle_getattr(fuse, handler, hdr, req);
   1494     }
   1495 
   1496     case FUSE_SETATTR: { /* setattr_in -> attr_out */
   1497         const struct fuse_setattr_in *req = data;
   1498         return handle_setattr(fuse, handler, hdr, req);
   1499     }
   1500 
   1501 //    case FUSE_READLINK:
   1502 //    case FUSE_SYMLINK:
   1503     case FUSE_MKNOD: { /* mknod_in, bytez[] -> entry_out */
   1504         const struct fuse_mknod_in *req = data;
   1505         const char *name = ((const char*) data) + sizeof(*req);
   1506         return handle_mknod(fuse, handler, hdr, req, name);
   1507     }
   1508 
   1509     case FUSE_MKDIR: { /* mkdir_in, bytez[] -> entry_out */
   1510         const struct fuse_mkdir_in *req = data;
   1511         const char *name = ((const char*) data) + sizeof(*req);
   1512         return handle_mkdir(fuse, handler, hdr, req, name);
   1513     }
   1514 
   1515     case FUSE_UNLINK: { /* bytez[] -> */
   1516         const char* name = data;
   1517         return handle_unlink(fuse, handler, hdr, name);
   1518     }
   1519 
   1520     case FUSE_RMDIR: { /* bytez[] -> */
   1521         const char* name = data;
   1522         return handle_rmdir(fuse, handler, hdr, name);
   1523     }
   1524 
   1525     case FUSE_RENAME: { /* rename_in, oldname, newname ->  */
   1526         const struct fuse_rename_in *req = data;
   1527         const char *old_name = ((const char*) data) + sizeof(*req);
   1528         const char *new_name = old_name + strlen(old_name) + 1;
   1529         return handle_rename(fuse, handler, hdr, req, old_name, new_name);
   1530     }
   1531 
   1532 //    case FUSE_LINK:
   1533     case FUSE_OPEN: { /* open_in -> open_out */
   1534         const struct fuse_open_in *req = data;
   1535         return handle_open(fuse, handler, hdr, req);
   1536     }
   1537 
   1538     case FUSE_READ: { /* read_in -> byte[] */
   1539         const struct fuse_read_in *req = data;
   1540         return handle_read(fuse, handler, hdr, req);
   1541     }
   1542 
   1543     case FUSE_WRITE: { /* write_in, byte[write_in.size] -> write_out */
   1544         const struct fuse_write_in *req = data;
   1545         const void* buffer = (const __u8*)data + sizeof(*req);
   1546         return handle_write(fuse, handler, hdr, req, buffer);
   1547     }
   1548 
   1549     case FUSE_STATFS: { /* getattr_in -> attr_out */
   1550         return handle_statfs(fuse, handler, hdr);
   1551     }
   1552 
   1553     case FUSE_RELEASE: { /* release_in -> */
   1554         const struct fuse_release_in *req = data;
   1555         return handle_release(fuse, handler, hdr, req);
   1556     }
   1557 
   1558     case FUSE_FSYNC:
   1559     case FUSE_FSYNCDIR: {
   1560         const struct fuse_fsync_in *req = data;
   1561         return handle_fsync(fuse, handler, hdr, req);
   1562     }
   1563 
   1564 //    case FUSE_SETXATTR:
   1565 //    case FUSE_GETXATTR:
   1566 //    case FUSE_LISTXATTR:
   1567 //    case FUSE_REMOVEXATTR:
   1568     case FUSE_FLUSH: {
   1569         return handle_flush(fuse, handler, hdr);
   1570     }
   1571 
   1572     case FUSE_OPENDIR: { /* open_in -> open_out */
   1573         const struct fuse_open_in *req = data;
   1574         return handle_opendir(fuse, handler, hdr, req);
   1575     }
   1576 
   1577     case FUSE_READDIR: {
   1578         const struct fuse_read_in *req = data;
   1579         return handle_readdir(fuse, handler, hdr, req);
   1580     }
   1581 
   1582     case FUSE_RELEASEDIR: { /* release_in -> */
   1583         const struct fuse_release_in *req = data;
   1584         return handle_releasedir(fuse, handler, hdr, req);
   1585     }
   1586 
   1587     case FUSE_INIT: { /* init_in -> init_out */
   1588         const struct fuse_init_in *req = data;
   1589         return handle_init(fuse, handler, hdr, req);
   1590     }
   1591 
   1592     default: {
   1593         TRACE("[%d] NOTIMPL op=%d uniq=%"PRIx64" nid=%"PRIx64"\n",
   1594                 handler->token, hdr->opcode, hdr->unique, hdr->nodeid);
   1595         return -ENOSYS;
   1596     }
   1597     }
   1598 }
   1599 
   1600 static void handle_fuse_requests(struct fuse_handler* handler)
   1601 {
   1602     struct fuse* fuse = handler->fuse;
   1603     for (;;) {
   1604         ssize_t len = read(fuse->fd,
   1605                 handler->request_buffer, sizeof(handler->request_buffer));
   1606         if (len < 0) {
   1607             if (errno != EINTR) {
   1608                 ERROR("[%d] handle_fuse_requests: errno=%d\n", handler->token, errno);
   1609             }
   1610             continue;
   1611         }
   1612 
   1613         if ((size_t)len < sizeof(struct fuse_in_header)) {
   1614             ERROR("[%d] request too short: len=%zu\n", handler->token, (size_t)len);
   1615             continue;
   1616         }
   1617 
   1618         const struct fuse_in_header *hdr = (void*)handler->request_buffer;
   1619         if (hdr->len != (size_t)len) {
   1620             ERROR("[%d] malformed header: len=%zu, hdr->len=%u\n",
   1621                     handler->token, (size_t)len, hdr->len);
   1622             continue;
   1623         }
   1624 
   1625         const void *data = handler->request_buffer + sizeof(struct fuse_in_header);
   1626         size_t data_len = len - sizeof(struct fuse_in_header);
   1627         __u64 unique = hdr->unique;
   1628         int res = handle_fuse_request(fuse, handler, hdr, data, data_len);
   1629 
   1630         /* We do not access the request again after this point because the underlying
   1631          * buffer storage may have been reused while processing the request. */
   1632 
   1633         if (res != NO_STATUS) {
   1634             if (res) {
   1635                 TRACE("[%d] ERROR %d\n", handler->token, res);
   1636             }
   1637             fuse_status(fuse, unique, res);
   1638         }
   1639     }
   1640 }
   1641 
   1642 static void* start_handler(void* data)
   1643 {
   1644     struct fuse_handler* handler = data;
   1645     handle_fuse_requests(handler);
   1646     return NULL;
   1647 }
   1648 
   1649 static bool remove_str_to_int(void *key, void *value, void *context) {
   1650     Hashmap* map = context;
   1651     hashmapRemove(map, key);
   1652     free(key);
   1653     return true;
   1654 }
   1655 
   1656 static bool remove_int_to_null(void *key, void *value, void *context) {
   1657     Hashmap* map = context;
   1658     hashmapRemove(map, key);
   1659     return true;
   1660 }
   1661 
   1662 static int read_package_list(struct fuse *fuse) {
   1663     pthread_mutex_lock(&fuse->lock);
   1664 
   1665     hashmapForEach(fuse->package_to_appid, remove_str_to_int, fuse->package_to_appid);
   1666     hashmapForEach(fuse->appid_with_rw, remove_int_to_null, fuse->appid_with_rw);
   1667 
   1668     FILE* file = fopen(kPackagesListFile, "r");
   1669     if (!file) {
   1670         ERROR("failed to open package list: %s\n", strerror(errno));
   1671         pthread_mutex_unlock(&fuse->lock);
   1672         return -1;
   1673     }
   1674 
   1675     char buf[512];
   1676     while (fgets(buf, sizeof(buf), file) != NULL) {
   1677         char package_name[512];
   1678         int appid;
   1679         char gids[512];
   1680 
   1681         if (sscanf(buf, "%s %d %*d %*s %*s %s", package_name, &appid, gids) == 3) {
   1682             char* package_name_dup = strdup(package_name);
   1683             hashmapPut(fuse->package_to_appid, package_name_dup, (void*) (uintptr_t) appid);
   1684 
   1685             char* token = strtok(gids, ",");
   1686             while (token != NULL) {
   1687                 if (strtoul(token, NULL, 10) == fuse->write_gid) {
   1688                     hashmapPut(fuse->appid_with_rw, (void*) (uintptr_t) appid, (void*) (uintptr_t) 1);
   1689                     break;
   1690                 }
   1691                 token = strtok(NULL, ",");
   1692             }
   1693         }
   1694     }
   1695 
   1696     TRACE("read_package_list: found %zu packages, %zu with write_gid\n",
   1697             hashmapSize(fuse->package_to_appid),
   1698             hashmapSize(fuse->appid_with_rw));
   1699     fclose(file);
   1700     pthread_mutex_unlock(&fuse->lock);
   1701     return 0;
   1702 }
   1703 
   1704 static void watch_package_list(struct fuse* fuse) {
   1705     struct inotify_event *event;
   1706     char event_buf[512];
   1707 
   1708     int nfd = inotify_init();
   1709     if (nfd < 0) {
   1710         ERROR("inotify_init failed: %s\n", strerror(errno));
   1711         return;
   1712     }
   1713 
   1714     bool active = false;
   1715     while (1) {
   1716         if (!active) {
   1717             int res = inotify_add_watch(nfd, kPackagesListFile, IN_DELETE_SELF);
   1718             if (res == -1) {
   1719                 if (errno == ENOENT || errno == EACCES) {
   1720                     /* Framework may not have created yet, sleep and retry */
   1721                     ERROR("missing packages.list; retrying\n");
   1722                     sleep(3);
   1723                     continue;
   1724                 } else {
   1725                     ERROR("inotify_add_watch failed: %s\n", strerror(errno));
   1726                     return;
   1727                 }
   1728             }
   1729 
   1730             /* Watch above will tell us about any future changes, so
   1731              * read the current state. */
   1732             if (read_package_list(fuse) == -1) {
   1733                 ERROR("read_package_list failed: %s\n", strerror(errno));
   1734                 return;
   1735             }
   1736             active = true;
   1737         }
   1738 
   1739         int event_pos = 0;
   1740         int res = read(nfd, event_buf, sizeof(event_buf));
   1741         if (res < (int) sizeof(*event)) {
   1742             if (errno == EINTR)
   1743                 continue;
   1744             ERROR("failed to read inotify event: %s\n", strerror(errno));
   1745             return;
   1746         }
   1747 
   1748         while (res >= (int) sizeof(*event)) {
   1749             int event_size;
   1750             event = (struct inotify_event *) (event_buf + event_pos);
   1751 
   1752             TRACE("inotify event: %08x\n", event->mask);
   1753             if ((event->mask & IN_IGNORED) == IN_IGNORED) {
   1754                 /* Previously watched file was deleted, probably due to move
   1755                  * that swapped in new data; re-arm the watch and read. */
   1756                 active = false;
   1757             }
   1758 
   1759             event_size = sizeof(*event) + event->len;
   1760             res -= event_size;
   1761             event_pos += event_size;
   1762         }
   1763     }
   1764 }
   1765 
   1766 static int ignite_fuse(struct fuse* fuse, int num_threads)
   1767 {
   1768     struct fuse_handler* handlers;
   1769     int i;
   1770 
   1771     handlers = malloc(num_threads * sizeof(struct fuse_handler));
   1772     if (!handlers) {
   1773         ERROR("cannot allocate storage for threads\n");
   1774         return -ENOMEM;
   1775     }
   1776 
   1777     for (i = 0; i < num_threads; i++) {
   1778         handlers[i].fuse = fuse;
   1779         handlers[i].token = i;
   1780     }
   1781 
   1782     /* When deriving permissions, this thread is used to process inotify events,
   1783      * otherwise it becomes one of the FUSE handlers. */
   1784     i = (fuse->derive == DERIVE_NONE) ? 1 : 0;
   1785     for (; i < num_threads; i++) {
   1786         pthread_t thread;
   1787         int res = pthread_create(&thread, NULL, start_handler, &handlers[i]);
   1788         if (res) {
   1789             ERROR("failed to start thread #%d, error=%d\n", i, res);
   1790             goto quit;
   1791         }
   1792     }
   1793 
   1794     if (fuse->derive == DERIVE_NONE) {
   1795         handle_fuse_requests(&handlers[0]);
   1796     } else {
   1797         watch_package_list(fuse);
   1798     }
   1799 
   1800     ERROR("terminated prematurely\n");
   1801 
   1802     /* don't bother killing all of the other threads or freeing anything,
   1803      * should never get here anyhow */
   1804 quit:
   1805     exit(1);
   1806 }
   1807 
   1808 static int usage()
   1809 {
   1810     ERROR("usage: sdcard [OPTIONS] <source_path> <dest_path>\n"
   1811             "    -u: specify UID to run as\n"
   1812             "    -g: specify GID to run as\n"
   1813             "    -w: specify GID required to write (default sdcard_rw, requires -d or -l)\n"
   1814             "    -t: specify number of threads to use (default %d)\n"
   1815             "    -d: derive file permissions based on path\n"
   1816             "    -l: derive file permissions based on legacy internal layout\n"
   1817             "    -s: split derived permissions for pics, av\n"
   1818             "\n", DEFAULT_NUM_THREADS);
   1819     return 1;
   1820 }
   1821 
   1822 static int run(const char* source_path, const char* dest_path, uid_t uid,
   1823         gid_t gid, gid_t write_gid, int num_threads, derive_t derive,
   1824         bool split_perms) {
   1825     int fd;
   1826     char opts[256];
   1827     int res;
   1828     struct fuse fuse;
   1829 
   1830     /* cleanup from previous instance, if necessary */
   1831     umount2(dest_path, 2);
   1832 
   1833     fd = open("/dev/fuse", O_RDWR);
   1834     if (fd < 0){
   1835         ERROR("cannot open fuse device: %s\n", strerror(errno));
   1836         return -1;
   1837     }
   1838 
   1839     snprintf(opts, sizeof(opts),
   1840             "fd=%i,rootmode=40000,default_permissions,allow_other,user_id=%d,group_id=%d",
   1841             fd, uid, gid);
   1842 
   1843     res = mount("/dev/fuse", dest_path, "fuse", MS_NOSUID | MS_NODEV | MS_NOEXEC, opts);
   1844     if (res < 0) {
   1845         ERROR("cannot mount fuse filesystem: %s\n", strerror(errno));
   1846         goto error;
   1847     }
   1848 
   1849     res = setgroups(sizeof(kGroups) / sizeof(kGroups[0]), kGroups);
   1850     if (res < 0) {
   1851         ERROR("cannot setgroups: %s\n", strerror(errno));
   1852         goto error;
   1853     }
   1854 
   1855     res = setgid(gid);
   1856     if (res < 0) {
   1857         ERROR("cannot setgid: %s\n", strerror(errno));
   1858         goto error;
   1859     }
   1860 
   1861     res = setuid(uid);
   1862     if (res < 0) {
   1863         ERROR("cannot setuid: %s\n", strerror(errno));
   1864         goto error;
   1865     }
   1866 
   1867     fuse_init(&fuse, fd, source_path, write_gid, derive, split_perms);
   1868 
   1869     umask(0);
   1870     res = ignite_fuse(&fuse, num_threads);
   1871 
   1872     /* we do not attempt to umount the file system here because we are no longer
   1873      * running as the root user */
   1874 
   1875 error:
   1876     close(fd);
   1877     return res;
   1878 }
   1879 
   1880 int main(int argc, char **argv)
   1881 {
   1882     int res;
   1883     const char *source_path = NULL;
   1884     const char *dest_path = NULL;
   1885     uid_t uid = 0;
   1886     gid_t gid = 0;
   1887     gid_t write_gid = AID_SDCARD_RW;
   1888     int num_threads = DEFAULT_NUM_THREADS;
   1889     derive_t derive = DERIVE_NONE;
   1890     bool split_perms = false;
   1891     int i;
   1892     struct rlimit rlim;
   1893     int fs_version;
   1894 
   1895     int opt;
   1896     while ((opt = getopt(argc, argv, "u:g:w:t:dls")) != -1) {
   1897         switch (opt) {
   1898             case 'u':
   1899                 uid = strtoul(optarg, NULL, 10);
   1900                 break;
   1901             case 'g':
   1902                 gid = strtoul(optarg, NULL, 10);
   1903                 break;
   1904             case 'w':
   1905                 write_gid = strtoul(optarg, NULL, 10);
   1906                 break;
   1907             case 't':
   1908                 num_threads = strtoul(optarg, NULL, 10);
   1909                 break;
   1910             case 'd':
   1911                 derive = DERIVE_UNIFIED;
   1912                 break;
   1913             case 'l':
   1914                 derive = DERIVE_LEGACY;
   1915                 break;
   1916             case 's':
   1917                 split_perms = true;
   1918                 break;
   1919             case '?':
   1920             default:
   1921                 return usage();
   1922         }
   1923     }
   1924 
   1925     for (i = optind; i < argc; i++) {
   1926         char* arg = argv[i];
   1927         if (!source_path) {
   1928             source_path = arg;
   1929         } else if (!dest_path) {
   1930             dest_path = arg;
   1931         } else if (!uid) {
   1932             uid = strtoul(arg, NULL, 10);
   1933         } else if (!gid) {
   1934             gid = strtoul(arg, NULL, 10);
   1935         } else {
   1936             ERROR("too many arguments\n");
   1937             return usage();
   1938         }
   1939     }
   1940 
   1941     if (!source_path) {
   1942         ERROR("no source path specified\n");
   1943         return usage();
   1944     }
   1945     if (!dest_path) {
   1946         ERROR("no dest path specified\n");
   1947         return usage();
   1948     }
   1949     if (!uid || !gid) {
   1950         ERROR("uid and gid must be nonzero\n");
   1951         return usage();
   1952     }
   1953     if (num_threads < 1) {
   1954         ERROR("number of threads must be at least 1\n");
   1955         return usage();
   1956     }
   1957     if (split_perms && derive == DERIVE_NONE) {
   1958         ERROR("cannot split permissions without deriving\n");
   1959         return usage();
   1960     }
   1961 
   1962     rlim.rlim_cur = 8192;
   1963     rlim.rlim_max = 8192;
   1964     if (setrlimit(RLIMIT_NOFILE, &rlim)) {
   1965         ERROR("Error setting RLIMIT_NOFILE, errno = %d\n", errno);
   1966     }
   1967 
   1968     while ((fs_read_atomic_int("/data/.layout_version", &fs_version) == -1) || (fs_version < 3)) {
   1969         ERROR("installd fs upgrade not yet complete. Waiting...\n");
   1970         sleep(1);
   1971     }
   1972 
   1973     res = run(source_path, dest_path, uid, gid, write_gid, num_threads, derive, split_perms);
   1974     return res < 0 ? 1 : 0;
   1975 }
   1976