Home | History | Annotate | Download | only in adb
      1 /*
      2  * Copyright (C) 2007 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 #include <stdlib.h>
     18 #include <stdio.h>
     19 #include <string.h>
     20 
     21 #include <sys/stat.h>
     22 #include <sys/types.h>
     23 #include <dirent.h>
     24 #include <utime.h>
     25 #include <unistd.h>
     26 
     27 #include <errno.h>
     28 #include <private/android_filesystem_config.h>
     29 #include <selinux/android.h>
     30 #include "sysdeps.h"
     31 
     32 #define TRACE_TAG  TRACE_SYNC
     33 #include "adb.h"
     34 #include "file_sync_service.h"
     35 
     36 /* TODO: use fs_config to configure permissions on /data */
     37 static bool is_on_system(const char *name) {
     38     const char *SYSTEM = "/system/";
     39     return (strncmp(SYSTEM, name, strlen(SYSTEM)) == 0);
     40 }
     41 
     42 static bool is_on_vendor(const char *name) {
     43     const char *VENDOR = "/vendor/";
     44     return (strncmp(VENDOR, name, strlen(VENDOR)) == 0);
     45 }
     46 
     47 static int mkdirs(char *name)
     48 {
     49     int ret;
     50     char *x = name + 1;
     51     uid_t uid = -1;
     52     gid_t gid = -1;
     53     unsigned int mode = 0775;
     54     uint64_t cap = 0;
     55 
     56     if(name[0] != '/') return -1;
     57 
     58     for(;;) {
     59         x = adb_dirstart(x);
     60         if(x == 0) return 0;
     61         *x = 0;
     62         if (is_on_system(name) || is_on_vendor(name)) {
     63             fs_config(name, 1, &uid, &gid, &mode, &cap);
     64         }
     65         ret = adb_mkdir(name, mode);
     66         if((ret < 0) && (errno != EEXIST)) {
     67             D("mkdir(\"%s\") -> %s\n", name, strerror(errno));
     68             *x = '/';
     69             return ret;
     70         } else if(ret == 0) {
     71             ret = chown(name, uid, gid);
     72             if (ret < 0) {
     73                 *x = '/';
     74                 return ret;
     75             }
     76             selinux_android_restorecon(name, 0);
     77         }
     78         *x++ = '/';
     79     }
     80     return 0;
     81 }
     82 
     83 static int do_stat(int s, const char *path)
     84 {
     85     syncmsg msg;
     86     struct stat st;
     87 
     88     msg.stat.id = ID_STAT;
     89 
     90     if(lstat(path, &st)) {
     91         msg.stat.mode = 0;
     92         msg.stat.size = 0;
     93         msg.stat.time = 0;
     94     } else {
     95         msg.stat.mode = htoll(st.st_mode);
     96         msg.stat.size = htoll(st.st_size);
     97         msg.stat.time = htoll(st.st_mtime);
     98     }
     99 
    100     return writex(s, &msg.stat, sizeof(msg.stat));
    101 }
    102 
    103 static int do_list(int s, const char *path)
    104 {
    105     DIR *d;
    106     struct dirent *de;
    107     struct stat st;
    108     syncmsg msg;
    109     int len;
    110 
    111     char tmp[1024 + 256 + 1];
    112     char *fname;
    113 
    114     len = strlen(path);
    115     memcpy(tmp, path, len);
    116     tmp[len] = '/';
    117     fname = tmp + len + 1;
    118 
    119     msg.dent.id = ID_DENT;
    120 
    121     d = opendir(path);
    122     if(d == 0) goto done;
    123 
    124     while((de = readdir(d))) {
    125         int len = strlen(de->d_name);
    126 
    127             /* not supposed to be possible, but
    128                if it does happen, let's not buffer overrun */
    129         if(len > 256) continue;
    130 
    131         strcpy(fname, de->d_name);
    132         if(lstat(tmp, &st) == 0) {
    133             msg.dent.mode = htoll(st.st_mode);
    134             msg.dent.size = htoll(st.st_size);
    135             msg.dent.time = htoll(st.st_mtime);
    136             msg.dent.namelen = htoll(len);
    137 
    138             if(writex(s, &msg.dent, sizeof(msg.dent)) ||
    139                writex(s, de->d_name, len)) {
    140                 closedir(d);
    141                 return -1;
    142             }
    143         }
    144     }
    145 
    146     closedir(d);
    147 
    148 done:
    149     msg.dent.id = ID_DONE;
    150     msg.dent.mode = 0;
    151     msg.dent.size = 0;
    152     msg.dent.time = 0;
    153     msg.dent.namelen = 0;
    154     return writex(s, &msg.dent, sizeof(msg.dent));
    155 }
    156 
    157 static int fail_message(int s, const char *reason)
    158 {
    159     syncmsg msg;
    160     int len = strlen(reason);
    161 
    162     D("sync: failure: %s\n", reason);
    163 
    164     msg.data.id = ID_FAIL;
    165     msg.data.size = htoll(len);
    166     if(writex(s, &msg.data, sizeof(msg.data)) ||
    167        writex(s, reason, len)) {
    168         return -1;
    169     } else {
    170         return 0;
    171     }
    172 }
    173 
    174 static int fail_errno(int s)
    175 {
    176     return fail_message(s, strerror(errno));
    177 }
    178 
    179 static int handle_send_file(int s, char *path, uid_t uid,
    180         gid_t gid, mode_t mode, char *buffer, bool do_unlink)
    181 {
    182     syncmsg msg;
    183     unsigned int timestamp = 0;
    184     int fd;
    185 
    186     fd = adb_open_mode(path, O_WRONLY | O_CREAT | O_EXCL | O_CLOEXEC, mode);
    187     if(fd < 0 && errno == ENOENT) {
    188         if(mkdirs(path) != 0) {
    189             if(fail_errno(s))
    190                 return -1;
    191             fd = -1;
    192         } else {
    193             fd = adb_open_mode(path, O_WRONLY | O_CREAT | O_EXCL | O_CLOEXEC, mode);
    194         }
    195     }
    196     if(fd < 0 && errno == EEXIST) {
    197         fd = adb_open_mode(path, O_WRONLY | O_CLOEXEC, mode);
    198     }
    199     if(fd < 0) {
    200         if(fail_errno(s))
    201             return -1;
    202         fd = -1;
    203     } else {
    204         if(fchown(fd, uid, gid) != 0) {
    205             fail_errno(s);
    206             errno = 0;
    207         }
    208 
    209         /*
    210          * fchown clears the setuid bit - restore it if present.
    211          * Ignore the result of calling fchmod. It's not supported
    212          * by all filesystems. b/12441485
    213          */
    214         fchmod(fd, mode);
    215     }
    216 
    217     for(;;) {
    218         unsigned int len;
    219 
    220         if(readx(s, &msg.data, sizeof(msg.data)))
    221             goto fail;
    222 
    223         if(msg.data.id != ID_DATA) {
    224             if(msg.data.id == ID_DONE) {
    225                 timestamp = ltohl(msg.data.size);
    226                 break;
    227             }
    228             fail_message(s, "invalid data message");
    229             goto fail;
    230         }
    231         len = ltohl(msg.data.size);
    232         if(len > SYNC_DATA_MAX) {
    233             fail_message(s, "oversize data message");
    234             goto fail;
    235         }
    236         if(readx(s, buffer, len))
    237             goto fail;
    238 
    239         if(fd < 0)
    240             continue;
    241         if(writex(fd, buffer, len)) {
    242             int saved_errno = errno;
    243             adb_close(fd);
    244             if (do_unlink) adb_unlink(path);
    245             fd = -1;
    246             errno = saved_errno;
    247             if(fail_errno(s)) return -1;
    248         }
    249     }
    250 
    251     if(fd >= 0) {
    252         struct utimbuf u;
    253         adb_close(fd);
    254         selinux_android_restorecon(path, 0);
    255         u.actime = timestamp;
    256         u.modtime = timestamp;
    257         utime(path, &u);
    258 
    259         msg.status.id = ID_OKAY;
    260         msg.status.msglen = 0;
    261         if(writex(s, &msg.status, sizeof(msg.status)))
    262             return -1;
    263     }
    264     return 0;
    265 
    266 fail:
    267     if(fd >= 0)
    268         adb_close(fd);
    269     if (do_unlink) adb_unlink(path);
    270     return -1;
    271 }
    272 
    273 #ifdef HAVE_SYMLINKS
    274 static int handle_send_link(int s, char *path, char *buffer)
    275 {
    276     syncmsg msg;
    277     unsigned int len;
    278     int ret;
    279 
    280     if(readx(s, &msg.data, sizeof(msg.data)))
    281         return -1;
    282 
    283     if(msg.data.id != ID_DATA) {
    284         fail_message(s, "invalid data message: expected ID_DATA");
    285         return -1;
    286     }
    287 
    288     len = ltohl(msg.data.size);
    289     if(len > SYNC_DATA_MAX) {
    290         fail_message(s, "oversize data message");
    291         return -1;
    292     }
    293     if(readx(s, buffer, len))
    294         return -1;
    295 
    296     ret = symlink(buffer, path);
    297     if(ret && errno == ENOENT) {
    298         if(mkdirs(path) != 0) {
    299             fail_errno(s);
    300             return -1;
    301         }
    302         ret = symlink(buffer, path);
    303     }
    304     if(ret) {
    305         fail_errno(s);
    306         return -1;
    307     }
    308 
    309     if(readx(s, &msg.data, sizeof(msg.data)))
    310         return -1;
    311 
    312     if(msg.data.id == ID_DONE) {
    313         msg.status.id = ID_OKAY;
    314         msg.status.msglen = 0;
    315         if(writex(s, &msg.status, sizeof(msg.status)))
    316             return -1;
    317     } else {
    318         fail_message(s, "invalid data message: expected ID_DONE");
    319         return -1;
    320     }
    321 
    322     return 0;
    323 }
    324 #endif /* HAVE_SYMLINKS */
    325 
    326 static int do_send(int s, char *path, char *buffer)
    327 {
    328     char *tmp;
    329     unsigned int mode;
    330     int is_link, ret;
    331     bool do_unlink;
    332 
    333     tmp = strrchr(path,',');
    334     if(tmp) {
    335         *tmp = 0;
    336         errno = 0;
    337         mode = strtoul(tmp + 1, NULL, 0);
    338 #ifndef HAVE_SYMLINKS
    339         is_link = 0;
    340 #else
    341         is_link = S_ISLNK((mode_t) mode);
    342 #endif
    343         mode &= 0777;
    344     }
    345     if(!tmp || errno) {
    346         mode = 0644;
    347         is_link = 0;
    348         do_unlink = true;
    349     } else {
    350         struct stat st;
    351         /* Don't delete files before copying if they are not "regular" */
    352         do_unlink = lstat(path, &st) || S_ISREG(st.st_mode) || S_ISLNK(st.st_mode);
    353         if (do_unlink) {
    354             adb_unlink(path);
    355         }
    356     }
    357 
    358 #ifdef HAVE_SYMLINKS
    359     if(is_link)
    360         ret = handle_send_link(s, path, buffer);
    361     else {
    362 #else
    363     {
    364 #endif
    365         uid_t uid = -1;
    366         gid_t gid = -1;
    367         uint64_t cap = 0;
    368 
    369         /* copy user permission bits to "group" and "other" permissions */
    370         mode |= ((mode >> 3) & 0070);
    371         mode |= ((mode >> 3) & 0007);
    372 
    373         tmp = path;
    374         if(*tmp == '/') {
    375             tmp++;
    376         }
    377         if (is_on_system(path) || is_on_vendor(path)) {
    378             fs_config(tmp, 0, &uid, &gid, &mode, &cap);
    379         }
    380         ret = handle_send_file(s, path, uid, gid, mode, buffer, do_unlink);
    381     }
    382 
    383     return ret;
    384 }
    385 
    386 static int do_recv(int s, const char *path, char *buffer)
    387 {
    388     syncmsg msg;
    389     int fd, r;
    390 
    391     fd = adb_open(path, O_RDONLY | O_CLOEXEC);
    392     if(fd < 0) {
    393         if(fail_errno(s)) return -1;
    394         return 0;
    395     }
    396 
    397     msg.data.id = ID_DATA;
    398     for(;;) {
    399         r = adb_read(fd, buffer, SYNC_DATA_MAX);
    400         if(r <= 0) {
    401             if(r == 0) break;
    402             if(errno == EINTR) continue;
    403             r = fail_errno(s);
    404             adb_close(fd);
    405             return r;
    406         }
    407         msg.data.size = htoll(r);
    408         if(writex(s, &msg.data, sizeof(msg.data)) ||
    409            writex(s, buffer, r)) {
    410             adb_close(fd);
    411             return -1;
    412         }
    413     }
    414 
    415     adb_close(fd);
    416 
    417     msg.data.id = ID_DONE;
    418     msg.data.size = 0;
    419     if(writex(s, &msg.data, sizeof(msg.data))) {
    420         return -1;
    421     }
    422 
    423     return 0;
    424 }
    425 
    426 void file_sync_service(int fd, void *cookie)
    427 {
    428     syncmsg msg;
    429     char name[1025];
    430     unsigned namelen;
    431 
    432     char *buffer = malloc(SYNC_DATA_MAX);
    433     if(buffer == 0) goto fail;
    434 
    435     for(;;) {
    436         D("sync: waiting for command\n");
    437 
    438         if(readx(fd, &msg.req, sizeof(msg.req))) {
    439             fail_message(fd, "command read failure");
    440             break;
    441         }
    442         namelen = ltohl(msg.req.namelen);
    443         if(namelen > 1024) {
    444             fail_message(fd, "invalid namelen");
    445             break;
    446         }
    447         if(readx(fd, name, namelen)) {
    448             fail_message(fd, "filename read failure");
    449             break;
    450         }
    451         name[namelen] = 0;
    452 
    453         msg.req.namelen = 0;
    454         D("sync: '%s' '%s'\n", (char*) &msg.req, name);
    455 
    456         switch(msg.req.id) {
    457         case ID_STAT:
    458             if(do_stat(fd, name)) goto fail;
    459             break;
    460         case ID_LIST:
    461             if(do_list(fd, name)) goto fail;
    462             break;
    463         case ID_SEND:
    464             if(do_send(fd, name, buffer)) goto fail;
    465             break;
    466         case ID_RECV:
    467             if(do_recv(fd, name, buffer)) goto fail;
    468             break;
    469         case ID_QUIT:
    470             goto fail;
    471         default:
    472             fail_message(fd, "unknown command");
    473             goto fail;
    474         }
    475     }
    476 
    477 fail:
    478     if(buffer != 0) free(buffer);
    479     D("sync: done\n");
    480     adb_close(fd);
    481 }
    482