void set_verity_enabled_state_service(int fd, void* cookie) { bool enable = (cookie != NULL); if (kAllowDisableVerity) { char fstab_filename[PROPERTY_VALUE_MAX + sizeof(FSTAB_PREFIX)]; char propbuf[PROPERTY_VALUE_MAX]; int i; bool any_changed = false; property_get("ro.secure", propbuf, "0"); if (strcmp(propbuf, "1")) { WriteFdFmt(fd, "verity not enabled - ENG build\n"); goto errout; } property_get("ro.debuggable", propbuf, "0"); if (strcmp(propbuf, "1")) { WriteFdFmt(fd, "verity cannot be disabled/enabled - USER build\n"); goto errout; } property_get("ro.hardware", propbuf, ""); snprintf(fstab_filename, sizeof(fstab_filename), FSTAB_PREFIX"%s", propbuf); fstab = fs_mgr_read_fstab(fstab_filename); if (!fstab) { WriteFdFmt(fd, "Failed to open %s\nMaybe run adb root?\n", fstab_filename); goto errout; } /* Loop through entries looking for ones that vold manages */ for (i = 0; i < fstab->num_entries; i++) { if(fs_mgr_is_verified(&fstab->recs[i])) { if (!set_verity_enabled_state(fd, fstab->recs[i].blk_device, fstab->recs[i].mount_point, enable)) { any_changed = true; } } } if (any_changed) { WriteFdFmt(fd, "Now reboot your device for settings to take effect\n"); } } else { WriteFdFmt(fd, "%s-verity only works for userdebug builds\n", enable ? "enable" : "disable"); } errout: adb_close(fd); }
void restart_tcp_service(int fd, void *cookie) { int port = (int) (uintptr_t) cookie; if (port <= 0) { WriteFdFmt(fd, "invalid port %d\n", port); adb_close(fd); return; } android::base::SetProperty("service.adb.tcp.port", android::base::StringPrintf("%d", port)); WriteFdFmt(fd, "restarting in TCP mode port: %d\n", port); adb_close(fd); }
static bool reboot_service_impl(int fd, const char* arg) { const char* reboot_arg = arg; bool auto_reboot = false; if (strcmp(reboot_arg, "sideload-auto-reboot") == 0) { auto_reboot = true; reboot_arg = "sideload"; } // It reboots into sideload mode by setting "--sideload" or "--sideload_auto_reboot" // in the command file. if (strcmp(reboot_arg, "sideload") == 0) { if (getuid() != 0) { WriteFdExactly(fd, "'adb root' is required for 'adb reboot sideload'.\n"); return false; } const char* const recovery_dir = "/cache/recovery"; const char* const command_file = "/cache/recovery/command"; // Ensure /cache/recovery exists. if (adb_mkdir(recovery_dir, 0770) == -1 && errno != EEXIST) { D("Failed to create directory '%s': %s", recovery_dir, strerror(errno)); return false; } bool write_status = android::base::WriteStringToFile( auto_reboot ? "--sideload_auto_reboot" : "--sideload", command_file); if (!write_status) { return false; } reboot_arg = "recovery"; } sync(); char property_val[PROPERTY_VALUE_MAX]; int ret = snprintf(property_val, sizeof(property_val), "reboot,%s", reboot_arg); if (ret >= static_cast<int>(sizeof(property_val))) { WriteFdFmt(fd, "reboot string too long: %d\n", ret); return false; } ret = property_set(ANDROID_RB_PROPERTY, property_val); if (ret < 0) { WriteFdFmt(fd, "reboot failed: %d\n", ret); return false; } return true; }
void restart_tcp_service(int fd, void *cookie) { int port = (int) (uintptr_t) cookie; if (port <= 0) { WriteFdFmt(fd, "invalid port %d\n", port); adb_close(fd); return; } char value[PROPERTY_VALUE_MAX]; snprintf(value, sizeof(value), "%d", port); property_set("service.adb.tcp.port", value); WriteFdFmt(fd, "restarting in TCP mode port: %d\n", port); adb_close(fd); }
bool SendProtocolString(int fd, const std::string& s) { int length = s.size(); if (length > 0xffff) { length = 0xffff; } // The cost of sending two strings outweighs the cost of formatting. // "adb sync" performance is affected by this. return WriteFdFmt(fd, "%04x%.*s", length, length, s.c_str()); }
static bool remount_partition(int fd, const char* dir) { if (!directory_exists(dir)) { return true; } std::string dev = find_mount(dir); if (dev.empty()) { return true; } if (!make_block_device_writable(dev)) { WriteFdFmt(fd, "remount of %s failed; couldn't make block device %s writable: %s\n", dir, dev.c_str(), strerror(errno)); return false; } if (mount(dev.c_str(), dir, "none", MS_REMOUNT, nullptr) == -1) { WriteFdFmt(fd, "remount of %s failed: %s\n", dir, strerror(errno)); return false; } return true; }
TEST(io, WriteFdFmt) { TemporaryFile tf; ASSERT_NE(-1, tf.fd); // Test writing a partial string to the file. ASSERT_TRUE(WriteFdFmt(tf.fd, "Foo%s%d", "bar", 123)) << strerror(errno); ASSERT_EQ(0, lseek(tf.fd, SEEK_SET, 0)); std::string s; ASSERT_TRUE(android::base::ReadFdToString(tf.fd, &s)); EXPECT_STREQ("Foobar123", s.c_str()); }
int read_block_adb(void* data, uint32_t block, uint8_t* buffer, uint32_t fetch_size) { adb_data* ad = reinterpret_cast<adb_data*>(data); if (!WriteFdFmt(ad->sfd, "%08u", block)) { fprintf(stderr, "failed to write to adb host: %s\n", strerror(errno)); return -EIO; } if (!ReadFdExactly(ad->sfd, buffer, fetch_size)) { fprintf(stderr, "failed to read from adb host: %s\n", strerror(errno)); return -EIO; } return 0; }
/* Turn verity on/off */ static int set_verity_enabled_state(int fd, const char *block_device, const char* mount_point, bool enable) { if (!make_block_device_writable(block_device)) { WriteFdFmt(fd, "Could not make block device %s writable (%s).\n", block_device, strerror(errno)); return -1; } fec::io fh(block_device, O_RDWR); if (!fh) { WriteFdFmt(fd, "Could not open block device %s (%s).\n", block_device, strerror(errno)); WriteFdFmt(fd, "Maybe run adb root?\n"); return -1; } fec_verity_metadata metadata; if (!fh.get_verity_metadata(metadata)) { WriteFdFmt(fd, "Couldn't find verity metadata!\n"); return -1; } if (!enable && metadata.disabled) { WriteFdFmt(fd, "Verity already disabled on %s\n", mount_point); return -1; } if (enable && !metadata.disabled) { WriteFdFmt(fd, "Verity already enabled on %s\n", mount_point); return -1; } if (!fh.set_verity_status(enable)) { WriteFdFmt(fd, "Could not set verity %s flag on device %s with error %s\n", enable ? "enabled" : "disabled", block_device, strerror(errno)); return -1; } WriteFdFmt(fd, "Verity %s on %s\n", enable ? "enabled" : "disabled", mount_point); return 0; }
static bool reboot_service_impl(int fd, const char* arg) { const char* reboot_arg = arg; bool auto_reboot = false; if (strcmp(reboot_arg, "sideload-auto-reboot") == 0) { auto_reboot = true; reboot_arg = "sideload"; } // It reboots into sideload mode by setting "--sideload" or "--sideload_auto_reboot" // in the command file. if (strcmp(reboot_arg, "sideload") == 0) { if (getuid() != 0) { WriteFdExactly(fd, "'adb root' is required for 'adb reboot sideload'.\n"); return false; } const char* const recovery_dir = "/cache/recovery"; const char* const command_file = "/cache/recovery/command"; // Ensure /cache/recovery exists. if (adb_mkdir(recovery_dir, 0770) == -1 && errno != EEXIST) { D("Failed to create directory '%s': %s", recovery_dir, strerror(errno)); return false; } bool write_status = android::base::WriteStringToFile( auto_reboot ? "--sideload_auto_reboot" : "--sideload", command_file); if (!write_status) { return false; } reboot_arg = "recovery"; } sync(); std::string reboot_string = android::base::StringPrintf("reboot,%s", reboot_arg); if (!android::base::SetProperty(ANDROID_RB_PROPERTY, reboot_string)) { WriteFdFmt(fd, "reboot (%s) failed\n", reboot_string.c_str()); return false; } return true; }
void remount_service(int fd, void* cookie) { if (getuid() != 0) { WriteFdExactly(fd, "Not running as root. Try \"adb root\" first.\n"); adb_close(fd); return; } char prop_buf[PROPERTY_VALUE_MAX]; property_get("partition.system.verified", prop_buf, ""); bool system_verified = (strlen(prop_buf) > 0); property_get("partition.vendor.verified", prop_buf, ""); bool vendor_verified = (strlen(prop_buf) > 0); if (system_verified || vendor_verified) { // Allow remount but warn of likely bad effects bool both = system_verified && vendor_verified; WriteFdFmt(fd, "dm_verity is enabled on the %s%s%s partition%s.\n", system_verified ? "system" : "", both ? " and " : "", vendor_verified ? "vendor" : "", both ? "s" : ""); WriteFdExactly(fd, "Use \"adb disable-verity\" to disable verity.\n" "If you do not, remount may succeed, however, you will still " "not be able to write to these volumes.\n"); } bool success = true; property_get("ro.build.system_root_image", prop_buf, ""); bool system_root = !strcmp(prop_buf, "true"); if (system_root) { success &= remount_partition(fd, "/"); } else { success &= remount_partition(fd, "/system"); } success &= remount_partition(fd, "/vendor"); success &= remount_partition(fd, "/oem"); WriteFdExactly(fd, success ? "remount succeeded\n" : "remount failed\n"); adb_close(fd); }
static bool reboot_service_impl(int fd, const char* arg) { const char* reboot_arg = arg; bool auto_reboot = false; if (strcmp(reboot_arg, "sideload-auto-reboot") == 0) { auto_reboot = true; reboot_arg = "sideload"; } // It reboots into sideload mode by setting "--sideload" or "--sideload_auto_reboot" // in the command file. if (strcmp(reboot_arg, "sideload") == 0) { if (getuid() != 0) { WriteFdExactly(fd, "'adb root' is required for 'adb reboot sideload'.\n"); return false; } const std::vector<std::string> options = { auto_reboot ? "--sideload_auto_reboot" : "--sideload" }; std::string err; if (!write_bootloader_message(options, &err)) { D("Failed to set bootloader message: %s", err.c_str()); return false; } reboot_arg = "recovery"; } sync(); std::string reboot_string = android::base::StringPrintf("reboot,%s", reboot_arg); if (!android::base::SetProperty(ANDROID_RB_PROPERTY, reboot_string)) { WriteFdFmt(fd, "reboot (%s) failed\n", reboot_string.c_str()); return false; } return true; }
void remount_service(int fd, void* cookie) { if (getuid() != 0) { WriteFdExactly(fd, "Not running as root. Try \"adb root\" first.\n"); adb_close(fd); return; } bool system_verified = !(android::base::GetProperty("partition.system.verified", "").empty()); bool vendor_verified = !(android::base::GetProperty("partition.vendor.verified", "").empty()); if (system_verified || vendor_verified) { // Allow remount but warn of likely bad effects bool both = system_verified && vendor_verified; WriteFdFmt(fd, "dm_verity is enabled on the %s%s%s partition%s.\n", system_verified ? "system" : "", both ? " and " : "", vendor_verified ? "vendor" : "", both ? "s" : ""); WriteFdExactly(fd, "Use \"adb disable-verity\" to disable verity.\n" "If you do not, remount may succeed, however, you will still " "not be able to write to these volumes.\n"); } bool success = true; if (android::base::GetBoolProperty("ro.build.system_root_image", false)) { success &= remount_partition(fd, "/"); } else { success &= remount_partition(fd, "/system"); } success &= remount_partition(fd, "/vendor"); success &= remount_partition(fd, "/oem"); WriteFdExactly(fd, success ? "remount succeeded\n" : "remount failed\n"); adb_close(fd); }