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 "daemon/file_sync_service.h" 20 21 #include "sysdeps.h" 22 23 #include <dirent.h> 24 #include <errno.h> 25 #include <stdio.h> 26 #include <stdlib.h> 27 #include <string.h> 28 #include <sys/stat.h> 29 #include <sys/time.h> 30 #include <sys/types.h> 31 #include <unistd.h> 32 #include <utime.h> 33 34 #include <memory> 35 #include <optional> 36 #include <span> 37 #include <string> 38 #include <variant> 39 #include <vector> 40 41 #include <android-base/file.h> 42 #include <android-base/macros.h> 43 #include <android-base/stringprintf.h> 44 #include <android-base/strings.h> 45 46 #include <adbd_fs.h> 47 48 // Needed for __android_log_security_bswrite. 49 #include <private/android_logger.h> 50 51 #if defined(__ANDROID__) 52 #include <linux/capability.h> 53 #include <selinux/android.h> 54 #include <sys/xattr.h> 55 #endif 56 57 #include "adb.h" 58 #include "adb_io.h" 59 #include "adb_trace.h" 60 #include "adb_utils.h" 61 #include "compression_utils.h" 62 #include "file_sync_protocol.h" 63 #include "security_log_tags.h" 64 #include "sysdeps/errno.h" 65 66 using android::base::borrowed_fd; 67 using android::base::Dirname; 68 using android::base::Realpath; 69 using android::base::StringPrintf; 70 71 static bool should_use_fs_config(const std::string& path) { 72 #if defined(__ANDROID__) 73 // TODO: use fs_config to configure permissions on /data too. 74 return !android::base::StartsWith(path, "/data/"); 75 #else 76 UNUSED(path); 77 return false; 78 #endif 79 } 80 81 static bool update_capabilities(const char* path, uint64_t capabilities) { 82 #if defined(__ANDROID__) 83 if (capabilities == 0) { 84 // Ensure we clean up in case the capabilities weren't 0 in the past. 85 removexattr(path, XATTR_NAME_CAPS); 86 return true; 87 } 88 89 vfs_cap_data cap_data = {}; 90 cap_data.magic_etc = VFS_CAP_REVISION_2 | VFS_CAP_FLAGS_EFFECTIVE; 91 cap_data.data[0].permitted = (capabilities & 0xffffffff); 92 cap_data.data[0].inheritable = 0; 93 cap_data.data[1].permitted = (capabilities >> 32); 94 cap_data.data[1].inheritable = 0; 95 return setxattr(path, XATTR_NAME_CAPS, &cap_data, sizeof(cap_data), 0) != -1; 96 #else 97 UNUSED(path, capabilities); 98 return true; 99 #endif 100 } 101 102 static bool secure_mkdirs(const std::string& path) { 103 if (path[0] != '/') return false; 104 105 std::vector<std::string> path_components = android::base::Split(path, "/"); 106 std::string partial_path; 107 for (const auto& path_component : path_components) { 108 uid_t uid = -1; 109 gid_t gid = -1; 110 mode_t mode = 0775; 111 uint64_t capabilities = 0; 112 113 if (path_component.empty()) { 114 continue; 115 } 116 117 if (partial_path.empty() || partial_path.back() != OS_PATH_SEPARATOR) { 118 partial_path += OS_PATH_SEPARATOR; 119 } 120 partial_path += path_component; 121 122 if (should_use_fs_config(partial_path)) { 123 adbd_fs_config(partial_path.c_str(), 1, nullptr, &uid, &gid, &mode, &capabilities); 124 } 125 if (adb_mkdir(partial_path.c_str(), mode) == -1) { 126 if (errno != EEXIST) { 127 return false; 128 } 129 } else { 130 if (chown(partial_path.c_str(), uid, gid) == -1) return false; 131 132 #if defined(__ANDROID__) 133 // Not all filesystems support setting SELinux labels. http://b/23530370. 134 selinux_android_restorecon(partial_path.c_str(), 0); 135 #endif 136 137 if (!update_capabilities(partial_path.c_str(), capabilities)) return false; 138 } 139 } 140 return true; 141 } 142 143 static bool do_lstat_v1(int s, const char* path) { 144 syncmsg msg = {}; 145 msg.stat_v1.id = ID_LSTAT_V1; 146 147 struct stat st = {}; 148 lstat(path, &st); 149 msg.stat_v1.mode = st.st_mode; 150 msg.stat_v1.size = st.st_size; 151 msg.stat_v1.mtime = st.st_mtime; 152 return WriteFdExactly(s, &msg.stat_v1, sizeof(msg.stat_v1)); 153 } 154 155 static bool do_stat_v2(int s, uint32_t id, const char* path) { 156 syncmsg msg = {}; 157 msg.stat_v2.id = id; 158 159 decltype(&stat) stat_fn; 160 if (id == ID_STAT_V2) { 161 stat_fn = stat; 162 } else { 163 stat_fn = lstat; 164 } 165 166 struct stat st = {}; 167 int rc = stat_fn(path, &st); 168 if (rc == -1) { 169 msg.stat_v2.error = errno_to_wire(errno); 170 } else { 171 msg.stat_v2.dev = st.st_dev; 172 msg.stat_v2.ino = st.st_ino; 173 msg.stat_v2.mode = st.st_mode; 174 msg.stat_v2.nlink = st.st_nlink; 175 msg.stat_v2.uid = st.st_uid; 176 msg.stat_v2.gid = st.st_gid; 177 msg.stat_v2.size = st.st_size; 178 msg.stat_v2.atime = st.st_atime; 179 msg.stat_v2.mtime = st.st_mtime; 180 msg.stat_v2.ctime = st.st_ctime; 181 } 182 183 return WriteFdExactly(s, &msg.stat_v2, sizeof(msg.stat_v2)); 184 } 185 186 template <bool v2> 187 static bool do_list(int s, const char* path) { 188 dirent* de; 189 190 using MessageType = 191 std::conditional_t<v2, decltype(syncmsg::dent_v2), decltype(syncmsg::dent_v1)>; 192 MessageType msg; 193 uint32_t msg_id; 194 if constexpr (v2) { 195 msg_id = ID_DENT_V2; 196 } else { 197 msg_id = ID_DENT_V1; 198 } 199 200 std::unique_ptr<DIR, int(*)(DIR*)> d(opendir(path), closedir); 201 if (!d) goto done; 202 203 while ((de = readdir(d.get()))) { 204 memset(&msg, 0, sizeof(msg)); 205 msg.id = msg_id; 206 207 std::string filename(StringPrintf("%s/%s", path, de->d_name)); 208 209 struct stat st; 210 if (lstat(filename.c_str(), &st) == 0) { 211 msg.mode = st.st_mode; 212 msg.size = st.st_size; 213 msg.mtime = st.st_mtime; 214 215 if constexpr (v2) { 216 msg.dev = st.st_dev; 217 msg.ino = st.st_ino; 218 msg.nlink = st.st_nlink; 219 msg.uid = st.st_uid; 220 msg.gid = st.st_gid; 221 msg.atime = st.st_atime; 222 msg.ctime = st.st_ctime; 223 } 224 } else { 225 if constexpr (v2) { 226 msg.error = errno; 227 } else { 228 continue; 229 } 230 } 231 232 size_t d_name_length = strlen(de->d_name); 233 msg.namelen = d_name_length; 234 235 if (!WriteFdExactly(s, &msg, sizeof(msg)) || 236 !WriteFdExactly(s, de->d_name, d_name_length)) { 237 return false; 238 } 239 } 240 241 done: 242 memset(&msg, 0, sizeof(msg)); 243 msg.id = ID_DONE; 244 return WriteFdExactly(s, &msg, sizeof(msg)); 245 } 246 247 static bool do_list_v1(int s, const char* path) { 248 return do_list<false>(s, path); 249 } 250 251 static bool do_list_v2(int s, const char* path) { 252 return do_list<true>(s, path); 253 } 254 255 // Make sure that SendFail from adb_io.cpp isn't accidentally used in this file. 256 #pragma GCC poison SendFail 257 258 static bool SendSyncFail(borrowed_fd fd, const std::string& reason) { 259 D("sync: failure: %s", reason.c_str()); 260 261 syncmsg msg; 262 msg.data.id = ID_FAIL; 263 msg.data.size = reason.size(); 264 return WriteFdExactly(fd, &msg.data, sizeof(msg.data)) && WriteFdExactly(fd, reason); 265 } 266 267 static bool SendSyncFailErrno(borrowed_fd fd, const std::string& reason) { 268 return SendSyncFail(fd, StringPrintf("%s: %s", reason.c_str(), strerror(errno))); 269 } 270 271 static bool handle_send_file_data(borrowed_fd s, unique_fd fd, uint32_t* timestamp, 272 CompressionType compression) { 273 syncmsg msg; 274 Block buffer(SYNC_DATA_MAX); 275 std::span<char> buffer_span(buffer.data(), buffer.size()); 276 std::variant<std::monostate, NullDecoder, BrotliDecoder, LZ4Decoder, ZstdDecoder> 277 decoder_storage; 278 Decoder* decoder = nullptr; 279 280 switch (compression) { 281 case CompressionType::None: 282 decoder = &decoder_storage.emplace<NullDecoder>(buffer_span); 283 break; 284 285 case CompressionType::Brotli: 286 decoder = &decoder_storage.emplace<BrotliDecoder>(buffer_span); 287 break; 288 289 case CompressionType::LZ4: 290 decoder = &decoder_storage.emplace<LZ4Decoder>(buffer_span); 291 break; 292 293 case CompressionType::Zstd: 294 decoder = &decoder_storage.emplace<ZstdDecoder>(buffer_span); 295 break; 296 297 case CompressionType::Any: 298 LOG(FATAL) << "unexpected CompressionType::Any"; 299 } 300 301 while (true) { 302 if (!ReadFdExactly(s, &msg.data, sizeof(msg.data))) return false; 303 304 if (msg.data.id == ID_DONE) { 305 *timestamp = msg.data.size; 306 decoder->Finish(); 307 } else if (msg.data.id == ID_DATA) { 308 Block block(msg.data.size); 309 if (!ReadFdExactly(s, block.data(), msg.data.size)) return false; 310 decoder->Append(std::move(block)); 311 } else { 312 SendSyncFail(s, "invalid data message"); 313 return false; 314 } 315 316 while (true) { 317 std::span<char> output; 318 DecodeResult result = decoder->Decode(&output); 319 if (result == DecodeResult::Error) { 320 SendSyncFailErrno(s, "decompress failed"); 321 return false; 322 } 323 324 // fd is -1 if the client is pushing with --dry-run. 325 if (fd != -1) { 326 if (!WriteFdExactly(fd, output.data(), output.size())) { 327 SendSyncFailErrno(s, "write failed"); 328 return false; 329 } 330 } 331 332 if (result == DecodeResult::NeedInput) { 333 break; 334 } else if (result == DecodeResult::MoreOutput) { 335 continue; 336 } else if (result == DecodeResult::Done) { 337 return true; 338 } else { 339 LOG(FATAL) << "invalid DecodeResult: " << static_cast<int>(result); 340 } 341 } 342 } 343 344 __builtin_unreachable(); 345 } 346 347 static bool handle_send_file(borrowed_fd s, const char* path, uint32_t* timestamp, uid_t uid, 348 gid_t gid, uint64_t capabilities, mode_t mode, 349 CompressionType compression, bool dry_run, std::vector<char>& buffer, 350 bool do_unlink) { 351 syncmsg msg; 352 unique_fd fd; 353 354 if (!dry_run) { 355 __android_log_security_bswrite(SEC_TAG_ADB_SEND_FILE, path); 356 fd.reset(adb_open_mode(path, O_WRONLY | O_CREAT | O_EXCL | O_CLOEXEC, mode)); 357 358 if (fd < 0 && errno == ENOENT) { 359 if (!secure_mkdirs(Dirname(path))) { 360 SendSyncFailErrno(s, "secure_mkdirs failed"); 361 goto fail; 362 } 363 fd.reset(adb_open_mode(path, O_WRONLY | O_CREAT | O_EXCL | O_CLOEXEC, mode)); 364 } 365 if (fd < 0 && errno == EEXIST) { 366 fd.reset(adb_open_mode(path, O_WRONLY | O_CLOEXEC, mode)); 367 } 368 if (fd < 0) { 369 SendSyncFailErrno(s, "couldn't create file"); 370 goto fail; 371 } else { 372 if (fchown(fd.get(), uid, gid) == -1) { 373 struct stat st; 374 std::string real_path; 375 376 // Only return failure if parent directory does not have S_ISGID bit set, 377 // if S_ISGID is set then file will inherit groupid from directory 378 if (!Realpath(path, &real_path) || lstat(Dirname(real_path).c_str(), &st) == -1 || 379 (S_ISDIR(st.st_mode) && (st.st_mode & S_ISGID) == 0)) { 380 SendSyncFailErrno(s, "fchown failed"); 381 goto fail; 382 } 383 } 384 385 #if defined(__ANDROID__) 386 // Not all filesystems support setting SELinux labels. http://b/23530370. 387 selinux_android_restorecon(path, 0); 388 #endif 389 390 // fchown clears the setuid bit - restore it if present. 391 // Ignore the result of calling fchmod. It's not supported 392 // by all filesystems, so we don't check for success. b/12441485 393 fchmod(fd.get(), mode); 394 } 395 396 int rc = posix_fadvise(fd.get(), 0, 0, 397 POSIX_FADV_SEQUENTIAL | POSIX_FADV_NOREUSE | POSIX_FADV_WILLNEED); 398 if (rc != 0) { 399 D("[ Failed to fadvise: %s ]", strerror(rc)); 400 } 401 } 402 403 if (!handle_send_file_data(s, std::move(fd), timestamp, compression)) { 404 goto fail; 405 } 406 407 if (!update_capabilities(path, capabilities)) { 408 SendSyncFailErrno(s, "update_capabilities failed"); 409 goto fail; 410 } 411 412 msg.status.id = ID_OKAY; 413 msg.status.msglen = 0; 414 return WriteFdExactly(s, &msg.status, sizeof(msg.status)); 415 416 fail: 417 // If there's a problem on the device, we'll send an ID_FAIL message and 418 // close the socket. Unfortunately the kernel will sometimes throw that 419 // data away if the other end keeps writing without reading (which is 420 // the case with old versions of adb). To maintain compatibility, keep 421 // reading and throwing away ID_DATA packets until the other side notices 422 // that we've reported an error. 423 while (true) { 424 if (!ReadFdExactly(s, &msg.data, sizeof(msg.data))) break; 425 426 if (msg.data.id == ID_DONE) { 427 break; 428 } else if (msg.data.id != ID_DATA) { 429 char id[5]; 430 memcpy(id, &msg.data.id, sizeof(msg.data.id)); 431 id[4] = '\0'; 432 D("handle_send_fail received unexpected id '%s' during failure", id); 433 break; 434 } 435 436 if (msg.data.size > buffer.size()) { 437 D("handle_send_fail received oversized packet of length '%u' during failure", 438 msg.data.size); 439 break; 440 } 441 442 if (!ReadFdExactly(s, &buffer[0], msg.data.size)) break; 443 } 444 445 if (do_unlink) adb_unlink(path); 446 return false; 447 } 448 449 #if defined(_WIN32) 450 extern bool handle_send_link(int s, const std::string& path, 451 uint32_t* timestamp, std::vector<char>& buffer) 452 __attribute__((error("no symlinks on Windows"))); 453 #else 454 static bool handle_send_link(int s, const std::string& path, uint32_t* timestamp, bool dry_run, 455 std::vector<char>& buffer) { 456 syncmsg msg; 457 458 if (!ReadFdExactly(s, &msg.data, sizeof(msg.data))) return false; 459 460 if (msg.data.id != ID_DATA) { 461 SendSyncFail(s, "invalid data message: expected ID_DATA"); 462 return false; 463 } 464 465 unsigned int len = msg.data.size; 466 if (len > buffer.size()) { // TODO: resize buffer? 467 SendSyncFail(s, "oversize data message"); 468 return false; 469 } 470 if (!ReadFdExactly(s, &buffer[0], len)) return false; 471 472 std::string buf_link; 473 if (!dry_run) { 474 if (!android::base::Readlink(path, &buf_link) || (buf_link != &buffer[0])) { 475 adb_unlink(path.c_str()); 476 auto ret = symlink(&buffer[0], path.c_str()); 477 if (ret && errno == ENOENT) { 478 if (!secure_mkdirs(Dirname(path))) { 479 SendSyncFailErrno(s, "secure_mkdirs failed"); 480 return false; 481 } 482 ret = symlink(&buffer[0], path.c_str()); 483 } 484 if (ret) { 485 SendSyncFailErrno(s, "symlink failed"); 486 return false; 487 } 488 } 489 } 490 491 if (!ReadFdExactly(s, &msg.data, sizeof(msg.data))) return false; 492 493 if (msg.data.id == ID_DONE) { 494 *timestamp = msg.data.size; 495 msg.status.id = ID_OKAY; 496 msg.status.msglen = 0; 497 if (!WriteFdExactly(s, &msg.status, sizeof(msg.status))) return false; 498 } else { 499 SendSyncFail(s, "invalid data message: expected ID_DONE"); 500 return false; 501 } 502 503 return true; 504 } 505 #endif 506 507 static bool send_impl(int s, const std::string& path, mode_t mode, CompressionType compression, 508 bool dry_run, std::vector<char>& buffer) { 509 // Don't delete files before copying if they are not "regular" or symlinks. 510 struct stat st; 511 bool do_unlink = false; 512 if (!dry_run) { 513 do_unlink = (lstat(path.c_str(), &st) == -1) || S_ISREG(st.st_mode) || 514 (S_ISLNK(st.st_mode) && !S_ISLNK(mode)); 515 } 516 if (do_unlink) { 517 adb_unlink(path.c_str()); 518 } 519 520 bool result; 521 uint32_t timestamp; 522 if (S_ISLNK(mode)) { 523 result = handle_send_link(s, path, ×tamp, dry_run, buffer); 524 } else { 525 // Copy user permission bits to "group" and "other" permissions. 526 mode &= 0777; 527 mode |= ((mode >> 3) & 0070); 528 mode |= ((mode >> 3) & 0007); 529 530 uid_t uid = -1; 531 gid_t gid = -1; 532 uint64_t capabilities = 0; 533 if (should_use_fs_config(path) && !dry_run) { 534 adbd_fs_config(path.c_str(), 0, nullptr, &uid, &gid, &mode, &capabilities); 535 } 536 537 result = handle_send_file(s, path.c_str(), ×tamp, uid, gid, capabilities, mode, 538 compression, dry_run, buffer, do_unlink); 539 } 540 541 if (!result) { 542 return false; 543 } 544 545 struct timeval tv[2]; 546 tv[0].tv_sec = timestamp; 547 tv[0].tv_usec = 0; 548 tv[1].tv_sec = timestamp; 549 tv[1].tv_usec = 0; 550 lutimes(path.c_str(), tv); 551 return true; 552 } 553 554 static bool do_send_v1(int s, const std::string& spec, std::vector<char>& buffer) { 555 // 'spec' is of the form "/some/path,0755". Break it up. 556 size_t comma = spec.find_last_of(','); 557 if (comma == std::string::npos) { 558 SendSyncFail(s, "missing , in ID_SEND_V1"); 559 return false; 560 } 561 562 std::string path = spec.substr(0, comma); 563 564 errno = 0; 565 mode_t mode = strtoul(spec.substr(comma + 1).c_str(), nullptr, 0); 566 if (errno != 0) { 567 SendSyncFail(s, "bad mode"); 568 return false; 569 } 570 571 return send_impl(s, path, mode, CompressionType::None, false, buffer); 572 } 573 574 static bool do_send_v2(int s, const std::string& path, std::vector<char>& buffer) { 575 // Read the setup packet. 576 syncmsg msg; 577 int rc = ReadFdExactly(s, &msg.send_v2_setup, sizeof(msg.send_v2_setup)); 578 if (rc == 0) { 579 LOG(ERROR) << "failed to read send_v2 setup packet: EOF"; 580 return false; 581 } else if (rc < 0) { 582 PLOG(ERROR) << "failed to read send_v2 setup packet"; 583 } 584 585 bool dry_run = false; 586 std::optional<CompressionType> compression; 587 588 uint32_t orig_flags = msg.send_v2_setup.flags; 589 if (msg.send_v2_setup.flags & kSyncFlagBrotli) { 590 msg.send_v2_setup.flags &= ~kSyncFlagBrotli; 591 if (compression) { 592 SendSyncFail(s, android::base::StringPrintf("multiple compression flags received: %d", 593 orig_flags)); 594 return false; 595 } 596 compression = CompressionType::Brotli; 597 } 598 if (msg.send_v2_setup.flags & kSyncFlagLZ4) { 599 msg.send_v2_setup.flags &= ~kSyncFlagLZ4; 600 if (compression) { 601 SendSyncFail(s, android::base::StringPrintf("multiple compression flags received: %d", 602 orig_flags)); 603 return false; 604 } 605 compression = CompressionType::LZ4; 606 } 607 if (msg.send_v2_setup.flags & kSyncFlagZstd) { 608 msg.send_v2_setup.flags &= ~kSyncFlagZstd; 609 if (compression) { 610 SendSyncFail(s, android::base::StringPrintf("multiple compression flags received: %d", 611 orig_flags)); 612 return false; 613 } 614 compression = CompressionType::Zstd; 615 } 616 if (msg.send_v2_setup.flags & kSyncFlagDryRun) { 617 msg.send_v2_setup.flags &= ~kSyncFlagDryRun; 618 dry_run = true; 619 } 620 621 if (msg.send_v2_setup.flags) { 622 SendSyncFail(s, android::base::StringPrintf("unknown flags: %d", msg.send_v2_setup.flags)); 623 return false; 624 } 625 626 errno = 0; 627 return send_impl(s, path, msg.send_v2_setup.mode, compression.value_or(CompressionType::None), 628 dry_run, buffer); 629 } 630 631 static bool recv_impl(borrowed_fd s, const char* path, CompressionType compression, 632 std::vector<char>& buffer) { 633 __android_log_security_bswrite(SEC_TAG_ADB_RECV_FILE, path); 634 635 unique_fd fd(adb_open(path, O_RDONLY | O_CLOEXEC)); 636 if (fd < 0) { 637 SendSyncFailErrno(s, "open failed"); 638 return false; 639 } 640 641 int rc = posix_fadvise(fd.get(), 0, 0, POSIX_FADV_SEQUENTIAL | POSIX_FADV_NOREUSE); 642 if (rc != 0) { 643 D("[ Failed to fadvise: %s ]", strerror(rc)); 644 } 645 646 syncmsg msg; 647 msg.data.id = ID_DATA; 648 649 std::variant<std::monostate, NullEncoder, BrotliEncoder, LZ4Encoder, ZstdEncoder> 650 encoder_storage; 651 Encoder* encoder; 652 653 switch (compression) { 654 case CompressionType::None: 655 encoder = &encoder_storage.emplace<NullEncoder>(SYNC_DATA_MAX); 656 break; 657 658 case CompressionType::Brotli: 659 encoder = &encoder_storage.emplace<BrotliEncoder>(SYNC_DATA_MAX); 660 break; 661 662 case CompressionType::LZ4: 663 encoder = &encoder_storage.emplace<LZ4Encoder>(SYNC_DATA_MAX); 664 break; 665 666 case CompressionType::Zstd: 667 encoder = &encoder_storage.emplace<ZstdEncoder>(SYNC_DATA_MAX); 668 break; 669 670 case CompressionType::Any: 671 LOG(FATAL) << "unexpected CompressionType::Any"; 672 } 673 674 bool sending = true; 675 while (sending) { 676 Block input(SYNC_DATA_MAX); 677 int r = adb_read(fd.get(), input.data(), input.size()); 678 if (r < 0) { 679 SendSyncFailErrno(s, "read failed"); 680 return false; 681 } 682 683 if (r == 0) { 684 encoder->Finish(); 685 } else { 686 input.resize(r); 687 encoder->Append(std::move(input)); 688 } 689 690 while (true) { 691 Block output; 692 EncodeResult result = encoder->Encode(&output); 693 if (result == EncodeResult::Error) { 694 SendSyncFailErrno(s, "compress failed"); 695 return false; 696 } 697 698 if (!output.empty()) { 699 msg.data.size = output.size(); 700 if (!WriteFdExactly(s, &msg.data, sizeof(msg.data)) || 701 !WriteFdExactly(s, output.data(), output.size())) { 702 return false; 703 } 704 } 705 706 if (result == EncodeResult::Done) { 707 sending = false; 708 break; 709 } else if (result == EncodeResult::NeedInput) { 710 break; 711 } else if (result == EncodeResult::MoreOutput) { 712 continue; 713 } 714 } 715 } 716 717 msg.data.id = ID_DONE; 718 msg.data.size = 0; 719 return WriteFdExactly(s, &msg.data, sizeof(msg.data)); 720 } 721 722 static bool do_recv_v1(borrowed_fd s, const char* path, std::vector<char>& buffer) { 723 return recv_impl(s, path, CompressionType::None, buffer); 724 } 725 726 static bool do_recv_v2(borrowed_fd s, const char* path, std::vector<char>& buffer) { 727 syncmsg msg; 728 // Read the setup packet. 729 int rc = ReadFdExactly(s, &msg.recv_v2_setup, sizeof(msg.recv_v2_setup)); 730 if (rc == 0) { 731 LOG(ERROR) << "failed to read recv_v2 setup packet: EOF"; 732 return false; 733 } else if (rc < 0) { 734 PLOG(ERROR) << "failed to read recv_v2 setup packet"; 735 } 736 737 std::optional<CompressionType> compression; 738 uint32_t orig_flags = msg.recv_v2_setup.flags; 739 if (msg.recv_v2_setup.flags & kSyncFlagBrotli) { 740 msg.recv_v2_setup.flags &= ~kSyncFlagBrotli; 741 if (compression) { 742 SendSyncFail(s, android::base::StringPrintf("multiple compression flags received: %d", 743 orig_flags)); 744 return false; 745 } 746 compression = CompressionType::Brotli; 747 } 748 if (msg.recv_v2_setup.flags & kSyncFlagLZ4) { 749 msg.recv_v2_setup.flags &= ~kSyncFlagLZ4; 750 if (compression) { 751 SendSyncFail(s, android::base::StringPrintf("multiple compression flags received: %d", 752 orig_flags)); 753 return false; 754 } 755 compression = CompressionType::LZ4; 756 } 757 if (msg.recv_v2_setup.flags & kSyncFlagZstd) { 758 msg.recv_v2_setup.flags &= ~kSyncFlagZstd; 759 if (compression) { 760 SendSyncFail(s, android::base::StringPrintf("multiple compression flags received: %d", 761 orig_flags)); 762 return false; 763 } 764 compression = CompressionType::Zstd; 765 } 766 767 if (msg.recv_v2_setup.flags) { 768 SendSyncFail(s, android::base::StringPrintf("unknown flags: %d", msg.recv_v2_setup.flags)); 769 return false; 770 } 771 772 return recv_impl(s, path, compression.value_or(CompressionType::None), buffer); 773 } 774 775 static const char* sync_id_to_name(uint32_t id) { 776 switch (id) { 777 case ID_LSTAT_V1: 778 return "lstat_v1"; 779 case ID_LSTAT_V2: 780 return "lstat_v2"; 781 case ID_STAT_V2: 782 return "stat_v2"; 783 case ID_LIST_V1: 784 return "list_v1"; 785 case ID_LIST_V2: 786 return "list_v2"; 787 case ID_SEND_V1: 788 return "send_v1"; 789 case ID_SEND_V2: 790 return "send_v2"; 791 case ID_RECV_V1: 792 return "recv_v1"; 793 case ID_RECV_V2: 794 return "recv_v2"; 795 case ID_QUIT: 796 return "quit"; 797 default: 798 return "???"; 799 } 800 } 801 802 static bool handle_sync_command(int fd, std::vector<char>& buffer) { 803 D("sync: waiting for request"); 804 805 SyncRequest request; 806 if (!ReadFdExactly(fd, &request, sizeof(request))) { 807 SendSyncFail(fd, "command read failure"); 808 return false; 809 } 810 size_t path_length = request.path_length; 811 if (path_length > 1024) { 812 SendSyncFail(fd, "path too long"); 813 return false; 814 } 815 char name[1025]; 816 if (!ReadFdExactly(fd, name, path_length)) { 817 SendSyncFail(fd, "filename read failure"); 818 return false; 819 } 820 name[path_length] = 0; 821 822 std::string id_name = sync_id_to_name(request.id); 823 824 D("sync: %s('%s')", id_name.c_str(), name); 825 switch (request.id) { 826 case ID_LSTAT_V1: 827 if (!do_lstat_v1(fd, name)) return false; 828 break; 829 case ID_LSTAT_V2: 830 case ID_STAT_V2: 831 if (!do_stat_v2(fd, request.id, name)) return false; 832 break; 833 case ID_LIST_V1: 834 if (!do_list_v1(fd, name)) return false; 835 break; 836 case ID_LIST_V2: 837 if (!do_list_v2(fd, name)) return false; 838 break; 839 case ID_SEND_V1: 840 if (!do_send_v1(fd, name, buffer)) return false; 841 break; 842 case ID_SEND_V2: 843 if (!do_send_v2(fd, name, buffer)) return false; 844 break; 845 case ID_RECV_V1: 846 if (!do_recv_v1(fd, name, buffer)) return false; 847 break; 848 case ID_RECV_V2: 849 if (!do_recv_v2(fd, name, buffer)) return false; 850 break; 851 case ID_QUIT: 852 return false; 853 default: 854 SendSyncFail(fd, StringPrintf("unknown command %08x", request.id)); 855 return false; 856 } 857 858 return true; 859 } 860 861 void file_sync_service(unique_fd fd) { 862 std::vector<char> buffer(SYNC_DATA_MAX); 863 864 while (handle_sync_command(fd.get(), buffer)) { 865 } 866 867 D("sync: done"); 868 } 869