• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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, &timestamp, 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(), &timestamp, 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