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 SYNC
     18 
     19 #include "sysdeps.h"
     20 #include "file_sync_service.h"
     21 
     22 #include <dirent.h>
     23 #include <errno.h>
     24 #include <log/log.h>
     25 #include <selinux/android.h>
     26 #include <stdio.h>
     27 #include <stdlib.h>
     28 #include <string.h>
     29 #include <sys/stat.h>
     30 #include <sys/types.h>
     31 #include <unistd.h>
     32 #include <utime.h>
     33 
     34 #include "adb.h"
     35 #include "adb_io.h"
     36 #include "adb_utils.h"
     37 #include "private/android_filesystem_config.h"
     38 #include "security_log_tags.h"
     39 
     40 #include <android-base/stringprintf.h>
     41 #include <android-base/strings.h>
     42 
     43 static bool should_use_fs_config(const std::string& path) {
     44     // TODO: use fs_config to configure permissions on /data.
     45     return android::base::StartsWith(path, "/system/") ||
     46            android::base::StartsWith(path, "/vendor/") ||
     47            android::base::StartsWith(path, "/oem/");
     48 }
     49 
     50 static bool secure_mkdirs(const std::string& path) {
     51     uid_t uid = -1;
     52     gid_t gid = -1;
     53     unsigned int mode = 0775;
     54     uint64_t cap = 0;
     55 
     56     if (path[0] != '/') return false;
     57 
     58     std::vector<std::string> path_components = android::base::Split(path, "/");
     59     std::string partial_path;
     60     for (const auto& path_component : path_components) {
     61         if (partial_path.back() != OS_PATH_SEPARATOR) partial_path += OS_PATH_SEPARATOR;
     62         partial_path += path_component;
     63 
     64         if (should_use_fs_config(partial_path)) {
     65             fs_config(partial_path.c_str(), 1, nullptr, &uid, &gid, &mode, &cap);
     66         }
     67         if (adb_mkdir(partial_path.c_str(), mode) == -1) {
     68             if (errno != EEXIST) {
     69                 return false;
     70             }
     71         } else {
     72             if (chown(partial_path.c_str(), uid, gid) == -1) {
     73                 return false;
     74             }
     75             // Not all filesystems support setting SELinux labels. http://b/23530370.
     76             selinux_android_restorecon(partial_path.c_str(), 0);
     77         }
     78     }
     79     return true;
     80 }
     81 
     82 static bool do_stat(int s, const char* path) {
     83     syncmsg msg;
     84     msg.stat.id = ID_STAT;
     85 
     86     struct stat st;
     87     memset(&st, 0, sizeof(st));
     88     // TODO: add a way to report that the stat failed!
     89     lstat(path, &st);
     90     msg.stat.mode = st.st_mode;
     91     msg.stat.size = st.st_size;
     92     msg.stat.time = st.st_mtime;
     93 
     94     return WriteFdExactly(s, &msg.stat, sizeof(msg.stat));
     95 }
     96 
     97 static bool do_list(int s, const char* path) {
     98     dirent* de;
     99 
    100     syncmsg msg;
    101     msg.dent.id = ID_DENT;
    102 
    103     std::unique_ptr<DIR, int(*)(DIR*)> d(opendir(path), closedir);
    104     if (!d) goto done;
    105 
    106     while ((de = readdir(d.get()))) {
    107         std::string filename(android::base::StringPrintf("%s/%s", path, de->d_name));
    108 
    109         struct stat st;
    110         if (lstat(filename.c_str(), &st) == 0) {
    111             size_t d_name_length = strlen(de->d_name);
    112             msg.dent.mode = st.st_mode;
    113             msg.dent.size = st.st_size;
    114             msg.dent.time = st.st_mtime;
    115             msg.dent.namelen = d_name_length;
    116 
    117             if (!WriteFdExactly(s, &msg.dent, sizeof(msg.dent)) ||
    118                     !WriteFdExactly(s, de->d_name, d_name_length)) {
    119                 return false;
    120             }
    121         }
    122     }
    123 
    124 done:
    125     msg.dent.id = ID_DONE;
    126     msg.dent.mode = 0;
    127     msg.dent.size = 0;
    128     msg.dent.time = 0;
    129     msg.dent.namelen = 0;
    130     return WriteFdExactly(s, &msg.dent, sizeof(msg.dent));
    131 }
    132 
    133 // Make sure that SendFail from adb_io.cpp isn't accidentally used in this file.
    134 #pragma GCC poison SendFail
    135 
    136 static bool SendSyncFail(int fd, const std::string& reason) {
    137     D("sync: failure: %s", reason.c_str());
    138 
    139     syncmsg msg;
    140     msg.data.id = ID_FAIL;
    141     msg.data.size = reason.size();
    142     return WriteFdExactly(fd, &msg.data, sizeof(msg.data)) && WriteFdExactly(fd, reason);
    143 }
    144 
    145 static bool SendSyncFailErrno(int fd, const std::string& reason) {
    146     return SendSyncFail(fd, android::base::StringPrintf("%s: %s", reason.c_str(), strerror(errno)));
    147 }
    148 
    149 static bool handle_send_file(int s, const char* path, uid_t uid,
    150                              gid_t gid, mode_t mode, std::vector<char>& buffer, bool do_unlink) {
    151     syncmsg msg;
    152     unsigned int timestamp = 0;
    153 
    154     __android_log_security_bswrite(SEC_TAG_ADB_SEND_FILE, path);
    155 
    156     int fd = adb_open_mode(path, O_WRONLY | O_CREAT | O_EXCL | O_CLOEXEC, mode);
    157     if (fd < 0 && errno == ENOENT) {
    158         if (!secure_mkdirs(adb_dirname(path))) {
    159             SendSyncFailErrno(s, "secure_mkdirs failed");
    160             goto fail;
    161         }
    162         fd = adb_open_mode(path, O_WRONLY | O_CREAT | O_EXCL | O_CLOEXEC, mode);
    163     }
    164     if (fd < 0 && errno == EEXIST) {
    165         fd = adb_open_mode(path, O_WRONLY | O_CLOEXEC, mode);
    166     }
    167     if (fd < 0) {
    168         SendSyncFailErrno(s, "couldn't create file");
    169         goto fail;
    170     } else {
    171         if (fchown(fd, uid, gid) == -1) {
    172             SendSyncFailErrno(s, "fchown failed");
    173             goto fail;
    174         }
    175 
    176         // Not all filesystems support setting SELinux labels. http://b/23530370.
    177         selinux_android_restorecon(path, 0);
    178 
    179         // fchown clears the setuid bit - restore it if present.
    180         // Ignore the result of calling fchmod. It's not supported
    181         // by all filesystems. b/12441485
    182         fchmod(fd, mode);
    183     }
    184 
    185     while (true) {
    186         if (!ReadFdExactly(s, &msg.data, sizeof(msg.data))) goto fail;
    187 
    188         if (msg.data.id != ID_DATA) {
    189             if (msg.data.id == ID_DONE) {
    190                 timestamp = msg.data.size;
    191                 break;
    192             }
    193             SendSyncFail(s, "invalid data message");
    194             goto abort;
    195         }
    196 
    197         if (msg.data.size > buffer.size()) {  // TODO: resize buffer?
    198             SendSyncFail(s, "oversize data message");
    199             goto abort;
    200         }
    201 
    202         if (!ReadFdExactly(s, &buffer[0], msg.data.size)) goto abort;
    203 
    204         if (!WriteFdExactly(fd, &buffer[0], msg.data.size)) {
    205             SendSyncFailErrno(s, "write failed");
    206             goto fail;
    207         }
    208     }
    209 
    210     adb_close(fd);
    211 
    212     utimbuf u;
    213     u.actime = timestamp;
    214     u.modtime = timestamp;
    215     utime(path, &u);
    216 
    217     msg.status.id = ID_OKAY;
    218     msg.status.msglen = 0;
    219     return WriteFdExactly(s, &msg.status, sizeof(msg.status));
    220 
    221 fail:
    222     // If there's a problem on the device, we'll send an ID_FAIL message and
    223     // close the socket. Unfortunately the kernel will sometimes throw that
    224     // data away if the other end keeps writing without reading (which is
    225     // the case with old versions of adb). To maintain compatibility, keep
    226     // reading and throwing away ID_DATA packets until the other side notices
    227     // that we've reported an error.
    228     while (true) {
    229         if (!ReadFdExactly(s, &msg.data, sizeof(msg.data))) goto fail;
    230 
    231         if (msg.data.id == ID_DONE) {
    232             goto abort;
    233         } else if (msg.data.id != ID_DATA) {
    234             char id[5];
    235             memcpy(id, &msg.data.id, sizeof(msg.data.id));
    236             id[4] = '\0';
    237             D("handle_send_fail received unexpected id '%s' during failure", id);
    238             goto abort;
    239         }
    240 
    241         if (msg.data.size > buffer.size()) {
    242             D("handle_send_fail received oversized packet of length '%u' during failure",
    243               msg.data.size);
    244             goto abort;
    245         }
    246 
    247         if (!ReadFdExactly(s, &buffer[0], msg.data.size)) goto abort;
    248     }
    249 
    250 abort:
    251     if (fd >= 0) adb_close(fd);
    252     if (do_unlink) adb_unlink(path);
    253     return false;
    254 }
    255 
    256 #if defined(_WIN32)
    257 extern bool handle_send_link(int s, const std::string& path, std::vector<char>& buffer) __attribute__((error("no symlinks on Windows")));
    258 #else
    259 static bool handle_send_link(int s, const std::string& path, std::vector<char>& buffer) {
    260     syncmsg msg;
    261     unsigned int len;
    262     int ret;
    263 
    264     if (!ReadFdExactly(s, &msg.data, sizeof(msg.data))) return false;
    265 
    266     if (msg.data.id != ID_DATA) {
    267         SendSyncFail(s, "invalid data message: expected ID_DATA");
    268         return false;
    269     }
    270 
    271     len = msg.data.size;
    272     if (len > buffer.size()) { // TODO: resize buffer?
    273         SendSyncFail(s, "oversize data message");
    274         return false;
    275     }
    276     if (!ReadFdExactly(s, &buffer[0], len)) return false;
    277 
    278     ret = symlink(&buffer[0], path.c_str());
    279     if (ret && errno == ENOENT) {
    280         if (!secure_mkdirs(adb_dirname(path))) {
    281             SendSyncFailErrno(s, "secure_mkdirs failed");
    282             return false;
    283         }
    284         ret = symlink(&buffer[0], path.c_str());
    285     }
    286     if (ret) {
    287         SendSyncFailErrno(s, "symlink failed");
    288         return false;
    289     }
    290 
    291     if (!ReadFdExactly(s, &msg.data, sizeof(msg.data))) return false;
    292 
    293     if (msg.data.id == ID_DONE) {
    294         msg.status.id = ID_OKAY;
    295         msg.status.msglen = 0;
    296         if (!WriteFdExactly(s, &msg.status, sizeof(msg.status))) return false;
    297     } else {
    298         SendSyncFail(s, "invalid data message: expected ID_DONE");
    299         return false;
    300     }
    301 
    302     return true;
    303 }
    304 #endif
    305 
    306 static bool do_send(int s, const std::string& spec, std::vector<char>& buffer) {
    307     // 'spec' is of the form "/some/path,0755". Break it up.
    308     size_t comma = spec.find_last_of(',');
    309     if (comma == std::string::npos) {
    310         SendSyncFail(s, "missing , in ID_SEND");
    311         return false;
    312     }
    313 
    314     std::string path = spec.substr(0, comma);
    315 
    316     errno = 0;
    317     mode_t mode = strtoul(spec.substr(comma + 1).c_str(), nullptr, 0);
    318     if (errno != 0) {
    319         SendSyncFail(s, "bad mode");
    320         return false;
    321     }
    322 
    323     // Don't delete files before copying if they are not "regular" or symlinks.
    324     struct stat st;
    325     bool do_unlink = (lstat(path.c_str(), &st) == -1) || S_ISREG(st.st_mode) || S_ISLNK(st.st_mode);
    326     if (do_unlink) {
    327         adb_unlink(path.c_str());
    328     }
    329 
    330     if (S_ISLNK(mode)) {
    331         return handle_send_link(s, path.c_str(), buffer);
    332     }
    333 
    334     // Copy user permission bits to "group" and "other" permissions.
    335     mode &= 0777;
    336     mode |= ((mode >> 3) & 0070);
    337     mode |= ((mode >> 3) & 0007);
    338 
    339     uid_t uid = -1;
    340     gid_t gid = -1;
    341     uint64_t cap = 0;
    342     if (should_use_fs_config(path)) {
    343         unsigned int broken_api_hack = mode;
    344         fs_config(path.c_str(), 0, nullptr, &uid, &gid, &broken_api_hack, &cap);
    345         mode = broken_api_hack;
    346     }
    347     return handle_send_file(s, path.c_str(), uid, gid, mode, buffer, do_unlink);
    348 }
    349 
    350 static bool do_recv(int s, const char* path, std::vector<char>& buffer) {
    351     __android_log_security_bswrite(SEC_TAG_ADB_RECV_FILE, path);
    352 
    353     int fd = adb_open(path, O_RDONLY | O_CLOEXEC);
    354     if (fd < 0) {
    355         SendSyncFailErrno(s, "open failed");
    356         return false;
    357     }
    358 
    359     syncmsg msg;
    360     msg.data.id = ID_DATA;
    361     while (true) {
    362         int r = adb_read(fd, &buffer[0], buffer.size());
    363         if (r <= 0) {
    364             if (r == 0) break;
    365             SendSyncFailErrno(s, "read failed");
    366             adb_close(fd);
    367             return false;
    368         }
    369         msg.data.size = r;
    370         if (!WriteFdExactly(s, &msg.data, sizeof(msg.data)) || !WriteFdExactly(s, &buffer[0], r)) {
    371             adb_close(fd);
    372             return false;
    373         }
    374     }
    375 
    376     adb_close(fd);
    377 
    378     msg.data.id = ID_DONE;
    379     msg.data.size = 0;
    380     return WriteFdExactly(s, &msg.data, sizeof(msg.data));
    381 }
    382 
    383 static bool handle_sync_command(int fd, std::vector<char>& buffer) {
    384     D("sync: waiting for request");
    385 
    386     SyncRequest request;
    387     if (!ReadFdExactly(fd, &request, sizeof(request))) {
    388         SendSyncFail(fd, "command read failure");
    389         return false;
    390     }
    391     size_t path_length = request.path_length;
    392     if (path_length > 1024) {
    393         SendSyncFail(fd, "path too long");
    394         return false;
    395     }
    396     char name[1025];
    397     if (!ReadFdExactly(fd, name, path_length)) {
    398         SendSyncFail(fd, "filename read failure");
    399         return false;
    400     }
    401     name[path_length] = 0;
    402 
    403     const char* id = reinterpret_cast<const char*>(&request.id);
    404     D("sync: '%.4s' '%s'", id, name);
    405 
    406     switch (request.id) {
    407       case ID_STAT:
    408         if (!do_stat(fd, name)) return false;
    409         break;
    410       case ID_LIST:
    411         if (!do_list(fd, name)) return false;
    412         break;
    413       case ID_SEND:
    414         if (!do_send(fd, name, buffer)) return false;
    415         break;
    416       case ID_RECV:
    417         if (!do_recv(fd, name, buffer)) return false;
    418         break;
    419       case ID_QUIT:
    420         return false;
    421       default:
    422         SendSyncFail(fd, android::base::StringPrintf("unknown command '%.4s' (%08x)",
    423                                                      id, request.id));
    424         return false;
    425     }
    426 
    427     return true;
    428 }
    429 
    430 void file_sync_service(int fd, void* cookie) {
    431     std::vector<char> buffer(SYNC_DATA_MAX);
    432 
    433     while (handle_sync_command(fd, buffer)) {
    434     }
    435 
    436     D("sync: done");
    437     adb_close(fd);
    438 }
    439