Merge changes If7b13672,I96135a8c
* changes:
AshmemTest: expand ProtTest cases
AshmemTest: test lseek() and read() on ashmem fds
diff --git a/adb/client/usb_libusb.cpp b/adb/client/usb_libusb.cpp
index 20610ee..a32c605 100644
--- a/adb/client/usb_libusb.cpp
+++ b/adb/client/usb_libusb.cpp
@@ -159,6 +159,20 @@
libusb_get_device_address(device));
}
+static std::string get_device_serial_path(libusb_device* device) {
+ uint8_t ports[7];
+ int port_count = libusb_get_port_numbers(device, ports, 7);
+ if (port_count < 0) return "";
+
+ std::string path =
+ StringPrintf("/sys/bus/usb/devices/%d-%d", libusb_get_bus_number(device), ports[0]);
+ for (int port = 1; port < port_count; ++port) {
+ path += StringPrintf(".%d", ports[port]);
+ }
+ path += "/serial";
+ return path;
+}
+
static bool endpoint_is_output(uint8_t endpoint) {
return (endpoint & LIBUSB_ENDPOINT_DIR_MASK) == LIBUSB_ENDPOINT_OUT;
}
@@ -291,49 +305,67 @@
}
}
- libusb_device_handle* handle_raw;
+ bool writable = true;
+ libusb_device_handle* handle_raw = nullptr;
rc = libusb_open(device, &handle_raw);
- if (rc != 0) {
- LOG(WARNING) << "failed to open usb device at " << device_address << ": "
- << libusb_error_name(rc);
- continue;
- }
-
unique_device_handle handle(handle_raw);
- LOG(DEBUG) << "successfully opened adb device at " << device_address << ", "
- << StringPrintf("bulk_in = %#x, bulk_out = %#x", bulk_in, bulk_out);
-
- device_serial.resize(255);
- rc = libusb_get_string_descriptor_ascii(
- handle_raw, device_desc.iSerialNumber,
- reinterpret_cast<unsigned char*>(&device_serial[0]), device_serial.length());
if (rc == 0) {
- LOG(WARNING) << "received empty serial from device at " << device_address;
- continue;
- } else if (rc < 0) {
- LOG(WARNING) << "failed to get serial from device at " << device_address
- << libusb_error_name(rc);
- continue;
- }
- device_serial.resize(rc);
+ LOG(DEBUG) << "successfully opened adb device at " << device_address << ", "
+ << StringPrintf("bulk_in = %#x, bulk_out = %#x", bulk_in, bulk_out);
- // WARNING: this isn't released via RAII.
- rc = libusb_claim_interface(handle.get(), interface_num);
- if (rc != 0) {
- LOG(WARNING) << "failed to claim adb interface for device '" << device_serial << "'"
- << libusb_error_name(rc);
- continue;
- }
-
- for (uint8_t endpoint : {bulk_in, bulk_out}) {
- rc = libusb_clear_halt(handle.get(), endpoint);
- if (rc != 0) {
- LOG(WARNING) << "failed to clear halt on device '" << device_serial
- << "' endpoint 0x" << std::hex << endpoint << ": "
+ device_serial.resize(255);
+ rc = libusb_get_string_descriptor_ascii(
+ handle_raw, device_desc.iSerialNumber,
+ reinterpret_cast<unsigned char*>(&device_serial[0]), device_serial.length());
+ if (rc == 0) {
+ LOG(WARNING) << "received empty serial from device at " << device_address;
+ continue;
+ } else if (rc < 0) {
+ LOG(WARNING) << "failed to get serial from device at " << device_address
<< libusb_error_name(rc);
- libusb_release_interface(handle.get(), interface_num);
continue;
}
+ device_serial.resize(rc);
+
+ // WARNING: this isn't released via RAII.
+ rc = libusb_claim_interface(handle.get(), interface_num);
+ if (rc != 0) {
+ LOG(WARNING) << "failed to claim adb interface for device '" << device_serial
+ << "'" << libusb_error_name(rc);
+ continue;
+ }
+
+ for (uint8_t endpoint : {bulk_in, bulk_out}) {
+ rc = libusb_clear_halt(handle.get(), endpoint);
+ if (rc != 0) {
+ LOG(WARNING) << "failed to clear halt on device '" << device_serial
+ << "' endpoint 0x" << std::hex << endpoint << ": "
+ << libusb_error_name(rc);
+ libusb_release_interface(handle.get(), interface_num);
+ continue;
+ }
+ }
+ } else {
+ LOG(WARNING) << "failed to open usb device at " << device_address << ": "
+ << libusb_error_name(rc);
+ writable = false;
+
+#if defined(__linux__)
+ // libusb doesn't think we should be messing around with devices we don't have
+ // write access to, but Linux at least lets us get the serial number anyway.
+ if (!android::base::ReadFileToString(get_device_serial_path(device),
+ &device_serial)) {
+ // We don't actually want to treat an unknown serial as an error because
+ // devices aren't able to communicate a serial number in early bringup.
+ // http://b/20883914
+ device_serial = "unknown";
+ }
+ device_serial = android::base::Trim(device_serial);
+#else
+ // On Mac OS and Windows, we're screwed. But I don't think this situation actually
+ // happens on those OSes.
+ continue;
+#endif
}
auto result = std::make_unique<usb_handle>(device_address, device_serial,
@@ -346,7 +378,8 @@
usb_handles[device_address] = std::move(result);
}
- register_usb_transport(usb_handle_raw, device_serial.c_str(), device_address.c_str(), 1);
+ register_usb_transport(usb_handle_raw, device_serial.c_str(), device_address.c_str(),
+ writable);
LOG(INFO) << "registered new usb device '" << device_serial << "'";
}
diff --git a/adb/diagnose_usb.cpp b/adb/diagnose_usb.cpp
index 0f067b0..9f721bf 100644
--- a/adb/diagnose_usb.cpp
+++ b/adb/diagnose_usb.cpp
@@ -25,13 +25,14 @@
#if defined(__linux__)
#include <grp.h>
+#include <pwd.h>
#endif
static const char kPermissionsHelpUrl[] = "http://developer.android.com/tools/device.html";
-// Returns a message describing any potential problems we find with udev, or nullptr if we can't
-// find plugdev information (i.e. udev is not installed).
-static const char* GetUdevProblem() {
+// Returns a message describing any potential problems we find with udev, or an empty string if we
+// can't find plugdev information (i.e. udev is not installed).
+static std::string GetUdevProblem() {
#if defined(__linux__)
errno = 0;
group* plugdev_group = getgrnam("plugdev");
@@ -41,43 +42,45 @@
perror("failed to read plugdev group info");
}
// We can't give any generally useful advice here, just let the caller print the help URL.
- return nullptr;
+ return "";
}
- // getgroups(2) indicates that the group_member() may not check the egid so we check it
+ // getgroups(2) indicates that the GNU group_member(3) may not check the egid so we check it
// additionally just to be sure.
if (group_member(plugdev_group->gr_gid) || getegid() == plugdev_group->gr_gid) {
// The user is in plugdev so the problem is likely with the udev rules.
- return "verify udev rules";
+ return "user in plugdev group; are your udev rules wrong?";
}
- return "udev requires plugdev group membership";
+ passwd* pwd = getpwuid(getuid());
+ return android::base::StringPrintf("user %s is not in the plugdev group",
+ pwd ? pwd->pw_name : "?");
#else
- return nullptr;
+ return "";
#endif
}
// Short help text must be a single line, and will look something like:
-// no permissions (reason); see <URL>
+//
+// no permissions (reason); see [URL]
std::string UsbNoPermissionsShortHelpText() {
std::string help_text = "no permissions";
- const char* problem = GetUdevProblem();
- if (problem != nullptr) {
- help_text += android::base::StringPrintf(" (%s)", problem);
- }
+ std::string problem(GetUdevProblem());
+ if (!problem.empty()) help_text += " (" + problem + ")";
return android::base::StringPrintf("%s; see [%s]", help_text.c_str(), kPermissionsHelpUrl);
}
-// Long help text can span multiple lines and should provide more detailed information.
+// Long help text can span multiple lines but doesn't currently provide more detailed information:
+//
+// insufficient permissions for device: reason
+// See [URL] for more information
std::string UsbNoPermissionsLongHelpText() {
std::string header = "insufficient permissions for device";
- const char* problem = GetUdevProblem();
- if (problem != nullptr) {
- header += android::base::StringPrintf(": %s", problem);
- }
+ std::string problem(GetUdevProblem());
+ if (!problem.empty()) header += ": " + problem;
- return android::base::StringPrintf("%s.\nSee [%s] for more information.",
- header.c_str(), kPermissionsHelpUrl);
+ return android::base::StringPrintf("%s\nSee [%s] for more information", header.c_str(),
+ kPermissionsHelpUrl);
}
diff --git a/fs_mgr/fs_mgr_avb.cpp b/fs_mgr/fs_mgr_avb.cpp
index 94cea57..31babfe 100644
--- a/fs_mgr/fs_mgr_avb.cpp
+++ b/fs_mgr/fs_mgr_avb.cpp
@@ -483,13 +483,34 @@
// Only allow two verify results:
// - AVB_SLOT_VERIFY_RESULT_OK.
// - AVB_SLOT_VERIFY_RESULT_ERROR_VERIFICATION (for UNLOCKED state).
- if (verify_result == AVB_SLOT_VERIFY_RESULT_ERROR_VERIFICATION) {
- if (!avb_verifier->IsDeviceUnlocked()) {
- LERROR << "ERROR_VERIFICATION isn't allowed";
+ // If the device is UNLOCKED, i.e., |allow_verification_error| is true for
+ // AvbSlotVerify(), then the following return values are all non-fatal:
+ // * AVB_SLOT_VERIFY_RESULT_ERROR_VERIFICATION
+ // * AVB_SLOT_VERIFY_RESULT_ERROR_PUBLIC_KEY_REJECTED
+ // * AVB_SLOT_VERIFY_RESULT_ERROR_ROLLBACK_INDEX
+ // The latter two results were checked by bootloader prior to start fs_mgr so
+ // we just need to handle the first result here. See *dummy* operations in
+ // FsManagerAvbOps and the comments in external/avb/libavb/avb_slot_verify.h
+ // for more details.
+ switch (verify_result) {
+ case AVB_SLOT_VERIFY_RESULT_OK:
+ avb_handle->status_ = kFsManagerAvbHandleSuccess;
+ break;
+ case AVB_SLOT_VERIFY_RESULT_ERROR_VERIFICATION:
+ if (!avb_verifier->IsDeviceUnlocked()) {
+ LERROR << "ERROR_VERIFICATION isn't allowed when the device is LOCKED";
+ return nullptr;
+ }
+ avb_handle->status_ = kFsManagerAvbHandleErrorVerification;
+ break;
+ default:
+ LERROR << "avb_slot_verify failed, result: " << verify_result;
return nullptr;
- }
- } else if (verify_result != AVB_SLOT_VERIFY_RESULT_OK) {
- LERROR << "avb_slot_verify failed, result: " << verify_result;
+ }
+
+ // Verifies vbmeta images against the digest passed from bootloader.
+ if (!avb_verifier->VerifyVbmetaImages(*avb_handle->avb_slot_data_)) {
+ LERROR << "VerifyVbmetaImages failed";
return nullptr;
}
@@ -497,30 +518,20 @@
avb_handle->avb_version_ =
android::base::StringPrintf("%d.%d", AVB_VERSION_MAJOR, AVB_VERSION_MINOR);
- // Verifies vbmeta images against the digest passed from bootloader.
- if (!avb_verifier->VerifyVbmetaImages(*avb_handle->avb_slot_data_)) {
- LERROR << "VerifyVbmetaImages failed";
- return nullptr;
- } else {
- // Checks whether FLAGS_HASHTREE_DISABLED is set.
- AvbVBMetaImageHeader vbmeta_header;
- avb_vbmeta_image_header_to_host_byte_order(
- (AvbVBMetaImageHeader*)avb_handle->avb_slot_data_->vbmeta_images[0].vbmeta_data,
- &vbmeta_header);
+ // Checks whether FLAGS_HASHTREE_DISABLED is set.
+ AvbVBMetaImageHeader vbmeta_header;
+ avb_vbmeta_image_header_to_host_byte_order(
+ (AvbVBMetaImageHeader*)avb_handle->avb_slot_data_->vbmeta_images[0].vbmeta_data,
+ &vbmeta_header);
- bool hashtree_disabled =
- ((AvbVBMetaImageFlags)vbmeta_header.flags & AVB_VBMETA_IMAGE_FLAGS_HASHTREE_DISABLED);
- if (hashtree_disabled) {
- avb_handle->status_ = kFsManagerAvbHandleHashtreeDisabled;
- return avb_handle;
- }
+ bool hashtree_disabled =
+ ((AvbVBMetaImageFlags)vbmeta_header.flags & AVB_VBMETA_IMAGE_FLAGS_HASHTREE_DISABLED);
+ if (hashtree_disabled) {
+ avb_handle->status_ = kFsManagerAvbHandleHashtreeDisabled;
}
- if (verify_result == AVB_SLOT_VERIFY_RESULT_OK) {
- avb_handle->status_ = kFsManagerAvbHandleSuccess;
- return avb_handle;
- }
- return nullptr;
+ LINFO << "Returning avb_handle with status: " << avb_handle->status_;
+ return avb_handle;
}
bool FsManagerAvbHandle::SetUpAvb(struct fstab_rec* fstab_entry, bool wait_for_verity_dev) {
@@ -528,11 +539,12 @@
if (!avb_slot_data_ || avb_slot_data_->num_vbmeta_images < 1) {
return false;
}
+
+ if (status_ == kFsManagerAvbHandleUninitialized) return false;
if (status_ == kFsManagerAvbHandleHashtreeDisabled) {
LINFO << "AVB HASHTREE disabled on:" << fstab_entry->mount_point;
return true;
}
- if (status_ != kFsManagerAvbHandleSuccess) return false;
std::string partition_name(basename(fstab_entry->mount_point));
if (!avb_validate_utf8((const uint8_t*)partition_name.c_str(), partition_name.length())) {
diff --git a/fs_mgr/include/fs_mgr_avb.h b/fs_mgr/include/fs_mgr_avb.h
index a66ff42..65ff9941 100644
--- a/fs_mgr/include/fs_mgr_avb.h
+++ b/fs_mgr/include/fs_mgr_avb.h
@@ -25,9 +25,10 @@
#include "fs_mgr.h"
enum FsManagerAvbHandleStatus {
+ kFsManagerAvbHandleUninitialized = -1,
kFsManagerAvbHandleSuccess = 0,
kFsManagerAvbHandleHashtreeDisabled = 1,
- kFsManagerAvbHandleFail = 2,
+ kFsManagerAvbHandleErrorVerification = 2,
};
class FsManagerAvbHandle;
@@ -88,7 +89,7 @@
};
protected:
- FsManagerAvbHandle() : avb_slot_data_(nullptr), status_(kFsManagerAvbHandleFail) {}
+ FsManagerAvbHandle() : avb_slot_data_(nullptr), status_(kFsManagerAvbHandleUninitialized) {}
private:
AvbSlotVerifyData* avb_slot_data_;
diff --git a/libbacktrace/Android.bp b/libbacktrace/Android.bp
index 285aa6e..7dd9227 100644
--- a/libbacktrace/Android.bp
+++ b/libbacktrace/Android.bp
@@ -110,7 +110,7 @@
"libunwind",
],
- static_libs: ["libcutils"],
+ static_libs: ["libasync_safe", "libcutils"],
},
},
}
diff --git a/libbacktrace/BacktraceAsyncSafeLog.h b/libbacktrace/BacktraceAsyncSafeLog.h
new file mode 100644
index 0000000..14f51be
--- /dev/null
+++ b/libbacktrace/BacktraceAsyncSafeLog.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _LIBBACKTRACE_BACKTRACE_ASYNC_SAFE_LOG_H
+#define _LIBBACKTRACE_BACKTRACE_ASYNC_SAFE_LOG_H
+
+#if defined(__ANDROID__)
+
+#include <async_safe/log.h>
+
+// Logging macros for use in signal handler, only available on target.
+#define BACK_ASYNC_SAFE_LOGW(format, ...) \
+ async_safe_format_log(ANDROID_LOG_WARN, "libbacktrace", "%s: " format, __PRETTY_FUNCTION__, \
+ ##__VA_ARGS__)
+
+#define BACK_ASYNC_SAFE_LOGE(format, ...) \
+ async_safe_format_log(ANDROID_LOG_ERROR, "libbacktrace", "%s: " format, __PRETTY_FUNCTION__, \
+ ##__VA_ARGS__)
+
+#else
+
+#define BACK_ASYNC_SAFE_LOGW(format, ...)
+
+#define BACK_ASYNC_SAFE_LOGE(format, ...)
+
+#endif
+
+#endif // _LIBBACKTRACE_BACKTRACE_ASYNC_SAFE_LOG_H
diff --git a/libbacktrace/BacktraceCurrent.cpp b/libbacktrace/BacktraceCurrent.cpp
index d7a3b01..fb76b85 100644
--- a/libbacktrace/BacktraceCurrent.cpp
+++ b/libbacktrace/BacktraceCurrent.cpp
@@ -31,8 +31,8 @@
#include <backtrace/Backtrace.h>
#include <backtrace/BacktraceMap.h>
+#include "BacktraceAsyncSafeLog.h"
#include "BacktraceCurrent.h"
-#include "BacktraceLog.h"
#include "ThreadEntry.h"
#include "thread_utils.h"
@@ -47,7 +47,7 @@
*out_value = *reinterpret_cast<word_t*>(ptr);
return true;
} else {
- BACK_LOGW("pointer %p not in a readable map", reinterpret_cast<void*>(ptr));
+ BACK_ASYNC_SAFE_LOGW("pointer %p not in a readable map", reinterpret_cast<void*>(ptr));
*out_value = static_cast<word_t>(-1);
return false;
}
@@ -114,7 +114,8 @@
static void SignalLogOnly(int, siginfo_t*, void*) {
ErrnoRestorer restore;
- BACK_LOGE("pid %d, tid %d: Received a spurious signal %d\n", getpid(), gettid(), THREAD_SIGNAL);
+ BACK_ASYNC_SAFE_LOGE("pid %d, tid %d: Received a spurious signal %d\n", getpid(), gettid(),
+ THREAD_SIGNAL);
}
static void SignalHandler(int, siginfo_t*, void* sigcontext) {
@@ -122,7 +123,7 @@
ThreadEntry* entry = ThreadEntry::Get(getpid(), gettid(), false);
if (!entry) {
- BACK_LOGE("pid %d, tid %d entry not found", getpid(), gettid());
+ BACK_ASYNC_SAFE_LOGE("pid %d, tid %d entry not found", getpid(), gettid());
return;
}
@@ -141,7 +142,7 @@
entry->Wake();
} else {
// At this point, it is possible that entry has been freed, so just exit.
- BACK_LOGE("Timed out waiting for unwind thread to indicate it completed.");
+ BACK_ASYNC_SAFE_LOGE("Timed out waiting for unwind thread to indicate it completed.");
}
}
@@ -159,7 +160,7 @@
act.sa_flags = SA_RESTART | SA_SIGINFO | SA_ONSTACK;
sigemptyset(&act.sa_mask);
if (sigaction(THREAD_SIGNAL, &act, &oldact) != 0) {
- BACK_LOGE("sigaction failed: %s", strerror(errno));
+ BACK_ASYNC_SAFE_LOGE("sigaction failed: %s", strerror(errno));
ThreadEntry::Remove(entry);
pthread_mutex_unlock(&g_sigaction_mutex);
error_ = BACKTRACE_UNWIND_ERROR_INTERNAL;
@@ -212,7 +213,7 @@
// Wait for the thread to indicate it is done with the ThreadEntry.
if (!entry->Wait(3)) {
// Send a warning, but do not mark as a failure to unwind.
- BACK_LOGW("Timed out waiting for signal handler to indicate it finished.");
+ BACK_ASYNC_SAFE_LOGW("Timed out waiting for signal handler to indicate it finished.");
}
} else {
// Check to see if the thread has disappeared.
@@ -220,7 +221,7 @@
error_ = BACKTRACE_UNWIND_ERROR_THREAD_DOESNT_EXIST;
} else {
error_ = BACKTRACE_UNWIND_ERROR_THREAD_TIMEOUT;
- BACK_LOGE("Timed out waiting for signal handler to get ucontext data.");
+ BACK_ASYNC_SAFE_LOGE("Timed out waiting for signal handler to get ucontext data.");
}
}
diff --git a/libbacktrace/ThreadEntry.cpp b/libbacktrace/ThreadEntry.cpp
index 084c1aa..9bd59e4 100644
--- a/libbacktrace/ThreadEntry.cpp
+++ b/libbacktrace/ThreadEntry.cpp
@@ -21,7 +21,7 @@
#include <time.h>
#include <ucontext.h>
-#include "BacktraceLog.h"
+#include "BacktraceAsyncSafeLog.h"
#include "ThreadEntry.h"
// Initialize static member variables.
@@ -106,7 +106,7 @@
while (wait_value_ != value) {
int ret = pthread_cond_timedwait(&wait_cond_, &wait_mutex_, &ts);
if (ret != 0) {
- BACK_LOGW("pthread_cond_timedwait for value %d failed: %s", value, strerror(ret));
+ BACK_ASYNC_SAFE_LOGW("pthread_cond_timedwait for value %d failed: %s", value, strerror(ret));
wait_completed = false;
break;
}