1 /* 2 ** Copyright 2008, 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 "installd.h" 18 19 int create_pkg_path_in_dir(char path[PKG_PATH_MAX], 20 const dir_rec_t* dir, 21 const char* pkgname, 22 const char* postfix) 23 { 24 const size_t postfix_len = strlen(postfix); 25 26 const size_t pkgname_len = strlen(pkgname); 27 if (pkgname_len > PKG_NAME_MAX) { 28 return -1; 29 } 30 31 if (is_valid_package_name(pkgname) < 0) { 32 return -1; 33 } 34 35 if ((pkgname_len + dir->len + postfix_len) >= PKG_PATH_MAX) { 36 return -1; 37 } 38 39 char *dst = path; 40 size_t dst_size = PKG_PATH_MAX; 41 42 if (append_and_increment(&dst, dir->path, &dst_size) < 0 43 || append_and_increment(&dst, pkgname, &dst_size) < 0 44 || append_and_increment(&dst, postfix, &dst_size) < 0) { 45 LOGE("Error building APK path"); 46 return -1; 47 } 48 49 return 0; 50 } 51 52 /** 53 * Create the package path name for a given package name with a postfix for 54 * a certain persona. Returns 0 on success, and -1 on failure. 55 */ 56 int create_pkg_path(char path[PKG_PATH_MAX], 57 const char *pkgname, 58 const char *postfix, 59 uid_t persona) 60 { 61 size_t uid_len; 62 char* persona_prefix; 63 if (persona == 0) { 64 persona_prefix = PRIMARY_USER_PREFIX; 65 uid_len = 0; 66 } else { 67 persona_prefix = SECONDARY_USER_PREFIX; 68 uid_len = snprintf(NULL, 0, "%d", persona); 69 } 70 71 const size_t prefix_len = android_data_dir.len + strlen(persona_prefix) + uid_len + 1 /*slash*/; 72 char prefix[prefix_len + 1]; 73 74 char *dst = prefix; 75 size_t dst_size = sizeof(prefix); 76 77 if (append_and_increment(&dst, android_data_dir.path, &dst_size) < 0 78 || append_and_increment(&dst, persona_prefix, &dst_size) < 0) { 79 LOGE("Error building prefix for APK path"); 80 return -1; 81 } 82 83 if (persona != 0) { 84 int ret = snprintf(dst, dst_size, "%d/", persona); 85 if (ret < 0 || (size_t) ret != uid_len + 1) { 86 LOGW("Error appending UID to APK path"); 87 return -1; 88 } 89 } 90 91 dir_rec_t dir; 92 dir.path = prefix; 93 dir.len = prefix_len; 94 95 return create_pkg_path_in_dir(path, &dir, pkgname, postfix); 96 } 97 98 /** 99 * Create the path name for user data for a certain persona. 100 * Returns 0 on success, and -1 on failure. 101 */ 102 int create_persona_path(char path[PKG_PATH_MAX], 103 uid_t persona) 104 { 105 size_t uid_len; 106 char* persona_prefix; 107 if (persona == 0) { 108 persona_prefix = PRIMARY_USER_PREFIX; 109 uid_len = 0; 110 } else { 111 persona_prefix = SECONDARY_USER_PREFIX; 112 uid_len = snprintf(NULL, 0, "%d/", persona); 113 } 114 115 char *dst = path; 116 size_t dst_size = PKG_PATH_MAX; 117 118 if (append_and_increment(&dst, android_data_dir.path, &dst_size) < 0 119 || append_and_increment(&dst, persona_prefix, &dst_size) < 0) { 120 LOGE("Error building prefix for user path"); 121 return -1; 122 } 123 124 if (persona != 0) { 125 if (dst_size < uid_len + 1) { 126 LOGE("Error building user path"); 127 return -1; 128 } 129 int ret = snprintf(dst, dst_size, "%d/", persona); 130 if (ret < 0 || (size_t) ret != uid_len) { 131 LOGE("Error appending persona id to path"); 132 return -1; 133 } 134 } 135 return 0; 136 } 137 138 int create_move_path(char path[PKG_PATH_MAX], 139 const char* pkgname, 140 const char* leaf, 141 uid_t persona) 142 { 143 if ((android_data_dir.len + strlen(PRIMARY_USER_PREFIX) + strlen(pkgname) + strlen(leaf) + 1) 144 >= PKG_PATH_MAX) { 145 return -1; 146 } 147 148 sprintf(path, "%s%s%s/%s", android_data_dir.path, PRIMARY_USER_PREFIX, pkgname, leaf); 149 return 0; 150 } 151 152 /** 153 * Checks whether the package name is valid. Returns -1 on error and 154 * 0 on success. 155 */ 156 int is_valid_package_name(const char* pkgname) { 157 const char *x = pkgname; 158 int alpha = -1; 159 160 while (*x) { 161 if (isalnum(*x) || (*x == '_')) { 162 /* alphanumeric or underscore are fine */ 163 } else if (*x == '.') { 164 if ((x == pkgname) || (x[1] == '.') || (x[1] == 0)) { 165 /* periods must not be first, last, or doubled */ 166 LOGE("invalid package name '%s'\n", pkgname); 167 return -1; 168 } 169 } else if (*x == '-') { 170 /* Suffix -X is fine to let versioning of packages. 171 But whatever follows should be alphanumeric.*/ 172 alpha = 1; 173 } else { 174 /* anything not A-Z, a-z, 0-9, _, or . is invalid */ 175 LOGE("invalid package name '%s'\n", pkgname); 176 return -1; 177 } 178 179 x++; 180 } 181 182 if (alpha == 1) { 183 // Skip current character 184 x++; 185 while (*x) { 186 if (!isalnum(*x)) { 187 LOGE("invalid package name '%s' should include only numbers after -\n", pkgname); 188 return -1; 189 } 190 x++; 191 } 192 } 193 194 return 0; 195 } 196 197 static int _delete_dir_contents(DIR *d, const char *ignore) 198 { 199 int result = 0; 200 struct dirent *de; 201 int dfd; 202 203 dfd = dirfd(d); 204 205 if (dfd < 0) return -1; 206 207 while ((de = readdir(d))) { 208 const char *name = de->d_name; 209 210 /* skip the ignore name if provided */ 211 if (ignore && !strcmp(name, ignore)) continue; 212 213 if (de->d_type == DT_DIR) { 214 int r, subfd; 215 DIR *subdir; 216 217 /* always skip "." and ".." */ 218 if (name[0] == '.') { 219 if (name[1] == 0) continue; 220 if ((name[1] == '.') && (name[2] == 0)) continue; 221 } 222 223 subfd = openat(dfd, name, O_RDONLY | O_DIRECTORY); 224 if (subfd < 0) { 225 LOGE("Couldn't openat %s: %s\n", name, strerror(errno)); 226 result = -1; 227 continue; 228 } 229 subdir = fdopendir(subfd); 230 if (subdir == NULL) { 231 LOGE("Couldn't fdopendir %s: %s\n", name, strerror(errno)); 232 close(subfd); 233 result = -1; 234 continue; 235 } 236 if (_delete_dir_contents(subdir, 0)) { 237 result = -1; 238 } 239 closedir(subdir); 240 if (unlinkat(dfd, name, AT_REMOVEDIR) < 0) { 241 LOGE("Couldn't unlinkat %s: %s\n", name, strerror(errno)); 242 result = -1; 243 } 244 } else { 245 if (unlinkat(dfd, name, 0) < 0) { 246 LOGE("Couldn't unlinkat %s: %s\n", name, strerror(errno)); 247 result = -1; 248 } 249 } 250 } 251 252 return result; 253 } 254 255 int delete_dir_contents(const char *pathname, 256 int also_delete_dir, 257 const char *ignore) 258 { 259 int res = 0; 260 DIR *d; 261 262 d = opendir(pathname); 263 if (d == NULL) { 264 LOGE("Couldn't opendir %s: %s\n", pathname, strerror(errno)); 265 return -errno; 266 } 267 res = _delete_dir_contents(d, ignore); 268 closedir(d); 269 if (also_delete_dir) { 270 if (rmdir(pathname)) { 271 LOGE("Couldn't rmdir %s: %s\n", pathname, strerror(errno)); 272 res = -1; 273 } 274 } 275 return res; 276 } 277 278 int delete_dir_contents_fd(int dfd, const char *name) 279 { 280 int fd, res; 281 DIR *d; 282 283 fd = openat(dfd, name, O_RDONLY | O_DIRECTORY); 284 if (fd < 0) { 285 LOGE("Couldn't openat %s: %s\n", name, strerror(errno)); 286 return -1; 287 } 288 d = fdopendir(fd); 289 if (d == NULL) { 290 LOGE("Couldn't fdopendir %s: %s\n", name, strerror(errno)); 291 close(fd); 292 return -1; 293 } 294 res = _delete_dir_contents(d, 0); 295 closedir(d); 296 return res; 297 } 298 299 /** 300 * Checks whether a path points to a system app (.apk file). Returns 0 301 * if it is a system app or -1 if it is not. 302 */ 303 int validate_system_app_path(const char* path) { 304 size_t i; 305 306 for (i = 0; i < android_system_dirs.count; i++) { 307 const size_t dir_len = android_system_dirs.dirs[i].len; 308 if (!strncmp(path, android_system_dirs.dirs[i].path, dir_len)) { 309 if (path[dir_len] == '.' || strchr(path + dir_len, '/') != NULL) { 310 LOGE("invalid system apk path '%s' (trickery)\n", path); 311 return -1; 312 } 313 return 0; 314 } 315 } 316 317 return -1; 318 } 319 320 /** 321 * Get the contents of a environment variable that contains a path. Caller 322 * owns the string that is inserted into the directory record. Returns 323 * 0 on success and -1 on error. 324 */ 325 int get_path_from_env(dir_rec_t* rec, const char* var) { 326 const char* path = getenv(var); 327 int ret = get_path_from_string(rec, path); 328 if (ret < 0) { 329 LOGW("Problem finding value for environment variable %s\n", var); 330 } 331 return ret; 332 } 333 334 /** 335 * Puts the string into the record as a directory. Appends '/' to the end 336 * of all paths. Caller owns the string that is inserted into the directory 337 * record. A null value will result in an error. 338 * 339 * Returns 0 on success and -1 on error. 340 */ 341 int get_path_from_string(dir_rec_t* rec, const char* path) { 342 if (path == NULL) { 343 return -1; 344 } else { 345 const size_t path_len = strlen(path); 346 if (path_len <= 0) { 347 return -1; 348 } 349 350 // Make sure path is absolute. 351 if (path[0] != '/') { 352 return -1; 353 } 354 355 if (path[path_len - 1] == '/') { 356 // Path ends with a forward slash. Make our own copy. 357 358 rec->path = strdup(path); 359 if (rec->path == NULL) { 360 return -1; 361 } 362 363 rec->len = path_len; 364 } else { 365 // Path does not end with a slash. Generate a new string. 366 char *dst; 367 368 // Add space for slash and terminating null. 369 size_t dst_size = path_len + 2; 370 371 rec->path = malloc(dst_size); 372 if (rec->path == NULL) { 373 return -1; 374 } 375 376 dst = rec->path; 377 378 if (append_and_increment(&dst, path, &dst_size) < 0 379 || append_and_increment(&dst, "/", &dst_size)) { 380 LOGE("Error canonicalizing path"); 381 return -1; 382 } 383 384 rec->len = dst - rec->path; 385 } 386 } 387 return 0; 388 } 389 390 int copy_and_append(dir_rec_t* dst, const dir_rec_t* src, const char* suffix) { 391 dst->len = src->len + strlen(suffix); 392 const size_t dstSize = dst->len + 1; 393 dst->path = (char*) malloc(dstSize); 394 395 if (dst->path == NULL 396 || snprintf(dst->path, dstSize, "%s%s", src->path, suffix) 397 != (ssize_t) dst->len) { 398 LOGE("Could not allocate memory to hold appended path; aborting\n"); 399 return -1; 400 } 401 402 return 0; 403 } 404 405 /** 406 * Check whether path points to a valid path for an APK file. An ASEC 407 * directory is allowed to have one level of subdirectory names. Returns -1 408 * when an invalid path is encountered and 0 when a valid path is encountered. 409 */ 410 int validate_apk_path(const char *path) 411 { 412 int allowsubdir = 0; 413 char *subdir = NULL; 414 size_t dir_len; 415 size_t path_len; 416 417 if (!strncmp(path, android_app_dir.path, android_app_dir.len)) { 418 dir_len = android_app_dir.len; 419 } else if (!strncmp(path, android_app_private_dir.path, android_app_private_dir.len)) { 420 dir_len = android_app_private_dir.len; 421 } else if (!strncmp(path, android_asec_dir.path, android_asec_dir.len)) { 422 dir_len = android_asec_dir.len; 423 allowsubdir = 1; 424 } else { 425 LOGE("invalid apk path '%s' (bad prefix)\n", path); 426 return -1; 427 } 428 429 path_len = strlen(path); 430 431 /* 432 * Only allow the path to have a subdirectory if it's been marked as being allowed. 433 */ 434 if ((subdir = strchr(path + dir_len, '/')) != NULL) { 435 ++subdir; 436 if (!allowsubdir 437 || (path_len > (size_t) (subdir - path) && (strchr(subdir, '/') != NULL))) { 438 LOGE("invalid apk path '%s' (subdir?)\n", path); 439 return -1; 440 } 441 } 442 443 /* 444 * Directories can't have a period directly after the directory markers 445 * to prevent ".." 446 */ 447 if (path[dir_len] == '.' 448 || (subdir != NULL && ((*subdir == '.') || (strchr(subdir, '/') != NULL)))) { 449 LOGE("invalid apk path '%s' (trickery)\n", path); 450 return -1; 451 } 452 453 return 0; 454 } 455 456 int append_and_increment(char** dst, const char* src, size_t* dst_size) { 457 ssize_t ret = strlcpy(*dst, src, *dst_size); 458 if (ret < 0 || (size_t) ret >= *dst_size) { 459 return -1; 460 } 461 *dst += ret; 462 *dst_size -= ret; 463 return 0; 464 } 465 466 char *build_string2(char *s1, char *s2) { 467 if (s1 == NULL || s2 == NULL) return NULL; 468 469 int len_s1 = strlen(s1); 470 int len_s2 = strlen(s2); 471 int len = len_s1 + len_s2 + 1; 472 char *result = malloc(len); 473 if (result == NULL) return NULL; 474 475 strcpy(result, s1); 476 strcpy(result + len_s1, s2); 477 478 return result; 479 } 480 481 char *build_string3(char *s1, char *s2, char *s3) { 482 if (s1 == NULL || s2 == NULL || s3 == NULL) return NULL; 483 484 int len_s1 = strlen(s1); 485 int len_s2 = strlen(s2); 486 int len_s3 = strlen(s3); 487 int len = len_s1 + len_s2 + len_s3 + 1; 488 char *result = malloc(len); 489 if (result == NULL) return NULL; 490 491 strcpy(result, s1); 492 strcpy(result + len_s1, s2); 493 strcpy(result + len_s1 + len_s2, s3); 494 495 return result; 496 } 497