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