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