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