asocket* create_local_service_socket(const char* name, const atransport* transport) { #if !ADB_HOST if (!strcmp(name, "jdwp")) { return create_jdwp_service_socket(); } if (!strcmp(name, "track-jdwp")) { return create_jdwp_tracker_service_socket(); } #endif int fd = service_to_fd(name, transport); if (fd < 0) { return nullptr; } asocket* s = create_local_socket(fd); D("LS(%d): bound to '%s' via %d", s->id, name, fd); #if !ADB_HOST if ((!strncmp(name, "root:", 5) && getuid() != 0 && __android_log_is_debuggable()) || (!strncmp(name, "unroot:", 7) && getuid() == 0) || !strncmp(name, "usb:", 4) || !strncmp(name, "tcpip:", 6)) { D("LS(%d): enabling exit_on_close", s->id); s->exit_on_close = 1; } #endif return s; }
static bool should_drop_privileges() { // "adb root" not allowed, always drop privileges. if (!ALLOW_ADBD_ROOT && !is_device_unlocked()) return true; // The properties that affect `adb root` and `adb unroot` are ro.secure and // ro.debuggable. In this context the names don't make the expected behavior // particularly obvious. // // ro.debuggable: // Allowed to become root, but not necessarily the default. Set to 1 on // eng and userdebug builds. // // ro.secure: // Drop privileges by default. Set to 1 on userdebug and user builds. bool ro_secure = android::base::GetBoolProperty("ro.secure", true); bool ro_debuggable = __android_log_is_debuggable(); // Drop privileges if ro.secure is set... bool drop = ro_secure; // ... except "adb root" lets you keep privileges in a debuggable build. std::string prop = android::base::GetProperty("service.adb.root", ""); bool adb_root = (prop == "1"); bool adb_unroot = (prop == "0"); if (ro_debuggable && adb_root) { drop = false; } // ... and "adb unroot" lets you explicitly drop privileges. if (adb_unroot) { drop = true; } return drop; }
static void drop_capabilities_bounding_set_if_needed(struct minijail *j) { if (ALLOW_ADBD_ROOT || is_device_unlocked()) { if (__android_log_is_debuggable()) { return; } } minijail_capbset_drop(j, CAP_TO_MASK(CAP_SETUID) | CAP_TO_MASK(CAP_SETGID)); }
/* get boolean with the logger twist that supports eng adjustments */ LIBLOG_ABI_PRIVATE bool __android_logger_property_get_bool(const char* key, int flag) { struct cache_property property = { { NULL, -1 }, { 0 } }; if (flag & BOOL_DEFAULT_FLAG_PERSIST) { char newkey[PROP_NAME_MAX]; snprintf(newkey, sizeof(newkey), "ro.%s", key); refresh_cache_property(&property, newkey); property.cache.pinfo = NULL; property.cache.serial = -1; snprintf(newkey, sizeof(newkey), "persist.%s", key); refresh_cache_property(&property, newkey); property.cache.pinfo = NULL; property.cache.serial = -1; } refresh_cache_property(&property, key); if (check_flag(property.property, "true")) { return true; } if (check_flag(property.property, "false")) { return false; } if (check_flag(property.property, "eng")) { flag |= BOOL_DEFAULT_FLAG_ENG; } /* this is really a "not" flag */ if (check_flag(property.property, "svelte")) { flag |= BOOL_DEFAULT_FLAG_SVELTE; } /* Sanity Check */ if (flag & (BOOL_DEFAULT_FLAG_SVELTE | BOOL_DEFAULT_FLAG_ENG)) { flag &= ~BOOL_DEFAULT_FLAG_TRUE_FALSE; flag |= BOOL_DEFAULT_TRUE; } if ((flag & BOOL_DEFAULT_FLAG_SVELTE) && __android_logger_property_get_bool("ro.config.low_ram", BOOL_DEFAULT_FALSE)) { return false; } if ((flag & BOOL_DEFAULT_FLAG_ENG) && !__android_log_is_debuggable()) { return false; } return (flag & BOOL_DEFAULT_FLAG_TRUE_FALSE) != BOOL_DEFAULT_FALSE; }
void restart_root_service(int fd, void *cookie) { if (getuid() == 0) { WriteFdExactly(fd, "adbd is already running as root\n"); adb_close(fd); } else { if (!__android_log_is_debuggable()) { WriteFdExactly(fd, "adbd cannot run as root in production builds\n"); adb_close(fd); return; } android::base::SetProperty("service.adb.root", "1"); WriteFdExactly(fd, "restarting adbd as root\n"); adb_close(fd); } }
int fs_mgr_early_setup_verity(struct fstab_rec *fstab_rec) { if ((fstab_rec->fs_mgr_flags & MF_VERIFY) && device_is_secure()) { int rc = fs_mgr_setup_verity(fstab_rec); if (__android_log_is_debuggable() && rc == FS_MGR_SETUP_VERITY_DISABLED) { INFO("Verity disabled"); return FS_MGR_EARLY_SETUP_VERITY_NO_VERITY; } else if (rc == FS_MGR_SETUP_VERITY_SUCCESS) { return FS_MGR_EARLY_SETUP_VERITY_SUCCESS; } else { return FS_MGR_EARLY_SETUP_VERITY_FAIL; } } else if (device_is_secure()) { ERROR("Verity must be enabled for early mounted partitions on secured devices.\n"); return FS_MGR_EARLY_SETUP_VERITY_FAIL; } return FS_MGR_EARLY_SETUP_VERITY_NO_VERITY; }
/* If tmp_mount_point is non-null, mount the filesystem there. This is for the * tmp mount we do to check the user password * If multiple fstab entries are to be mounted on "n_name", it will try to mount each one * in turn, and stop on 1st success, or no more match. */ int fs_mgr_do_mount(struct fstab *fstab, char *n_name, char *n_blk_device, char *tmp_mount_point) { int i = 0; int ret = FS_MGR_DOMNT_FAILED; int mount_errors = 0; int first_mount_errno = 0; char *m; if (!fstab) { return ret; } for (i = 0; i < fstab->num_entries; i++) { if (!fs_match(fstab->recs[i].mount_point, n_name)) { continue; } /* We found our match */ /* If this swap or a raw partition, report an error */ if (!strcmp(fstab->recs[i].fs_type, "swap") || !strcmp(fstab->recs[i].fs_type, "emmc") || !strcmp(fstab->recs[i].fs_type, "mtd")) { ERROR("Cannot mount filesystem of type %s on %s\n", fstab->recs[i].fs_type, n_blk_device); goto out; } /* First check the filesystem if requested */ if (fstab->recs[i].fs_mgr_flags & MF_WAIT) { wait_for_file(n_blk_device, WAIT_TIMEOUT); } int force_check = do_quota(fstab->recs[i].blk_device, fstab->recs[i].fs_type, &fstab->recs[i]); if ((fstab->recs[i].fs_mgr_flags & MF_CHECK) || force_check) { check_fs(n_blk_device, fstab->recs[i].fs_type, fstab->recs[i].mount_point); } if (fstab->recs[i].fs_mgr_flags & MF_RESERVEDSIZE) { do_reserved_size(n_blk_device, fstab->recs[i].fs_type, &fstab->recs[i]); } if ((fstab->recs[i].fs_mgr_flags & MF_VERIFY) && device_is_secure()) { int rc = fs_mgr_setup_verity(&fstab->recs[i]); if (__android_log_is_debuggable() && rc == FS_MGR_SETUP_VERITY_DISABLED) { INFO("Verity disabled"); } else if (rc != FS_MGR_SETUP_VERITY_SUCCESS) { ERROR("Could not set up verified partition, skipping!\n"); continue; } } /* Now mount it where requested */ if (tmp_mount_point) { m = tmp_mount_point; } else { m = fstab->recs[i].mount_point; } if (__mount(n_blk_device, m, &fstab->recs[i])) { if (!first_mount_errno) first_mount_errno = errno; mount_errors++; continue; } else { ret = 0; goto out; } } if (mount_errors) { ERROR("Cannot mount filesystem on %s at %s. error: %s\n", n_blk_device, m, strerror(first_mount_errno)); if (first_mount_errno == EBUSY) { ret = FS_MGR_DOMNT_BUSY; } else { ret = FS_MGR_DOMNT_FAILED; } } else { /* We didn't find a match, say so and return an error */ ERROR("Cannot find mount point %s in fstab\n", fstab->recs[i].mount_point); } out: return ret; }
/* When multiple fstab records share the same mount_point, it will * try to mount each one in turn, and ignore any duplicates after a * first successful mount. * Returns -1 on error, and FS_MGR_MNTALL_* otherwise. */ int fs_mgr_mount_all(struct fstab *fstab, int mount_mode) { int i = 0; int encryptable = FS_MGR_MNTALL_DEV_NOT_ENCRYPTABLE; int error_count = 0; int mret = -1; int mount_errno = 0; int attempted_idx = -1; if (!fstab) { return -1; } for (i = 0; i < fstab->num_entries; i++) { /* Don't mount entries that are managed by vold or not for the mount mode*/ if ((fstab->recs[i].fs_mgr_flags & (MF_VOLDMANAGED | MF_RECOVERYONLY)) || ((mount_mode == MOUNT_MODE_LATE) && !fs_mgr_is_latemount(&fstab->recs[i])) || ((mount_mode == MOUNT_MODE_EARLY) && fs_mgr_is_latemount(&fstab->recs[i]))) { continue; } /* Skip swap and raw partition entries such as boot, recovery, etc */ if (!strcmp(fstab->recs[i].fs_type, "swap") || !strcmp(fstab->recs[i].fs_type, "emmc") || !strcmp(fstab->recs[i].fs_type, "mtd")) { continue; } /* Skip mounting the root partition, as it will already have been mounted */ if (!strcmp(fstab->recs[i].mount_point, "/")) { if ((fstab->recs[i].fs_mgr_flags & MS_RDONLY) != 0) { fs_mgr_set_blk_ro(fstab->recs[i].blk_device); } continue; } /* Translate LABEL= file system labels into block devices */ if (!strcmp(fstab->recs[i].fs_type, "ext2") || !strcmp(fstab->recs[i].fs_type, "ext3") || !strcmp(fstab->recs[i].fs_type, "ext4")) { int tret = translate_ext_labels(&fstab->recs[i]); if (tret < 0) { ERROR("Could not translate label to block device\n"); continue; } } if (fstab->recs[i].fs_mgr_flags & MF_WAIT) { wait_for_file(fstab->recs[i].blk_device, WAIT_TIMEOUT); } if ((fstab->recs[i].fs_mgr_flags & MF_VERIFY) && device_is_secure()) { int rc = fs_mgr_setup_verity(&fstab->recs[i]); if (__android_log_is_debuggable() && rc == FS_MGR_SETUP_VERITY_DISABLED) { INFO("Verity disabled"); } else if (rc != FS_MGR_SETUP_VERITY_SUCCESS) { ERROR("Could not set up verified partition, skipping!\n"); continue; } } int last_idx_inspected; int top_idx = i; mret = mount_with_alternatives(fstab, i, &last_idx_inspected, &attempted_idx); i = last_idx_inspected; mount_errno = errno; /* Deal with encryptability. */ if (!mret) { int status = handle_encryptable(&fstab->recs[attempted_idx]); if (status == FS_MGR_MNTALL_FAIL) { /* Fatal error - no point continuing */ return status; } if (status != FS_MGR_MNTALL_DEV_NOT_ENCRYPTABLE) { if (encryptable != FS_MGR_MNTALL_DEV_NOT_ENCRYPTABLE) { // Log and continue ERROR("Only one encryptable/encrypted partition supported\n"); } encryptable = status; } /* Success! Go get the next one */ continue; } /* mount(2) returned an error, handle the encryptable/formattable case */ bool wiped = partition_wiped(fstab->recs[top_idx].blk_device); bool crypt_footer = false; if (mret && mount_errno != EBUSY && mount_errno != EACCES && fs_mgr_is_formattable(&fstab->recs[top_idx]) && wiped) { /* top_idx and attempted_idx point at the same partition, but sometimes * at two different lines in the fstab. Use the top one for formatting * as that is the preferred one. */ ERROR("%s(): %s is wiped and %s %s is formattable. Format it.\n", __func__, fstab->recs[top_idx].blk_device, fstab->recs[top_idx].mount_point, fstab->recs[top_idx].fs_type); if (fs_mgr_is_encryptable(&fstab->recs[top_idx]) && strcmp(fstab->recs[top_idx].key_loc, KEY_IN_FOOTER)) { int fd = open(fstab->recs[top_idx].key_loc, O_WRONLY); if (fd >= 0) { INFO("%s(): also wipe %s\n", __func__, fstab->recs[top_idx].key_loc); wipe_block_device(fd, get_file_size(fd)); close(fd); } else { ERROR("%s(): %s wouldn't open (%s)\n", __func__, fstab->recs[top_idx].key_loc, strerror(errno)); } } else if (fs_mgr_is_encryptable(&fstab->recs[top_idx]) && !strcmp(fstab->recs[top_idx].key_loc, KEY_IN_FOOTER)) { crypt_footer = true; } if (fs_mgr_do_format(&fstab->recs[top_idx], crypt_footer) == 0) { /* Let's replay the mount actions. */ i = top_idx - 1; continue; } else { ERROR("%s(): Format failed. Suggest recovery...\n", __func__); encryptable = FS_MGR_MNTALL_DEV_NEEDS_RECOVERY; continue; } } if (mret && mount_errno != EBUSY && mount_errno != EACCES && fs_mgr_is_encryptable(&fstab->recs[attempted_idx])) { if (wiped) { ERROR("%s(): %s is wiped and %s %s is encryptable. Suggest recovery...\n", __func__, fstab->recs[attempted_idx].blk_device, fstab->recs[attempted_idx].mount_point, fstab->recs[attempted_idx].fs_type); encryptable = FS_MGR_MNTALL_DEV_NEEDS_RECOVERY; continue; } else { /* Need to mount a tmpfs at this mountpoint for now, and set * properties that vold will query later for decrypting */ ERROR("%s(): possibly an encryptable blkdev %s for mount %s type %s )\n", __func__, fstab->recs[attempted_idx].blk_device, fstab->recs[attempted_idx].mount_point, fstab->recs[attempted_idx].fs_type); if (fs_mgr_do_tmpfs_mount(fstab->recs[attempted_idx].mount_point) < 0) { ++error_count; continue; } } encryptable = FS_MGR_MNTALL_DEV_MIGHT_BE_ENCRYPTED; } else { if (fs_mgr_is_nofail(&fstab->recs[attempted_idx])) { ERROR("Ignoring failure to mount an un-encryptable or wiped partition on" "%s at %s options: %s error: %s\n", fstab->recs[attempted_idx].blk_device, fstab->recs[attempted_idx].mount_point, fstab->recs[attempted_idx].fs_options, strerror(mount_errno)); } else { ERROR("Failed to mount an un-encryptable or wiped partition on" "%s at %s options: %s error: %s\n", fstab->recs[attempted_idx].blk_device, fstab->recs[attempted_idx].mount_point, fstab->recs[attempted_idx].fs_options, strerror(mount_errno)); ++error_count; } continue; } } if (error_count) { return -1; } else { return encryptable; } }
// Look up tagname, generate one if necessary, and return a tag LIBLOG_ABI_PUBLIC int android_lookupEventTagNum(EventTagMap* map, const char* tagname, const char* format, int prio) { const char* ep = endOfTag(tagname); size_t len = ep - tagname; if (!len || *ep) { errno = EINVAL; return -1; } if ((prio != ANDROID_LOG_UNKNOWN) && (prio < ANDROID_LOG_SILENT) && !__android_log_is_loggable_len(prio, tagname, len, __android_log_is_debuggable() ? ANDROID_LOG_VERBOSE : ANDROID_LOG_DEBUG)) { errno = EPERM; return -1; } if (!format) format = ""; ssize_t fmtLen = strlen(format); int ret = map->find(TagFmt( std::make_pair(MapString(tagname, len), MapString(format, fmtLen)))); if (ret != -1) return ret; // call event tag service to arrange for a new tag char* buf = NULL; // Can not use android::base::StringPrintf, asprintf + free instead. static const char command_template[] = "getEventTag name=%s format=\"%s\""; ret = asprintf(&buf, command_template, tagname, format); if (ret > 0) { // Add some buffer margin for an estimate of the full return content. char* cp; size_t size = ret - strlen(command_template) + strlen("65535\n4294967295\t?\t\t\t?\t# uid=32767\n\n\f?success?"); if (size > (size_t)ret) { cp = static_cast<char*>(realloc(buf, size)); if (cp) { buf = cp; } else { size = ret; } } else { size = ret; } // Ask event log tag service for an allocation if (__send_log_msg(buf, size) >= 0) { buf[size - 1] = '\0'; unsigned long val = strtoul(buf, &cp, 10); // return size if ((buf != cp) && (val > 0) && (*cp == '\n')) { // truncation OK val = strtoul(cp + 1, &cp, 10); // allocated tag number if ((val > 0) && (val < UINT32_MAX) && (*cp == '\t')) { free(buf); ret = val; // cache map->emplaceUnique(ret, TagFmt(std::make_pair( MapString(std::string(tagname, len)), MapString(std::string(format, fmtLen))))); return ret; } } } free(buf); } // Hail Mary ret = map->find(MapString(tagname, len)); if (ret == -1) errno = ESRCH; return ret; }