Merge "Improve "adb sideload" error reporting."
diff --git a/Android.mk b/Android.mk
index d17b063..112bc80 100644
--- a/Android.mk
+++ b/Android.mk
@@ -363,6 +363,7 @@
LOCAL_STRIP_MODULE := keep_symbols
LOCAL_STATIC_LIBRARIES := \
libadbd \
+ libavb_user \
libbase \
libbootloader_message \
libfs_mgr \
diff --git a/adb_auth_host.cpp b/adb_auth_host.cpp
index c3f1fe0..365bf77 100644
--- a/adb_auth_host.cpp
+++ b/adb_auth_host.cpp
@@ -82,16 +82,17 @@
return false;
}
- size_t base64_key_length;
- if (!EVP_EncodedLength(&base64_key_length, sizeof(binary_key_data))) {
+ size_t expected_length;
+ if (!EVP_EncodedLength(&expected_length, sizeof(binary_key_data))) {
LOG(ERROR) << "Public key too large to base64 encode";
return false;
}
std::string content;
- content.resize(base64_key_length);
- base64_key_length = EVP_EncodeBlock(reinterpret_cast<uint8_t*>(&content[0]), binary_key_data,
- sizeof(binary_key_data));
+ content.resize(expected_length);
+ size_t actual_length = EVP_EncodeBlock(reinterpret_cast<uint8_t*>(&content[0]), binary_key_data,
+ sizeof(binary_key_data));
+ content.resize(actual_length);
content += get_user_info();
diff --git a/commandline.cpp b/commandline.cpp
index 1d3d081..a9b1540 100644
--- a/commandline.cpp
+++ b/commandline.cpp
@@ -68,20 +68,17 @@
static int install_app_legacy(TransportType t, const char* serial, int argc, const char** argv);
static int uninstall_app_legacy(TransportType t, const char* serial, int argc, const char** argv);
-static auto& gProductOutPath = *new std::string();
extern int gListenAll;
DefaultStandardStreamsCallback DEFAULT_STANDARD_STREAMS_CALLBACK(nullptr, nullptr);
-static std::string product_file(const char *extra) {
- if (gProductOutPath.empty()) {
- fprintf(stderr, "adb: Product directory not specified; "
- "use -p or define ANDROID_PRODUCT_OUT\n");
+static std::string product_file(const char* file) {
+ const char* ANDROID_PRODUCT_OUT = getenv("ANDROID_PRODUCT_OUT");
+ if (ANDROID_PRODUCT_OUT == nullptr) {
+ fprintf(stderr, "adb: product directory not specified; set $ANDROID_PRODUCT_OUT\n");
exit(1);
}
-
- return android::base::StringPrintf("%s%s%s",
- gProductOutPath.c_str(), OS_PATH_SEPARATOR_STR, extra);
+ return android::base::StringPrintf("%s%s%s", ANDROID_PRODUCT_OUT, OS_PATH_SEPARATOR_STR, file);
}
static void help() {
@@ -92,11 +89,7 @@
" -a listen on all network interfaces, not just localhost\n"
" -d use USB device (error if multiple devices connected)\n"
" -e use TCP/IP device (error if multiple TCP/IP devices available)\n"
- " -s SERIAL\n"
- " use device with given serial number (overrides $ANDROID_SERIAL)\n"
- " -p PRODUCT\n"
- " name or path ('angler'/'out/target/product/angler');\n"
- " default $ANDROID_PRODUCT_OUT\n"
+ " -s SERIAL use device with given serial (overrides $ANDROID_SERIAL)\n"
" -H name of adb server host [default=localhost]\n"
" -P port of adb server [default=5037]\n"
" -L SOCKET listen on given socket for adb server [default=tcp:localhost:5037]\n"
@@ -138,9 +131,8 @@
" pull [-a] REMOTE... LOCAL\n"
" copy files/dirs from device\n"
" -a: preserve file timestamp and mode\n"
- " sync [DIR]\n"
- " copy all changed files to device; if DIR is \"system\", \"vendor\", \"oem\",\n"
- " or \"data\", only sync that partition (default all)\n"
+ " sync [system|vendor|oem|data|all]\n"
+ " sync a local build from $ANDROID_PRODUCT_OUT to the device (default all)\n"
" -l: list but don't copy\n"
"\n"
"shell:\n"
@@ -1241,66 +1233,6 @@
return 0;
}
-/* <hint> may be:
- * - A simple product name
- * e.g., "sooner"
- * - A relative path from the CWD to the ANDROID_PRODUCT_OUT dir
- * e.g., "out/target/product/sooner"
- * - An absolute path to the PRODUCT_OUT dir
- * e.g., "/src/device/out/target/product/sooner"
- *
- * Given <hint>, try to construct an absolute path to the
- * ANDROID_PRODUCT_OUT dir.
- */
-static std::string find_product_out_path(const std::string& hint) {
- if (hint.empty()) {
- return "";
- }
-
- // If it's already absolute, don't bother doing any work.
- if (adb_is_absolute_host_path(hint.c_str())) {
- return hint;
- }
-
- // If any of the OS_PATH_SEPARATORS is found, assume it's a relative path;
- // make it absolute.
- // NOLINT: Do not complain if OS_PATH_SEPARATORS has only one character.
- if (hint.find_first_of(OS_PATH_SEPARATORS) != std::string::npos) { // NOLINT
- std::string cwd;
- if (!getcwd(&cwd)) {
- perror("adb: getcwd failed");
- return "";
- }
- return android::base::StringPrintf("%s%c%s", cwd.c_str(), OS_PATH_SEPARATOR, hint.c_str());
- }
-
- // It's a string without any slashes. Try to do something with it.
- //
- // Try to find the root of the build tree, and build a PRODUCT_OUT
- // path from there.
- char* top = getenv("ANDROID_BUILD_TOP");
- if (top == nullptr) {
- fprintf(stderr, "adb: ANDROID_BUILD_TOP not set!\n");
- return "";
- }
-
- std::string path = top;
- path += OS_PATH_SEPARATOR_STR;
- path += "out";
- path += OS_PATH_SEPARATOR_STR;
- path += "target";
- path += OS_PATH_SEPARATOR_STR;
- path += "product";
- path += OS_PATH_SEPARATOR_STR;
- path += hint;
- if (!directory_exists(path)) {
- fprintf(stderr, "adb: Couldn't find a product dir based on -p %s; "
- "\"%s\" doesn't exist\n", hint.c_str(), path.c_str());
- return "";
- }
- return path;
-}
-
static void parse_push_pull_args(const char** arg, int narg,
std::vector<const char*>* srcs,
const char** dst, bool* copy_attrs) {
@@ -1391,17 +1323,6 @@
signal(SIGPIPE, SIG_IGN);
#endif
- // If defined, this should be an absolute path to
- // the directory containing all of the various system images
- // for a particular product. If not defined, and the adb
- // command requires this information, then the user must
- // specify the path using "-p".
- char* ANDROID_PRODUCT_OUT = getenv("ANDROID_PRODUCT_OUT");
- if (ANDROID_PRODUCT_OUT != nullptr) {
- gProductOutPath = ANDROID_PRODUCT_OUT;
- }
- // TODO: also try TARGET_PRODUCT/TARGET_DEVICE as a hint
-
const char* server_host_str = nullptr;
const char* server_port_str = nullptr;
const char* server_socket_str = nullptr;
@@ -1427,21 +1348,6 @@
fprintf(stderr, "adb: invalid reply fd \"%s\"\n", reply_fd_str);
return 1;
}
- } else if (!strncmp(argv[0], "-p", 2)) {
- const char* product = nullptr;
- if (argv[0][2] == '\0') {
- if (argc < 2) return syntax_error("-p requires an argument");
- product = argv[1];
- argc--;
- argv++;
- } else {
- product = argv[0] + 2;
- }
- gProductOutPath = find_product_out_path(product);
- if (gProductOutPath.empty()) {
- fprintf(stderr, "adb: could not resolve \"-p %s\"\n", product);
- return 1;
- }
} else if (argv[0][0]=='-' && argv[0][1]=='s') {
if (isdigit(argv[0][2])) {
serial = argv[0] + 2;
@@ -1820,6 +1726,8 @@
return syntax_error("adb sync [-l] [PARTITION]");
}
+ if (src == "all") src = "";
+
if (src != "" &&
src != "system" && src != "data" && src != "vendor" && src != "oem") {
return syntax_error("don't know how to sync %s partition", src.c_str());
diff --git a/set_verity_enable_state_service.cpp b/set_verity_enable_state_service.cpp
index d4dd256..b2b1c18 100644
--- a/set_verity_enable_state_service.cpp
+++ b/set_verity_enable_state_service.cpp
@@ -20,6 +20,7 @@
#include <fcntl.h>
#include <inttypes.h>
+#include <libavb_user/libavb_user.h>
#include <stdarg.h>
#include <stdio.h>
#include <sys/stat.h>
@@ -45,13 +46,12 @@
#endif
/* Turn verity on/off */
-static int set_verity_enabled_state(int fd, const char *block_device,
- const char* mount_point, bool enable)
-{
+static bool 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;
+ return false;
}
fec::io fh(block_device, O_RDWR);
@@ -59,39 +59,84 @@
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;
+ return false;
}
fec_verity_metadata metadata;
if (!fh.get_verity_metadata(metadata)) {
WriteFdFmt(fd, "Couldn't find verity metadata!\n");
- return -1;
+ return false;
}
if (!enable && metadata.disabled) {
WriteFdFmt(fd, "Verity already disabled on %s\n", mount_point);
- return -1;
+ return false;
}
if (enable && !metadata.disabled) {
WriteFdFmt(fd, "Verity already enabled on %s\n", mount_point);
- return -1;
+ return false;
}
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;
+ return false;
}
WriteFdFmt(fd, "Verity %s on %s\n", enable ? "enabled" : "disabled", mount_point);
- return 0;
+ return true;
+}
+
+/* Helper function to get A/B suffix, if any. If the device isn't
+ * using A/B the empty string is returned. Otherwise either "_a",
+ * "_b", ... is returned.
+ *
+ * Note that since sometime in O androidboot.slot_suffix is deprecated
+ * and androidboot.slot should be used instead. Since bootloaders may
+ * be out of sync with the OS, we check both and for extra safety
+ * prepend a leading underscore if there isn't one already.
+ */
+static std::string get_ab_suffix() {
+ std::string ab_suffix = android::base::GetProperty("ro.boot.slot_suffix", "");
+ if (ab_suffix == "") {
+ ab_suffix = android::base::GetProperty("ro.boot.slot", "");
+ }
+ if (ab_suffix.size() > 0 && ab_suffix[0] != '_') {
+ ab_suffix = std::string("_") + ab_suffix;
+ }
+ return ab_suffix;
+}
+
+/* Use AVB to turn verity on/off */
+static bool set_avb_verity_enabled_state(int fd, AvbOps* ops, bool enable_verity) {
+ std::string ab_suffix = get_ab_suffix();
+
+ bool verity_enabled;
+ if (!avb_user_verity_get(ops, ab_suffix.c_str(), &verity_enabled)) {
+ WriteFdFmt(fd, "Error getting verity state\n");
+ return false;
+ }
+
+ if ((verity_enabled && enable_verity) || (!verity_enabled && !enable_verity)) {
+ WriteFdFmt(fd, "verity is already %s\n", verity_enabled ? "enabled" : "disabled");
+ return false;
+ }
+
+ if (!avb_user_verity_set(ops, ab_suffix.c_str(), enable_verity)) {
+ WriteFdFmt(fd, "Error setting verity\n");
+ return false;
+ }
+
+ WriteFdFmt(fd, "Successfully %s verity\n", enable_verity ? "enabled" : "disabled");
+ return true;
}
void set_verity_enabled_state_service(int fd, void* cookie) {
unique_fd closer(fd);
+ bool any_changed = false;
bool enable = (cookie != NULL);
if (!kAllowDisableVerity) {
@@ -108,21 +153,37 @@
return;
}
- // read all fstab entries at once from all sources
- fstab = fs_mgr_read_fstab_default();
- if (!fstab) {
- WriteFdFmt(fd, "Failed to read fstab\nMaybe run adb root?\n");
- return;
- }
+ // Figure out if we're using VB1.0 or VB2.0 (aka AVB).
+ std::string vbmeta_hash = android::base::GetProperty("ro.boot.vbmeta.digest", "");
+ if (vbmeta_hash != "") {
+ // Yep, the system is using AVB (by contract, androidboot.vbmeta.hash is
+ // set by the bootloader when using AVB).
+ AvbOps* ops = avb_ops_user_new();
+ if (ops == nullptr) {
+ WriteFdFmt(fd, "Error getting AVB ops\n");
+ return;
+ }
+ if (set_avb_verity_enabled_state(fd, ops, enable)) {
+ any_changed = true;
+ }
+ avb_ops_user_free(ops);
+ } else {
+ // Not using AVB - assume VB1.0.
- // Loop through entries looking for ones that vold manages.
- bool any_changed = false;
- for (int 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;
+ // read all fstab entries at once from all sources
+ fstab = fs_mgr_read_fstab_default();
+ if (!fstab) {
+ WriteFdFmt(fd, "Failed to read fstab\nMaybe run adb root?\n");
+ return;
+ }
+
+ // Loop through entries looking for ones that vold manages.
+ for (int 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;
+ }
}
}
}