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