Merge "Make memunreachable_binder_test suitable for VTS"
diff --git a/adb/adb.cpp b/adb/adb.cpp
index ee3503b..c4df5c4 100644
--- a/adb/adb.cpp
+++ b/adb/adb.cpp
@@ -42,7 +42,6 @@
#include <android-base/logging.h>
#include <android-base/macros.h>
#include <android-base/parsenetaddress.h>
-#include <android-base/quick_exit.h>
#include <android-base/stringprintf.h>
#include <android-base/strings.h>
@@ -105,31 +104,27 @@
}
uint32_t calculate_apacket_checksum(const apacket* p) {
- const unsigned char* x = reinterpret_cast<const unsigned char*>(p->data);
uint32_t sum = 0;
- size_t count = p->msg.data_length;
-
- while (count-- > 0) {
- sum += *x++;
+ for (size_t i = 0; i < p->msg.data_length; ++i) {
+ sum += static_cast<uint8_t>(p->payload[i]);
}
-
return sum;
}
apacket* get_apacket(void)
{
- apacket* p = reinterpret_cast<apacket*>(malloc(sizeof(apacket)));
+ apacket* p = new apacket();
if (p == nullptr) {
fatal("failed to allocate an apacket");
}
- memset(p, 0, sizeof(apacket) - MAX_PAYLOAD);
+ memset(&p->msg, 0, sizeof(p->msg));
return p;
}
void put_apacket(apacket *p)
{
- free(p);
+ delete p;
}
void handle_online(atransport *t)
@@ -155,8 +150,7 @@
#define DUMPMAX 32
void print_packet(const char *label, apacket *p)
{
- char *tag;
- char *x;
+ const char* tag;
unsigned count;
switch(p->msg.command){
@@ -173,15 +167,15 @@
fprintf(stderr, "%s: %s %08x %08x %04x \"",
label, tag, p->msg.arg0, p->msg.arg1, p->msg.data_length);
count = p->msg.data_length;
- x = (char*) p->data;
- if(count > DUMPMAX) {
+ const char* x = p->payload.data();
+ if (count > DUMPMAX) {
count = DUMPMAX;
tag = "\n";
} else {
tag = "\"\n";
}
- while(count-- > 0){
- if((*x >= ' ') && (*x < 127)) {
+ while (count-- > 0) {
+ if ((*x >= ' ') && (*x < 127)) {
fputc(*x, stderr);
} else {
fputc('.', stderr);
@@ -254,8 +248,8 @@
<< connection_str.length() << ")";
}
- memcpy(cp->data, connection_str.c_str(), connection_str.length());
- cp->msg.data_length = connection_str.length();
+ cp->payload = std::move(connection_str);
+ cp->msg.data_length = cp->payload.size();
send_packet(cp, t);
}
@@ -329,9 +323,7 @@
}
t->update_version(p->msg.arg0, p->msg.arg1);
- std::string banner(reinterpret_cast<const char*>(p->data),
- p->msg.data_length);
- parse_banner(banner, t);
+ parse_banner(p->payload, t);
#if ADB_HOST
handle_online(t);
@@ -354,6 +346,7 @@
((char*) (&(p->msg.command)))[2],
((char*) (&(p->msg.command)))[3]);
print_packet("recv", p);
+ CHECK_EQ(p->payload.size(), p->msg.data_length);
switch(p->msg.command){
case A_SYNC:
@@ -380,11 +373,11 @@
if (t->GetConnectionState() == kCsOffline) {
t->SetConnectionState(kCsUnauthorized);
}
- send_auth_response(p->data, p->msg.data_length, t);
+ send_auth_response(p->payload.data(), p->msg.data_length, t);
break;
#else
case ADB_AUTH_SIGNATURE:
- if (adbd_auth_verify(t->token, sizeof(t->token), p->data, p->msg.data_length)) {
+ if (adbd_auth_verify(t->token, sizeof(t->token), p->payload)) {
adbd_auth_verified(t);
t->failed_auth_attempts = 0;
} else {
@@ -394,7 +387,7 @@
break;
case ADB_AUTH_RSAPUBLICKEY:
- adbd_auth_confirm_key(p->data, p->msg.data_length, t);
+ adbd_auth_confirm_key(p->payload.data(), p->msg.data_length, t);
break;
#endif
default:
@@ -406,9 +399,7 @@
case A_OPEN: /* OPEN(local-id, 0, "destination") */
if (t->online && p->msg.arg0 != 0 && p->msg.arg1 == 0) {
- char *name = (char*) p->data;
- name[p->msg.data_length > 0 ? p->msg.data_length - 1 : 0] = 0;
- asocket* s = create_local_service_socket(name, t);
+ asocket* s = create_local_service_socket(p->payload.c_str(), t);
if (s == nullptr) {
send_close(0, p->msg.arg0, t);
} else {
@@ -474,11 +465,7 @@
asocket* s = find_local_socket(p->msg.arg1, p->msg.arg0);
if (s) {
unsigned rid = p->msg.arg0;
-
- // TODO: Convert apacket::data to a type that we can move out of.
- std::string copy(p->data, p->data + p->msg.data_length);
-
- if (s->enqueue(s, std::move(copy)) == 0) {
+ if (s->enqueue(s, std::move(p->payload)) == 0) {
D("Enqueue the socket");
send_ready(s->id, rid, t);
}
@@ -1071,7 +1058,7 @@
SendOkay(reply_fd);
// Rely on process exit to close the socket for us.
- android::base::quick_exit(0);
+ exit(0);
}
// "transport:" is used for switching transport with a specified serial number
diff --git a/adb/adb.h b/adb/adb.h
index c9c635a..a6d0463 100644
--- a/adb/adb.h
+++ b/adb/adb.h
@@ -74,7 +74,7 @@
struct apacket {
amessage msg;
- char data[MAX_PAYLOAD];
+ std::string payload;
};
uint32_t calculate_apacket_checksum(const apacket* packet);
diff --git a/adb/adb_auth.h b/adb/adb_auth.h
index a6f224f..715e04f 100644
--- a/adb/adb_auth.h
+++ b/adb/adb_auth.h
@@ -49,7 +49,7 @@
void adbd_auth_verified(atransport *t);
void adbd_cloexec_auth_socket();
-bool adbd_auth_verify(const char* token, size_t token_size, const char* sig, int sig_len);
+bool adbd_auth_verify(const char* token, size_t token_size, const std::string& sig);
void adbd_auth_confirm_key(const char* data, size_t len, atransport* t);
void send_auth_request(atransport *t);
diff --git a/adb/adb_auth_host.cpp b/adb/adb_auth_host.cpp
index 365bf77..c3aef16 100644
--- a/adb/adb_auth_host.cpp
+++ b/adb/adb_auth_host.cpp
@@ -299,20 +299,25 @@
return result;
}
-static int adb_auth_sign(RSA* key, const char* token, size_t token_size, char* sig) {
+static std::string adb_auth_sign(RSA* key, const char* token, size_t token_size) {
if (token_size != TOKEN_SIZE) {
D("Unexpected token size %zd", token_size);
return 0;
}
+ std::string result;
+ result.resize(MAX_PAYLOAD);
+
unsigned int len;
if (!RSA_sign(NID_sha1, reinterpret_cast<const uint8_t*>(token), token_size,
- reinterpret_cast<uint8_t*>(sig), &len, key)) {
- return 0;
+ reinterpret_cast<uint8_t*>(&result[0]), &len, key)) {
+ return std::string();
}
+ result.resize(len);
+
D("adb_auth_sign len=%d", len);
- return (int)len;
+ return result;
}
std::string adb_auth_get_userkey() {
@@ -446,13 +451,14 @@
}
apacket* p = get_apacket();
- memcpy(p->data, key.c_str(), key.size() + 1);
-
p->msg.command = A_AUTH;
p->msg.arg0 = ADB_AUTH_RSAPUBLICKEY;
+ p->payload = std::move(key);
+
// adbd expects a null-terminated string.
- p->msg.data_length = key.size() + 1;
+ p->payload.push_back('\0');
+ p->msg.data_length = p->payload.size();
send_packet(p, t);
}
@@ -467,8 +473,8 @@
LOG(INFO) << "Calling send_auth_response";
apacket* p = get_apacket();
- int ret = adb_auth_sign(key.get(), token, token_size, p->data);
- if (!ret) {
+ std::string result = adb_auth_sign(key.get(), token, token_size);
+ if (result.empty()) {
D("Error signing the token");
put_apacket(p);
return;
@@ -476,6 +482,7 @@
p->msg.command = A_AUTH;
p->msg.arg0 = ADB_AUTH_SIGNATURE;
- p->msg.data_length = ret;
+ p->payload = std::move(result);
+ p->msg.data_length = p->payload.size();
send_packet(p, t);
}
diff --git a/adb/adbd_auth.cpp b/adb/adbd_auth.cpp
index 3488ad1..3fd2b31 100644
--- a/adb/adbd_auth.cpp
+++ b/adb/adbd_auth.cpp
@@ -46,7 +46,7 @@
bool auth_required = true;
-bool adbd_auth_verify(const char* token, size_t token_size, const char* sig, int sig_len) {
+bool adbd_auth_verify(const char* token, size_t token_size, const std::string& sig) {
static constexpr const char* key_paths[] = { "/adb_keys", "/data/misc/adb/adb_keys", nullptr };
for (const auto& path : key_paths) {
@@ -80,7 +80,8 @@
bool verified =
(RSA_verify(NID_sha1, reinterpret_cast<const uint8_t*>(token), token_size,
- reinterpret_cast<const uint8_t*>(sig), sig_len, key) == 1);
+ reinterpret_cast<const uint8_t*>(sig.c_str()), sig.size(),
+ key) == 1);
RSA_free(key);
if (verified) return true;
}
@@ -210,10 +211,10 @@
}
apacket* p = get_apacket();
- memcpy(p->data, t->token, sizeof(t->token));
p->msg.command = A_AUTH;
p->msg.arg0 = ADB_AUTH_TOKEN;
p->msg.data_length = sizeof(t->token);
+ p->payload.assign(t->token, t->token + sizeof(t->token));
send_packet(p, t);
}
diff --git a/adb/client/main.cpp b/adb/client/main.cpp
index f0d0ce7..f28302b 100644
--- a/adb/client/main.cpp
+++ b/adb/client/main.cpp
@@ -28,7 +28,6 @@
#include <android-base/errors.h>
#include <android-base/file.h>
#include <android-base/logging.h>
-#include <android-base/quick_exit.h>
#include <android-base/stringprintf.h>
#include "adb.h"
@@ -61,7 +60,7 @@
static BOOL WINAPI ctrlc_handler(DWORD type) {
// TODO: Consider trying to kill a starting up adb server (if we're in
// launch_server) by calling GenerateConsoleCtrlEvent().
- android::base::quick_exit(STATUS_CONTROL_C_EXIT);
+ exit(STATUS_CONTROL_C_EXIT);
return TRUE;
}
#endif
@@ -95,7 +94,7 @@
SetConsoleCtrlHandler(ctrlc_handler, TRUE);
#else
signal(SIGINT, [](int) {
- fdevent_run_on_main_thread([]() { android::base::quick_exit(0); });
+ fdevent_run_on_main_thread([]() { exit(0); });
});
#endif
@@ -104,7 +103,7 @@
setup_daemon_logging();
}
- android::base::at_quick_exit(adb_server_cleanup);
+ atexit(adb_server_cleanup);
init_transport_registration();
init_mdns_transport_discovery();
diff --git a/adb/client/usb_libusb.cpp b/adb/client/usb_libusb.cpp
index 18f585d..46c3f58 100644
--- a/adb/client/usb_libusb.cpp
+++ b/adb/client/usb_libusb.cpp
@@ -19,6 +19,7 @@
#include "sysdeps.h"
#include <stdint.h>
+#include <stdlib.h>
#include <atomic>
#include <chrono>
@@ -33,7 +34,6 @@
#include <android-base/file.h>
#include <android-base/logging.h>
-#include <android-base/quick_exit.h>
#include <android-base/stringprintf.h>
#include <android-base/strings.h>
diff --git a/adb/fdevent.cpp b/adb/fdevent.cpp
index b28de4b..d285561 100644
--- a/adb/fdevent.cpp
+++ b/adb/fdevent.cpp
@@ -26,6 +26,7 @@
#include <unistd.h>
#include <atomic>
+#include <deque>
#include <functional>
#include <list>
#include <mutex>
@@ -81,7 +82,7 @@
static auto& run_queue_notify_fd = *new unique_fd();
static auto& run_queue_mutex = *new std::mutex();
-static auto& run_queue GUARDED_BY(run_queue_mutex) = *new std::vector<std::function<void()>>();
+static auto& run_queue GUARDED_BY(run_queue_mutex) = *new std::deque<std::function<void()>>();
void check_main_thread() {
if (main_thread_valid) {
@@ -359,11 +360,21 @@
}
#endif // !ADB_HOST
-static void fdevent_run_flush() REQUIRES(run_queue_mutex) {
- for (auto& f : run_queue) {
- f();
+static void fdevent_run_flush() EXCLUDES(run_queue_mutex) {
+ // We need to be careful around reentrancy here, since a function we call can queue up another
+ // function.
+ while (true) {
+ std::function<void()> fn;
+ {
+ std::lock_guard<std::mutex> lock(run_queue_mutex);
+ if (run_queue.empty()) {
+ break;
+ }
+ fn = run_queue.front();
+ run_queue.pop_front();
+ }
+ fn();
}
- run_queue.clear();
}
static void fdevent_run_func(int fd, unsigned ev, void* /* userdata */) {
@@ -377,22 +388,23 @@
PLOG(FATAL) << "failed to empty run queue notify fd";
}
- std::lock_guard<std::mutex> lock(run_queue_mutex);
fdevent_run_flush();
}
static void fdevent_run_setup() {
- std::lock_guard<std::mutex> lock(run_queue_mutex);
- CHECK(run_queue_notify_fd.get() == -1);
- int s[2];
- if (adb_socketpair(s) != 0) {
- PLOG(FATAL) << "failed to create run queue notify socketpair";
- }
+ {
+ std::lock_guard<std::mutex> lock(run_queue_mutex);
+ CHECK(run_queue_notify_fd.get() == -1);
+ int s[2];
+ if (adb_socketpair(s) != 0) {
+ PLOG(FATAL) << "failed to create run queue notify socketpair";
+ }
- run_queue_notify_fd.reset(s[0]);
- fdevent* fde = fdevent_create(s[1], fdevent_run_func, nullptr);
- CHECK(fde != nullptr);
- fdevent_add(fde, FDE_READ);
+ run_queue_notify_fd.reset(s[0]);
+ fdevent* fde = fdevent_create(s[1], fdevent_run_func, nullptr);
+ CHECK(fde != nullptr);
+ fdevent_add(fde, FDE_READ);
+ }
fdevent_run_flush();
}
diff --git a/adb/fdevent_test.cpp b/adb/fdevent_test.cpp
index 86e0209..63cc4d1 100644
--- a/adb/fdevent_test.cpp
+++ b/adb/fdevent_test.cpp
@@ -194,3 +194,31 @@
ASSERT_EQ(i, vec[i]);
}
}
+
+static std::function<void()> make_appender(std::vector<int>* vec, int value) {
+ return [vec, value]() {
+ check_main_thread();
+ if (value == 100) {
+ return;
+ }
+
+ vec->push_back(value);
+ fdevent_run_on_main_thread(make_appender(vec, value + 1));
+ };
+}
+
+TEST_F(FdeventTest, run_on_main_thread_reentrant) {
+ std::vector<int> vec;
+
+ PrepareThread();
+ std::thread thread(fdevent_loop);
+
+ fdevent_run_on_main_thread(make_appender(&vec, 0));
+
+ TerminateThread(thread);
+
+ ASSERT_EQ(100u, vec.size());
+ for (int i = 0; i < 100; ++i) {
+ ASSERT_EQ(i, vec[i]);
+ }
+}
diff --git a/adb/remount_service.cpp b/adb/remount_service.cpp
index 32ed28f..a4c7a5a 100644
--- a/adb/remount_service.cpp
+++ b/adb/remount_service.cpp
@@ -62,9 +62,9 @@
// The proc entry for / is full of lies, so check fstab instead.
// /proc/mounts lists rootfs and /dev/root, neither of which is what we want.
-static std::string find_mount(const char* dir) {
- if (strcmp(dir, "/") == 0) {
- return find_fstab_mount(dir);
+static std::string find_mount(const char* dir, bool is_root) {
+ if (is_root) {
+ return find_fstab_mount(dir);
} else {
return find_proc_mount(dir);
}
@@ -86,17 +86,29 @@
if (!directory_exists(dir)) {
return true;
}
- std::string dev = find_mount(dir);
- if (dev.empty()) {
+ bool is_root = strcmp(dir, "/") == 0;
+ std::string dev = find_mount(dir, is_root);
+ // Even if the device for the root is not found, we still try to remount it
+ // as rw. This typically only happens when running Android in a container:
+ // the root will almost always be in a loop device, which is dynamic, so
+ // it's not convenient to put in the fstab.
+ if (dev.empty() && !is_root) {
return true;
}
- if (!make_block_device_writable(dev)) {
+ if (!dev.empty() && !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 | MS_BIND, nullptr) == -1) {
+ // This is useful for cases where the superblock is already marked as
+ // read-write, but the mount itself is read-only, such as containers
+ // where the remount with just MS_REMOUNT is forbidden by the kernel.
+ WriteFdFmt(fd, "remount of the %s mount failed: %s.\n", dir, 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));
+ WriteFdFmt(fd, "remount of the %s superblock failed: %s\n", dir, strerror(errno));
return false;
}
return true;
diff --git a/adb/sockets.cpp b/adb/sockets.cpp
index 307cbfe..0007fed 100644
--- a/adb/sockets.cpp
+++ b/adb/sockets.cpp
@@ -413,15 +413,15 @@
p->msg.command = A_WRTE;
p->msg.arg0 = s->peer->id;
p->msg.arg1 = s->id;
- p->msg.data_length = data.size();
- if (data.size() > sizeof(p->data)) {
+ if (data.size() > MAX_PAYLOAD) {
put_apacket(p);
return -1;
}
- // TODO: Convert apacket::data to a type that we can move into.
- memcpy(p->data, data.data(), data.size());
+ p->payload = std::move(data);
+ p->msg.data_length = p->payload.size();
+
send_packet(p, s->transport);
return 1;
}
@@ -482,17 +482,20 @@
void connect_to_remote(asocket* s, const char* destination) {
D("Connect_to_remote call RS(%d) fd=%d", s->id, s->fd);
apacket* p = get_apacket();
- size_t len = strlen(destination) + 1;
-
- if (len > (s->get_max_payload() - 1)) {
- fatal("destination oversized");
- }
D("LS(%d): connect('%s')", s->id, destination);
p->msg.command = A_OPEN;
p->msg.arg0 = s->id;
- p->msg.data_length = len;
- strcpy((char*)p->data, destination);
+
+ // adbd expects a null-terminated string.
+ p->payload = destination;
+ p->payload.push_back('\0');
+ p->msg.data_length = p->payload.size();
+
+ if (p->msg.data_length > s->get_max_payload()) {
+ fatal("destination oversized");
+ }
+
send_packet(p, s->transport);
}
diff --git a/adb/transport.cpp b/adb/transport.cpp
index 9ae1297..6b1a00b 100644
--- a/adb/transport.cpp
+++ b/adb/transport.cpp
@@ -34,7 +34,6 @@
#include <android-base/logging.h>
#include <android-base/parsenetaddress.h>
-#include <android-base/quick_exit.h>
#include <android-base/stringprintf.h>
#include <android-base/strings.h>
#include <android-base/thread_annotations.h>
@@ -72,12 +71,14 @@
return false;
}
- if (packet->msg.data_length > sizeof(packet->data)) {
+ if (packet->msg.data_length > MAX_PAYLOAD) {
D("remote local: read overflow (data length = %" PRIu32 ")", packet->msg.data_length);
return false;
}
- if (!ReadFdExactly(fd_.get(), &packet->data, packet->msg.data_length)) {
+ packet->payload.resize(packet->msg.data_length);
+
+ if (!ReadFdExactly(fd_.get(), &packet->payload[0], packet->payload.size())) {
D("remote local: terminated (data)");
return false;
}
@@ -86,13 +87,18 @@
}
bool FdConnection::Write(apacket* packet) {
- uint32_t length = packet->msg.data_length;
-
- if (!WriteFdExactly(fd_.get(), &packet->msg, sizeof(amessage) + length)) {
+ if (!WriteFdExactly(fd_.get(), &packet->msg, sizeof(packet->msg))) {
D("remote local: write terminated");
return false;
}
+ if (packet->msg.data_length) {
+ if (!WriteFdExactly(fd_.get(), &packet->payload[0], packet->msg.data_length)) {
+ D("remote local: write terminated");
+ return false;
+ }
+ }
+
return true;
}
@@ -133,7 +139,7 @@
std::string result = android::base::StringPrintf("%s: %s: [%s] arg0=%s arg1=%s (len=%d) ", name,
func, cmd, arg0, arg1, len);
- result += dump_hex(p->data, len);
+ result += dump_hex(p->payload.data(), p->payload.size());
return result;
}
@@ -191,9 +197,10 @@
apacket* p = 0;
if (read_packet(fd, t->serial, &p)) {
D("%s: failed to read packet from transport socket on fd %d", t->serial, fd);
- } else {
- handle_packet(p, (atransport*)_t);
+ return;
}
+
+ handle_packet(p, (atransport*)_t);
}
}
@@ -243,6 +250,7 @@
p->msg.arg0 = 1;
p->msg.arg1 = ++(t->sync_token);
p->msg.magic = A_SYNC ^ 0xffffffff;
+ D("sending SYNC packet (len = %u, payload.size() = %zu)", p->msg.data_length, p->payload.size());
if (write_packet(t->fd, t->serial, &p)) {
put_apacket(p);
D("%s: failed to write SYNC packet", t->serial);
@@ -336,6 +344,13 @@
if (active) {
D("%s: transport got packet, sending to remote", t->serial);
ATRACE_NAME("write_transport write_remote");
+
+ // Allow sending the payload's implicit null terminator.
+ if (p->msg.data_length != p->payload.size()) {
+ LOG(FATAL) << "packet data length doesn't match payload: msg.data_length = "
+ << p->msg.data_length << ", payload.size() = " << p->payload.size();
+ }
+
if (t->Write(p) != 0) {
D("%s: remote write failed for transport", t->serial);
put_apacket(p);
diff --git a/adb/transport_usb.cpp b/adb/transport_usb.cpp
index a108699..d7565f6 100644
--- a/adb/transport_usb.cpp
+++ b/adb/transport_usb.cpp
@@ -61,13 +61,12 @@
static int UsbReadPayload(usb_handle* h, apacket* p) {
D("UsbReadPayload(%d)", p->msg.data_length);
- if (p->msg.data_length > sizeof(p->data)) {
+ if (p->msg.data_length > MAX_PAYLOAD) {
return -1;
}
#if CHECK_PACKET_OVERFLOW
size_t usb_packet_size = usb_get_max_packet_size(h);
- CHECK_EQ(0ULL, sizeof(p->data) % usb_packet_size);
// Round the data length up to the nearest packet size boundary.
// The device won't send a zero packet for packet size aligned payloads,
@@ -77,10 +76,18 @@
if (rem_size) {
len += usb_packet_size - rem_size;
}
- CHECK_LE(len, sizeof(p->data));
- return usb_read(h, &p->data, len);
+
+ p->payload.resize(len);
+ int rc = usb_read(h, &p->payload[0], p->payload.size());
+ if (rc != static_cast<int>(p->msg.data_length)) {
+ return -1;
+ }
+
+ p->payload.resize(rc);
+ return rc;
#else
- return usb_read(h, &p->data, p->msg.data_length);
+ p->payload.resize(p->msg.data_length);
+ return usb_read(h, &p->payload[0], p->payload.size());
#endif
}
@@ -120,12 +127,13 @@
}
if (p->msg.data_length) {
- if (p->msg.data_length > sizeof(p->data)) {
+ if (p->msg.data_length > MAX_PAYLOAD) {
PLOG(ERROR) << "remote usb: read overflow (data length = " << p->msg.data_length << ")";
return -1;
}
- if (usb_read(usb, p->data, p->msg.data_length)) {
+ p->payload.resize(p->msg.data_length);
+ if (usb_read(usb, &p->payload[0], p->payload.size())) {
PLOG(ERROR) << "remote usb: terminated (data)";
return -1;
}
@@ -152,7 +160,7 @@
return false;
}
- if (packet->msg.data_length != 0 && usb_write(handle_, &packet->data, size) != 0) {
+ if (packet->msg.data_length != 0 && usb_write(handle_, packet->payload.data(), size) != 0) {
PLOG(ERROR) << "remote usb: 2 - write terminated";
return false;
}
diff --git a/base/include/android-base/strings.h b/base/include/android-base/strings.h
index c11acb1..4d9fa34 100644
--- a/base/include/android-base/strings.h
+++ b/base/include/android-base/strings.h
@@ -67,8 +67,8 @@
// TODO: string_view
bool EndsWith(const std::string& s, const char* suffix);
bool EndsWithIgnoreCase(const std::string& s, const char* suffix);
-bool EndsWith(const std::string& s, const std::string& prefix);
-bool EndsWithIgnoreCase(const std::string& s, const std::string& prefix);
+bool EndsWith(const std::string& s, const std::string& suffix);
+bool EndsWithIgnoreCase(const std::string& s, const std::string& suffix);
// Tests whether 'lhs' equals 'rhs', ignoring case.
bool EqualsIgnoreCase(const std::string& lhs, const std::string& rhs);
diff --git a/debuggerd/Android.mk b/debuggerd/Android.mk
index 3bc1742..c03b41d 100644
--- a/debuggerd/Android.mk
+++ b/debuggerd/Android.mk
@@ -20,4 +20,5 @@
LOCAL_SRC_FILES_arm64 := seccomp_policy/crash_dump.arm64.policy
LOCAL_SRC_FILES_x86 := seccomp_policy/crash_dump.x86.policy
LOCAL_SRC_FILES_x86_64 := seccomp_policy/crash_dump.x86_64.policy
+LOCAL_MODULE_TARGET_ARCH := arm arm64 x86 x86_64
include $(BUILD_PREBUILT)
diff --git a/debuggerd/debuggerd_test.cpp b/debuggerd/debuggerd_test.cpp
index f8b4bad..397ff2f 100644
--- a/debuggerd/debuggerd_test.cpp
+++ b/debuggerd/debuggerd_test.cpp
@@ -20,6 +20,7 @@
#include <sys/capability.h>
#include <sys/prctl.h>
#include <sys/ptrace.h>
+#include <sys/resource.h>
#include <sys/syscall.h>
#include <sys/types.h>
#include <unistd.h>
@@ -570,7 +571,7 @@
static const char* const kDebuggerdSeccompPolicy =
"/system/etc/seccomp_policy/crash_dump." ABI_STRING ".policy";
-pid_t seccomp_fork() {
+static pid_t seccomp_fork_impl(void (*prejail)()) {
unique_fd policy_fd(open(kDebuggerdSeccompPolicy, O_RDONLY | O_CLOEXEC));
if (policy_fd == -1) {
LOG(FATAL) << "failed to open policy " << kDebuggerdSeccompPolicy;
@@ -607,10 +608,18 @@
continue;
}
+ if (prejail) {
+ prejail();
+ }
+
minijail_enter(jail.get());
return result;
}
+static pid_t seccomp_fork() {
+ return seccomp_fork_impl(nullptr);
+}
+
TEST_F(CrasherTest, seccomp_crash) {
int intercept_result;
unique_fd output_fd;
@@ -628,6 +637,46 @@
ASSERT_BACKTRACE_FRAME(result, "abort");
}
+static pid_t seccomp_fork_rlimit() {
+ return seccomp_fork_impl([]() {
+ struct rlimit rlim = {
+ .rlim_cur = 512 * 1024 * 1024,
+ .rlim_max = 512 * 1024 * 1024,
+ };
+
+ if (setrlimit(RLIMIT_AS, &rlim) != 0) {
+ raise(SIGINT);
+ }
+ });
+}
+
+TEST_F(CrasherTest, seccomp_crash_oom) {
+ int intercept_result;
+ unique_fd output_fd;
+
+ StartProcess(
+ []() {
+ std::vector<void*> vec;
+ for (int i = 0; i < 512; ++i) {
+ char* buf = static_cast<char*>(malloc(1024 * 1024));
+ if (!buf) {
+ abort();
+ }
+ memset(buf, 0xff, 1024 * 1024);
+ vec.push_back(buf);
+ }
+ },
+ &seccomp_fork_rlimit);
+
+ StartIntercept(&output_fd);
+ FinishCrasher();
+ AssertDeath(SIGABRT);
+ FinishIntercept(&intercept_result);
+ ASSERT_EQ(1, intercept_result) << "tombstoned reported failure";
+
+ // We can't actually generate a backtrace, just make sure that the process terminates.
+}
+
__attribute__((noinline)) extern "C" bool raise_debugger_signal(DebuggerdDumpType dump_type) {
siginfo_t siginfo;
siginfo.si_code = SI_QUEUE;
diff --git a/debuggerd/handler/debuggerd_fallback.cpp b/debuggerd/handler/debuggerd_fallback.cpp
index 364fca5..dea2e17 100644
--- a/debuggerd/handler/debuggerd_fallback.cpp
+++ b/debuggerd/handler/debuggerd_fallback.cpp
@@ -37,6 +37,7 @@
#include <atomic>
#include <memory>
+#include <mutex>
#include <android-base/file.h>
#include <android-base/unique_fd.h>
@@ -298,11 +299,13 @@
static void crash_handler(siginfo_t* info, ucontext_t* ucontext, void* abort_message) {
// Only allow one thread to handle a crash at a time (this can happen multiple times without
// exit, since tombstones can be requested without a real crash happening.)
- static pthread_mutex_t crash_mutex = PTHREAD_MUTEX_INITIALIZER;
- int ret = pthread_mutex_lock(&crash_mutex);
- if (ret != 0) {
- async_safe_format_log(ANDROID_LOG_INFO, "libc", "pthread_mutex_lock failed: %s", strerror(ret));
- return;
+ static std::recursive_mutex crash_mutex;
+ static int lock_count;
+
+ crash_mutex.lock();
+ if (lock_count++ > 0) {
+ async_safe_format_log(ANDROID_LOG_ERROR, "libc", "recursed signal handler call, exiting");
+ _exit(1);
}
unique_fd tombstone_socket, output_fd;
@@ -313,7 +316,8 @@
tombstoned_notify_completion(tombstone_socket.get());
}
- pthread_mutex_unlock(&crash_mutex);
+ --lock_count;
+ crash_mutex.unlock();
}
extern "C" void debuggerd_fallback_handler(siginfo_t* info, ucontext_t* ucontext,
diff --git a/fs_mgr/fs_mgr_fstab.cpp b/fs_mgr/fs_mgr_fstab.cpp
index 1c01d8c..9b7405a 100644
--- a/fs_mgr/fs_mgr_fstab.cpp
+++ b/fs_mgr/fs_mgr_fstab.cpp
@@ -39,6 +39,7 @@
char *key_loc;
char* key_dir;
char *verity_loc;
+ char *sysfs_path;
long long part_length;
char *label;
int partnum;
@@ -104,6 +105,7 @@
{"quota", MF_QUOTA},
{"eraseblk=", MF_ERASEBLKSIZE},
{"logicalblk=", MF_LOGICALBLKSIZE},
+ {"sysfs_path=", MF_SYSFS},
{"defaults", 0},
{0, 0},
};
@@ -341,6 +343,9 @@
unsigned int val = strtoul(strchr(p, '=') + 1, NULL, 0);
if (val >= 4096 && (val & (val - 1)) == 0)
flag_vals->logical_blk_size = val;
+ } else if ((fl[i].flag == MF_SYSFS) && flag_vals) {
+ /* The path to trigger device gc by idle-maint of vold. */
+ flag_vals->sysfs_path = strdup(strchr(p, '=') + 1);
}
break;
}
@@ -615,6 +620,7 @@
fstab->recs[cnt].file_names_mode = flag_vals.file_names_mode;
fstab->recs[cnt].erase_blk_size = flag_vals.erase_blk_size;
fstab->recs[cnt].logical_blk_size = flag_vals.logical_blk_size;
+ fstab->recs[cnt].sysfs_path = flag_vals.sysfs_path;
cnt++;
}
/* If an A/B partition, modify block device to be the real block device */
@@ -787,6 +793,7 @@
free(fstab->recs[i].key_loc);
free(fstab->recs[i].key_dir);
free(fstab->recs[i].label);
+ free(fstab->recs[i].sysfs_path);
}
/* Free the fstab_recs array created by calloc(3) */
@@ -922,3 +929,8 @@
int fs_mgr_is_quota(const struct fstab_rec* fstab) {
return fstab->fs_mgr_flags & MF_QUOTA;
}
+
+int fs_mgr_has_sysfs_path(const struct fstab_rec *fstab)
+{
+ return fstab->fs_mgr_flags & MF_SYSFS;
+}
diff --git a/fs_mgr/fs_mgr_priv.h b/fs_mgr/fs_mgr_priv.h
index 724156d..ade0cc4 100644
--- a/fs_mgr/fs_mgr_priv.h
+++ b/fs_mgr/fs_mgr_priv.h
@@ -109,7 +109,8 @@
#define MF_ERASEBLKSIZE 0x800000
#define MF_LOGICALBLKSIZE 0X1000000
#define MF_AVB 0X2000000
-#define MF_KEYDIRECTORY 0X4000000
+#define MF_KEYDIRECTORY 0X4000000
+#define MF_SYSFS 0X8000000
#define DM_BUF_SIZE 4096
diff --git a/fs_mgr/include_fstab/fstab/fstab.h b/fs_mgr/include_fstab/fstab/fstab.h
index 94aacfd..8c585dd 100644
--- a/fs_mgr/include_fstab/fstab/fstab.h
+++ b/fs_mgr/include_fstab/fstab/fstab.h
@@ -56,6 +56,7 @@
unsigned int file_names_mode;
unsigned int erase_blk_size;
unsigned int logical_blk_size;
+ char* sysfs_path;
};
struct fstab* fs_mgr_read_fstab_default();
@@ -83,6 +84,7 @@
int fs_mgr_is_nofail(const struct fstab_rec* fstab);
int fs_mgr_is_latemount(const struct fstab_rec* fstab);
int fs_mgr_is_quota(const struct fstab_rec* fstab);
+int fs_mgr_has_sysfs_path(const struct fstab_rec* fstab);
std::string fs_mgr_get_slot_suffix();
diff --git a/init/README.md b/init/README.md
index d7edf21..5c2352b 100644
--- a/init/README.md
+++ b/init/README.md
@@ -10,7 +10,11 @@
whitespace from breaking text into multiple tokens. The backslash,
when it is the last character on a line, may be used for line-folding.
-Lines which start with a # (leading whitespace allowed) are comments.
+Lines which start with a `#` (leading whitespace allowed) are comments.
+
+System properties can be expanded using the syntax
+`${property.name}`. This also works in contexts where concatenation is
+required, such as `import /init.recovery.${ro.hardware}.rc`.
Actions and Services implicitly declare a new section. All commands
or options belong to the section most recently declared. Commands
diff --git a/init/reboot.cpp b/init/reboot.cpp
index 242750a..03ed55a 100644
--- a/init/reboot.cpp
+++ b/init/reboot.cpp
@@ -20,6 +20,7 @@
#include <fcntl.h>
#include <linux/fs.h>
#include <mntent.h>
+#include <semaphore.h>
#include <sys/capability.h>
#include <sys/cdefs.h>
#include <sys/ioctl.h>
@@ -89,12 +90,13 @@
mnt_opts_(entry.mnt_opts) {}
bool Umount(bool force) {
+ LOG(INFO) << "Unmounting " << mnt_fsname_ << ":" << mnt_dir_ << " opts " << mnt_opts_;
int r = umount2(mnt_dir_.c_str(), force ? MNT_FORCE : 0);
if (r == 0) {
- LOG(INFO) << "umounted " << mnt_fsname_ << ":" << mnt_dir_ << " opts " << mnt_opts_;
+ LOG(INFO) << "Umounted " << mnt_fsname_ << ":" << mnt_dir_ << " opts " << mnt_opts_;
return true;
} else {
- PLOG(WARNING) << "cannot umount " << mnt_fsname_ << ":" << mnt_dir_ << " opts "
+ PLOG(WARNING) << "Cannot umount " << mnt_fsname_ << ":" << mnt_dir_ << " opts "
<< mnt_opts_;
return false;
}
@@ -328,39 +330,9 @@
return stat;
}
-void DoReboot(unsigned int cmd, const std::string& reason, const std::string& rebootTarget,
- bool runFsck) {
+void RebootThread(unsigned int cmd, std::chrono::milliseconds shutdown_timeout, bool runFsck,
+ sem_t* reboot_semaphore) {
Timer t;
- LOG(INFO) << "Reboot start, reason: " << reason << ", rebootTarget: " << rebootTarget;
-
- // Ensure last reboot reason is reduced to canonical
- // alias reported in bootloader or system boot reason.
- size_t skip = 0;
- std::vector<std::string> reasons = Split(reason, ",");
- if (reasons.size() >= 2 && reasons[0] == "reboot" &&
- (reasons[1] == "recovery" || reasons[1] == "bootloader" || reasons[1] == "cold" ||
- reasons[1] == "hard" || reasons[1] == "warm")) {
- skip = strlen("reboot,");
- }
- property_set(LAST_REBOOT_REASON_PROPERTY, reason.c_str() + skip);
- sync();
-
- bool is_thermal_shutdown = cmd == ANDROID_RB_THERMOFF;
-
- auto shutdown_timeout = 0ms;
- if (!SHUTDOWN_ZERO_TIMEOUT) {
- if (is_thermal_shutdown) {
- constexpr unsigned int thermal_shutdown_timeout = 1;
- shutdown_timeout = std::chrono::seconds(thermal_shutdown_timeout);
- } else {
- constexpr unsigned int shutdown_timeout_default = 6;
- auto shutdown_timeout_property = android::base::GetUintProperty(
- "ro.build.shutdown_timeout", shutdown_timeout_default);
- shutdown_timeout = std::chrono::seconds(shutdown_timeout_property);
- }
- }
- LOG(INFO) << "Shutdown timeout: " << shutdown_timeout.count() << " ms";
-
// keep debugging tools until non critical ones are all gone.
const std::set<std::string> kill_after_apps{"tombstoned", "logd", "adbd"};
// watchdogd is a vendor specific component but should be alive to complete shutdown safely.
@@ -384,7 +356,7 @@
}
// remaining operations (specifically fsck) may take a substantial duration
- if (cmd == ANDROID_RB_POWEROFF || is_thermal_shutdown) {
+ if (cmd == ANDROID_RB_POWEROFF || cmd == ANDROID_RB_THERMOFF) {
TurnOffBacklight();
}
@@ -461,8 +433,77 @@
UmountStat stat = TryUmountAndFsck(runFsck, shutdown_timeout - t.duration());
// Follow what linux shutdown is doing: one more sync with little bit delay
sync();
- if (!is_thermal_shutdown) std::this_thread::sleep_for(100ms);
+ if (cmd != ANDROID_RB_THERMOFF) std::this_thread::sleep_for(100ms);
LogShutdownTime(stat, &t);
+
+ if (reboot_semaphore != nullptr) {
+ sem_post(reboot_semaphore);
+ }
+}
+
+void RunRebootThread(unsigned int cmd, std::chrono::milliseconds shutdown_timeout) {
+ sem_t reboot_semaphore;
+ timespec shutdown_timeout_timespec;
+
+ if (sem_init(&reboot_semaphore, false, 0) == -1 ||
+ clock_gettime(CLOCK_REALTIME, &shutdown_timeout_timespec) == -1) {
+ // These should never fail, but if they do, skip the graceful reboot and reboot immediately.
+ return;
+ }
+
+ std::thread reboot_thread(&RebootThread, cmd, shutdown_timeout, false, &reboot_semaphore);
+ reboot_thread.detach();
+
+ // One extra second than the timeout passed to the thread as there is a final Umount pass
+ // after the timeout is reached.
+ shutdown_timeout_timespec.tv_sec += 1 + shutdown_timeout.count() / 1000;
+
+ int sem_return = 0;
+ while ((sem_return = sem_timedwait(&reboot_semaphore, &shutdown_timeout_timespec)) == -1 &&
+ errno == EINTR) {
+ }
+
+ if (sem_return == -1) {
+ LOG(ERROR) << "Reboot thread timed out";
+ }
+}
+
+void DoReboot(unsigned int cmd, const std::string& reason, const std::string& rebootTarget,
+ bool runFsck) {
+ LOG(INFO) << "Reboot start, reason: " << reason << ", rebootTarget: " << rebootTarget;
+
+ // Ensure last reboot reason is reduced to canonical
+ // alias reported in bootloader or system boot reason.
+ size_t skip = 0;
+ std::vector<std::string> reasons = Split(reason, ",");
+ if (reasons.size() >= 2 && reasons[0] == "reboot" &&
+ (reasons[1] == "recovery" || reasons[1] == "bootloader" || reasons[1] == "cold" ||
+ reasons[1] == "hard" || reasons[1] == "warm")) {
+ skip = strlen("reboot,");
+ }
+ property_set(LAST_REBOOT_REASON_PROPERTY, reason.c_str() + skip);
+ sync();
+
+ auto shutdown_timeout = 0ms;
+ if (!SHUTDOWN_ZERO_TIMEOUT) {
+ if (cmd == ANDROID_RB_THERMOFF) {
+ constexpr auto kThermalShutdownTimeout = 1s;
+ shutdown_timeout = kThermalShutdownTimeout;
+ } else {
+ constexpr unsigned int kShutdownTimeoutDefault = 6;
+ auto shutdown_timeout_property = android::base::GetUintProperty(
+ "ro.build.shutdown_timeout", kShutdownTimeoutDefault);
+ shutdown_timeout = std::chrono::seconds(shutdown_timeout_property);
+ }
+ }
+ LOG(INFO) << "Shutdown timeout: " << shutdown_timeout.count() << " ms";
+
+ if (runFsck) {
+ RebootThread(cmd, shutdown_timeout, true, nullptr);
+ } else {
+ RunRebootThread(cmd, shutdown_timeout);
+ }
+
// Reboot regardless of umount status. If umount fails, fsck after reboot will fix it.
RebootSystem(cmd, rebootTarget);
abort();
diff --git a/libbacktrace/UnwindStack.cpp b/libbacktrace/UnwindStack.cpp
index 0e32e47..711a12a 100644
--- a/libbacktrace/UnwindStack.cpp
+++ b/libbacktrace/UnwindStack.cpp
@@ -128,6 +128,22 @@
return true;
}
+bool Backtrace::UnwindOffline(unwindstack::Regs* regs, BacktraceMap* back_map,
+ const backtrace_stackinfo_t& stack,
+ std::vector<backtrace_frame_data_t>* frames,
+ BacktraceUnwindError* error) {
+ UnwindStackOfflineMap* offline_map = reinterpret_cast<UnwindStackOfflineMap*>(back_map);
+ // Create the process memory from the stack data since this will almost
+ // always be different each unwind.
+ if (!offline_map->CreateProcessMemory(stack)) {
+ if (error != nullptr) {
+ error->error_code = BACKTRACE_UNWIND_ERROR_SETUP_FAILED;
+ }
+ return false;
+ }
+ return Backtrace::Unwind(regs, back_map, frames, 0U, nullptr, error);
+}
+
UnwindStackCurrent::UnwindStackCurrent(pid_t pid, pid_t tid, BacktraceMap* map)
: BacktraceCurrent(pid, tid, map) {}
@@ -221,12 +237,12 @@
Backtrace* Backtrace::CreateOffline(ArchEnum arch, pid_t pid, pid_t tid,
const std::vector<backtrace_map_t>& maps,
const backtrace_stackinfo_t& stack) {
- BacktraceMap* map = BacktraceMap::CreateOffline(pid, maps, stack);
- if (map == nullptr) {
+ std::unique_ptr<UnwindStackOfflineMap> map(
+ reinterpret_cast<UnwindStackOfflineMap*>(BacktraceMap::CreateOffline(pid, maps)));
+ if (map.get() == nullptr || !map->CreateProcessMemory(stack)) {
return nullptr;
}
-
- return new UnwindStackOffline(arch, pid, tid, map, false);
+ return new UnwindStackOffline(arch, pid, tid, map.release(), false);
}
Backtrace* Backtrace::CreateOffline(ArchEnum arch, pid_t pid, pid_t tid, BacktraceMap* map) {
diff --git a/libbacktrace/UnwindStackMap.cpp b/libbacktrace/UnwindStackMap.cpp
index 6dcc621..9c6fed4 100644
--- a/libbacktrace/UnwindStackMap.cpp
+++ b/libbacktrace/UnwindStackMap.cpp
@@ -127,12 +127,7 @@
return false;
}
-bool UnwindStackOfflineMap::Build(const std::vector<backtrace_map_t>& backtrace_maps,
- const backtrace_stackinfo_t& stack) {
- if (stack.start >= stack.end) {
- return false;
- }
-
+bool UnwindStackOfflineMap::Build(const std::vector<backtrace_map_t>& backtrace_maps) {
for (const backtrace_map_t& map : backtrace_maps) {
maps_.push_back(map);
}
@@ -145,6 +140,13 @@
for (const backtrace_map_t& map : maps_) {
maps->Add(map.start, map.end, map.offset, map.flags, map.name, map.load_bias);
}
+ return true;
+}
+
+bool UnwindStackOfflineMap::CreateProcessMemory(const backtrace_stackinfo_t& stack) {
+ if (stack.start >= stack.end) {
+ return false;
+ }
// Create the process memory from the stack data.
uint64_t size = stack.end - stack.start;
@@ -154,7 +156,6 @@
std::shared_ptr<unwindstack::Memory> shared_memory(memory);
process_memory_.reset(new unwindstack::MemoryRange(shared_memory, 0, size, stack.start));
-
return true;
}
@@ -182,10 +183,9 @@
//-------------------------------------------------------------------------
// BacktraceMap create offline function.
//-------------------------------------------------------------------------
-BacktraceMap* BacktraceMap::CreateOffline(pid_t pid, const std::vector<backtrace_map_t>& maps,
- const backtrace_stackinfo_t& stack) {
+BacktraceMap* BacktraceMap::CreateOffline(pid_t pid, const std::vector<backtrace_map_t>& maps) {
UnwindStackOfflineMap* map = new UnwindStackOfflineMap(pid);
- if (!map->Build(maps, stack)) {
+ if (!map->Build(maps)) {
delete map;
return nullptr;
}
diff --git a/libbacktrace/UnwindStackMap.h b/libbacktrace/UnwindStackMap.h
index 94cbfb2..ec0d9c1 100644
--- a/libbacktrace/UnwindStackMap.h
+++ b/libbacktrace/UnwindStackMap.h
@@ -76,7 +76,9 @@
bool Build() override;
- bool Build(const std::vector<backtrace_map_t>& maps, const backtrace_stackinfo_t& stack);
+ bool Build(const std::vector<backtrace_map_t>& maps);
+
+ bool CreateProcessMemory(const backtrace_stackinfo_t& stack);
};
#endif // _LIBBACKTRACE_UNWINDSTACK_MAP_H
diff --git a/libbacktrace/include/backtrace/Backtrace.h b/libbacktrace/include/backtrace/Backtrace.h
index 7a37015..a088207 100644
--- a/libbacktrace/include/backtrace/Backtrace.h
+++ b/libbacktrace/include/backtrace/Backtrace.h
@@ -151,6 +151,11 @@
std::vector<backtrace_frame_data_t>* frames, size_t num_ignore_frames,
std::vector<std::string>* skip_names, BacktraceUnwindError* error = nullptr);
+ static bool UnwindOffline(unwindstack::Regs* regs, BacktraceMap* back_map,
+ const backtrace_stackinfo_t& stack_info,
+ std::vector<backtrace_frame_data_t>* frames,
+ BacktraceUnwindError* error = nullptr);
+
// Get the function name and offset into the function given the pc.
// If the string is empty, then no valid function name was found,
// or the pc is not in any valid map.
diff --git a/libbacktrace/include/backtrace/BacktraceMap.h b/libbacktrace/include/backtrace/BacktraceMap.h
index da54472..473d195 100644
--- a/libbacktrace/include/backtrace/BacktraceMap.h
+++ b/libbacktrace/include/backtrace/BacktraceMap.h
@@ -64,8 +64,7 @@
// is unsupported.
static BacktraceMap* Create(pid_t pid, bool uncached = false);
- static BacktraceMap* CreateOffline(pid_t pid, const std::vector<backtrace_map_t>& maps,
- const backtrace_stackinfo_t& stack);
+ static BacktraceMap* CreateOffline(pid_t pid, const std::vector<backtrace_map_t>& maps);
virtual ~BacktraceMap();
diff --git a/libcutils/fs_config.cpp b/libcutils/fs_config.cpp
index a993d41..5ea981f 100644
--- a/libcutils/fs_config.cpp
+++ b/libcutils/fs_config.cpp
@@ -202,16 +202,6 @@
CAP_MASK_LONG(CAP_NET_RAW),
"vendor/bin/hw/android.hardware.wifi@1.0-service" },
- // A non-privileged zygote that spawns isolated processes for web rendering.
- { 0750, AID_ROOT, AID_ROOT, CAP_MASK_LONG(CAP_SETUID) |
- CAP_MASK_LONG(CAP_SETGID) |
- CAP_MASK_LONG(CAP_SETPCAP),
- "system/bin/webview_zygote32" },
- { 0750, AID_ROOT, AID_ROOT, CAP_MASK_LONG(CAP_SETUID) |
- CAP_MASK_LONG(CAP_SETGID) |
- CAP_MASK_LONG(CAP_SETPCAP),
- "system/bin/webview_zygote64" },
-
// generic defaults
{ 00755, AID_ROOT, AID_ROOT, 0, "bin/*" },
{ 00640, AID_ROOT, AID_SHELL, 0, "fstab.*" },
diff --git a/libprocessgroup/Android.bp b/libprocessgroup/Android.bp
index 1974f2c..b0bc497 100644
--- a/libprocessgroup/Android.bp
+++ b/libprocessgroup/Android.bp
@@ -1,7 +1,7 @@
cc_library {
srcs: ["processgroup.cpp"],
name: "libprocessgroup",
- defaults: ["linux_bionic_supported"],
+ host_supported: true,
shared_libs: ["libbase"],
export_include_dirs: ["include"],
cflags: [
diff --git a/libprocessgroup/processgroup.cpp b/libprocessgroup/processgroup.cpp
index 8526b3a..6dfa697 100644
--- a/libprocessgroup/processgroup.cpp
+++ b/libprocessgroup/processgroup.cpp
@@ -22,6 +22,7 @@
#include <errno.h>
#include <fcntl.h>
#include <inttypes.h>
+#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -33,15 +34,19 @@
#include <memory>
#include <mutex>
#include <set>
+#include <string>
#include <thread>
#include <android-base/file.h>
#include <android-base/logging.h>
-#include <android-base/unique_fd.h>
+#include <android-base/stringprintf.h>
+#include <android-base/strings.h>
#include <private/android_filesystem_config.h>
#include <processgroup/processgroup.h>
+using android::base::StartsWith;
+using android::base::StringPrintf;
using android::base::WriteStringToFile;
using namespace std::chrono_literals;
@@ -50,171 +55,58 @@
#define MEM_CGROUP_TASKS "/dev/memcg/apps/tasks"
#define ACCT_CGROUP_PATH "/acct"
-#define PROCESSGROUP_UID_PREFIX "uid_"
-#define PROCESSGROUP_PID_PREFIX "pid_"
#define PROCESSGROUP_CGROUP_PROCS_FILE "/cgroup.procs"
-#define PROCESSGROUP_MAX_UID_LEN 11
-#define PROCESSGROUP_MAX_PID_LEN 11
-#define PROCESSGROUP_MAX_PATH_LEN \
- ((sizeof(MEM_CGROUP_PATH) > sizeof(ACCT_CGROUP_PATH) ? \
- sizeof(MEM_CGROUP_PATH) : sizeof(ACCT_CGROUP_PATH)) + \
- sizeof(PROCESSGROUP_UID_PREFIX) + 1 + \
- PROCESSGROUP_MAX_UID_LEN + \
- sizeof(PROCESSGROUP_PID_PREFIX) + 1 + \
- PROCESSGROUP_MAX_PID_LEN + \
- sizeof(PROCESSGROUP_CGROUP_PROCS_FILE) + \
- 1)
std::once_flag init_path_flag;
-class ProcessGroup {
- public:
- ProcessGroup() : buf_ptr_(buf_), buf_len_(0) {}
-
- bool Open(uid_t uid, int pid);
-
- // Return positive number and sets *pid = next pid in process cgroup on success
- // Returns 0 if there are no pids left in the process cgroup
- // Returns -errno if an error was encountered
- int GetOneAppProcess(pid_t* pid);
-
- private:
- // Returns positive number of bytes filled on success
- // Returns 0 if there was nothing to read
- // Returns -errno if an error was encountered
- int RefillBuffer();
-
- android::base::unique_fd fd_;
- char buf_[128];
- char* buf_ptr_;
- size_t buf_len_;
-};
-
-static const char* getCgroupRootPath() {
- static const char* cgroup_root_path = NULL;
+static const std::string& GetCgroupRootPath() {
+ static std::string cgroup_root_path;
std::call_once(init_path_flag, [&]() {
// Check if mem cgroup is mounted, only then check for write-access to avoid
// SELinux denials
- cgroup_root_path = access(MEM_CGROUP_TASKS, F_OK) || access(MEM_CGROUP_PATH, W_OK) ?
- ACCT_CGROUP_PATH : MEM_CGROUP_PATH;
+ cgroup_root_path =
+ (access(MEM_CGROUP_TASKS, F_OK) || access(MEM_CGROUP_PATH, W_OK) ? ACCT_CGROUP_PATH
+ : MEM_CGROUP_PATH);
});
return cgroup_root_path;
}
-static int convertUidToPath(char *path, size_t size, uid_t uid)
-{
- return snprintf(path, size, "%s/%s%d",
- getCgroupRootPath(),
- PROCESSGROUP_UID_PREFIX,
- uid);
+static std::string ConvertUidToPath(uid_t uid) {
+ return StringPrintf("%s/uid_%d", GetCgroupRootPath().c_str(), uid);
}
-static int convertUidPidToPath(char *path, size_t size, uid_t uid, int pid)
-{
- return snprintf(path, size, "%s/%s%d/%s%d",
- getCgroupRootPath(),
- PROCESSGROUP_UID_PREFIX,
- uid,
- PROCESSGROUP_PID_PREFIX,
- pid);
+static std::string ConvertUidPidToPath(uid_t uid, int pid) {
+ return StringPrintf("%s/uid_%d/pid_%d", GetCgroupRootPath().c_str(), uid, pid);
}
-bool ProcessGroup::Open(uid_t uid, int pid) {
- char path[PROCESSGROUP_MAX_PATH_LEN] = {0};
- convertUidPidToPath(path, sizeof(path), uid, pid);
- strlcat(path, PROCESSGROUP_CGROUP_PROCS_FILE, sizeof(path));
-
- int fd = open(path, O_RDONLY);
- if (fd < 0) return false;
-
- fd_.reset(fd);
-
- LOG(VERBOSE) << "Initialized context for " << path;
-
- return true;
-}
-
-int ProcessGroup::RefillBuffer() {
- memmove(buf_, buf_ptr_, buf_len_);
- buf_ptr_ = buf_;
-
- ssize_t ret = read(fd_, buf_ptr_ + buf_len_, sizeof(buf_) - buf_len_ - 1);
- if (ret < 0) {
- return -errno;
- } else if (ret == 0) {
- return 0;
- }
-
- buf_len_ += ret;
- buf_[buf_len_] = 0;
- LOG(VERBOSE) << "Read " << ret << " to buffer: " << buf_;
-
- assert(buf_len_ <= sizeof(buf_));
-
- return ret;
-}
-
-int ProcessGroup::GetOneAppProcess(pid_t* out_pid) {
- *out_pid = 0;
-
- char* eptr;
- while ((eptr = static_cast<char*>(memchr(buf_ptr_, '\n', buf_len_))) == nullptr) {
- int ret = RefillBuffer();
- if (ret <= 0) return ret;
- }
-
- *eptr = '\0';
- char* pid_eptr = nullptr;
- errno = 0;
- long pid = strtol(buf_ptr_, &pid_eptr, 10);
- if (errno != 0) {
- return -errno;
- }
- if (pid_eptr != eptr) {
- errno = EINVAL;
- return -errno;
- }
-
- buf_len_ -= (eptr - buf_ptr_) + 1;
- buf_ptr_ = eptr + 1;
-
- *out_pid = static_cast<pid_t>(pid);
- return 1;
-}
-
-static int removeProcessGroup(uid_t uid, int pid)
-{
+static int RemoveProcessGroup(uid_t uid, int pid) {
int ret;
- char path[PROCESSGROUP_MAX_PATH_LEN] = {0};
- convertUidPidToPath(path, sizeof(path), uid, pid);
- ret = rmdir(path);
+ auto uid_pid_path = ConvertUidPidToPath(uid, pid);
+ ret = rmdir(uid_pid_path.c_str());
- convertUidToPath(path, sizeof(path), uid);
- rmdir(path);
+ auto uid_path = ConvertUidToPath(uid);
+ rmdir(uid_path.c_str());
return ret;
}
-static void removeUidProcessGroups(const char *uid_path)
-{
- std::unique_ptr<DIR, decltype(&closedir)> uid(opendir(uid_path), closedir);
+static void RemoveUidProcessGroups(const std::string& uid_path) {
+ std::unique_ptr<DIR, decltype(&closedir)> uid(opendir(uid_path.c_str()), closedir);
if (uid != NULL) {
dirent* dir;
while ((dir = readdir(uid.get())) != nullptr) {
- char path[PROCESSGROUP_MAX_PATH_LEN];
-
if (dir->d_type != DT_DIR) {
continue;
}
- if (strncmp(dir->d_name, PROCESSGROUP_PID_PREFIX, strlen(PROCESSGROUP_PID_PREFIX))) {
+ if (!StartsWith(dir->d_name, "pid_")) {
continue;
}
- snprintf(path, sizeof(path), "%s/%s", uid_path, dir->d_name);
+ auto path = StringPrintf("%s/%s", uid_path.c_str(), dir->d_name);
LOG(VERBOSE) << "Removing " << path;
- if (rmdir(path) == -1) PLOG(WARNING) << "Failed to remove " << path;
+ if (rmdir(path.c_str()) == -1) PLOG(WARNING) << "Failed to remove " << path;
}
}
}
@@ -222,38 +114,38 @@
void removeAllProcessGroups()
{
LOG(VERBOSE) << "removeAllProcessGroups()";
- const char* cgroup_root_path = getCgroupRootPath();
- std::unique_ptr<DIR, decltype(&closedir)> root(opendir(cgroup_root_path), closedir);
+ const auto& cgroup_root_path = GetCgroupRootPath();
+ std::unique_ptr<DIR, decltype(&closedir)> root(opendir(cgroup_root_path.c_str()), closedir);
if (root == NULL) {
PLOG(ERROR) << "Failed to open " << cgroup_root_path;
} else {
dirent* dir;
while ((dir = readdir(root.get())) != nullptr) {
- char path[PROCESSGROUP_MAX_PATH_LEN];
-
if (dir->d_type != DT_DIR) {
continue;
}
- if (strncmp(dir->d_name, PROCESSGROUP_UID_PREFIX, strlen(PROCESSGROUP_UID_PREFIX))) {
+
+ if (!StartsWith(dir->d_name, "uid_")) {
continue;
}
- snprintf(path, sizeof(path), "%s/%s", cgroup_root_path, dir->d_name);
- removeUidProcessGroups(path);
+ auto path = StringPrintf("%s/%s", cgroup_root_path.c_str(), dir->d_name);
+ RemoveUidProcessGroups(path);
LOG(VERBOSE) << "Removing " << path;
- if (rmdir(path) == -1) PLOG(WARNING) << "Failed to remove " << path;
+ if (rmdir(path.c_str()) == -1) PLOG(WARNING) << "Failed to remove " << path;
}
}
}
// Returns number of processes killed on success
// Returns 0 if there are no processes in the process cgroup left to kill
-// Returns -errno on error
-static int doKillProcessGroupOnce(uid_t uid, int initialPid, int signal) {
- ProcessGroup process_group;
- if (!process_group.Open(uid, initialPid)) {
+// Returns -1 on error
+static int DoKillProcessGroupOnce(uid_t uid, int initialPid, int signal) {
+ auto path = ConvertUidPidToPath(uid, initialPid) + PROCESSGROUP_CGROUP_PROCS_FILE;
+ std::unique_ptr<FILE, decltype(&fclose)> fd(fopen(path.c_str(), "re"), fclose);
+ if (!fd) {
PLOG(WARNING) << "Failed to open process cgroup uid " << uid << " pid " << initialPid;
- return -errno;
+ return -1;
}
// We separate all of the pids in the cgroup into those pids that are also the leaders of
@@ -262,10 +154,9 @@
pgids.emplace(initialPid);
std::set<pid_t> pids;
- int ret;
pid_t pid;
int processes = 0;
- while ((ret = process_group.GetOneAppProcess(&pid)) > 0 && pid >= 0) {
+ while (fscanf(fd.get(), "%d\n", &pid) == 1 && pid >= 0) {
processes++;
if (pid == 0) {
// Should never happen... but if it does, trying to kill this
@@ -312,15 +203,15 @@
}
}
- return ret >= 0 ? processes : ret;
+ return feof(fd.get()) ? processes : -1;
}
-static int killProcessGroup(uid_t uid, int initialPid, int signal, int retries) {
+static int KillProcessGroup(uid_t uid, int initialPid, int signal, int retries) {
std::chrono::steady_clock::time_point start = std::chrono::steady_clock::now();
int retry = retries;
int processes;
- while ((processes = doKillProcessGroupOnce(uid, initialPid, signal)) > 0) {
+ while ((processes = DoKillProcessGroupOnce(uid, initialPid, signal)) > 0) {
LOG(VERBOSE) << "Killed " << processes << " processes for processgroup " << initialPid;
if (retry > 0) {
std::this_thread::sleep_for(5ms);
@@ -350,7 +241,7 @@
LOG(INFO) << "Successfully killed process cgroup uid " << uid << " pid " << initialPid
<< " in " << static_cast<int>(ms) << "ms";
}
- return removeProcessGroup(uid, initialPid);
+ return RemoveProcessGroup(uid, initialPid);
} else {
if (retries > 0) {
LOG(ERROR) << "Failed to kill process cgroup uid " << uid << " pid " << initialPid
@@ -362,22 +253,21 @@
}
int killProcessGroup(uid_t uid, int initialPid, int signal) {
- return killProcessGroup(uid, initialPid, signal, 40 /*retries*/);
+ return KillProcessGroup(uid, initialPid, signal, 40 /*retries*/);
}
int killProcessGroupOnce(uid_t uid, int initialPid, int signal) {
- return killProcessGroup(uid, initialPid, signal, 0 /*retries*/);
+ return KillProcessGroup(uid, initialPid, signal, 0 /*retries*/);
}
-static bool mkdirAndChown(const char *path, mode_t mode, uid_t uid, gid_t gid)
-{
- if (mkdir(path, mode) == -1 && errno != EEXIST) {
+static bool MkdirAndChown(const std::string& path, mode_t mode, uid_t uid, gid_t gid) {
+ if (mkdir(path.c_str(), mode) == -1 && errno != EEXIST) {
return false;
}
- if (chown(path, uid, gid) == -1) {
+ if (chown(path.c_str(), uid, gid) == -1) {
int saved_errno = errno;
- rmdir(path);
+ rmdir(path.c_str());
errno = saved_errno;
return false;
}
@@ -387,42 +277,38 @@
int createProcessGroup(uid_t uid, int initialPid)
{
- char path[PROCESSGROUP_MAX_PATH_LEN] = {0};
+ auto uid_path = ConvertUidToPath(uid);
- convertUidToPath(path, sizeof(path), uid);
-
- if (!mkdirAndChown(path, 0750, AID_SYSTEM, AID_SYSTEM)) {
- PLOG(ERROR) << "Failed to make and chown " << path;
+ if (!MkdirAndChown(uid_path, 0750, AID_SYSTEM, AID_SYSTEM)) {
+ PLOG(ERROR) << "Failed to make and chown " << uid_path;
return -errno;
}
- convertUidPidToPath(path, sizeof(path), uid, initialPid);
+ auto uid_pid_path = ConvertUidPidToPath(uid, initialPid);
- if (!mkdirAndChown(path, 0750, AID_SYSTEM, AID_SYSTEM)) {
- PLOG(ERROR) << "Failed to make and chown " << path;
+ if (!MkdirAndChown(uid_pid_path, 0750, AID_SYSTEM, AID_SYSTEM)) {
+ PLOG(ERROR) << "Failed to make and chown " << uid_pid_path;
return -errno;
}
- strlcat(path, PROCESSGROUP_CGROUP_PROCS_FILE, sizeof(path));
+ auto uid_pid_procs_file = uid_pid_path + PROCESSGROUP_CGROUP_PROCS_FILE;
int ret = 0;
- if (!WriteStringToFile(std::to_string(initialPid), path)) {
+ if (!WriteStringToFile(std::to_string(initialPid), uid_pid_procs_file)) {
ret = -errno;
- PLOG(ERROR) << "Failed to write '" << initialPid << "' to " << path;
+ PLOG(ERROR) << "Failed to write '" << initialPid << "' to " << uid_pid_procs_file;
}
return ret;
}
-static bool setProcessGroupValue(uid_t uid, int pid, const char* fileName, int64_t value) {
- char path[PROCESSGROUP_MAX_PATH_LEN] = {0};
- if (strcmp(getCgroupRootPath(), MEM_CGROUP_PATH)) {
- PLOG(ERROR) << "Memcg is not mounted." << path;
+static bool SetProcessGroupValue(uid_t uid, int pid, const std::string& file_name, int64_t value) {
+ if (GetCgroupRootPath() != MEM_CGROUP_PATH) {
+ PLOG(ERROR) << "Memcg is not mounted.";
return false;
}
- convertUidPidToPath(path, sizeof(path), uid, pid);
- strlcat(path, fileName, sizeof(path));
+ auto path = ConvertUidPidToPath(uid, pid) + file_name;
if (!WriteStringToFile(std::to_string(value), path)) {
PLOG(ERROR) << "Failed to write '" << value << "' to " << path;
@@ -432,13 +318,13 @@
}
bool setProcessGroupSwappiness(uid_t uid, int pid, int swappiness) {
- return setProcessGroupValue(uid, pid, "/memory.swappiness", swappiness);
+ return SetProcessGroupValue(uid, pid, "/memory.swappiness", swappiness);
}
bool setProcessGroupSoftLimit(uid_t uid, int pid, int64_t soft_limit_in_bytes) {
- return setProcessGroupValue(uid, pid, "/memory.soft_limit_in_bytes", soft_limit_in_bytes);
+ return SetProcessGroupValue(uid, pid, "/memory.soft_limit_in_bytes", soft_limit_in_bytes);
}
bool setProcessGroupLimit(uid_t uid, int pid, int64_t limit_in_bytes) {
- return setProcessGroupValue(uid, pid, "/memory.limit_in_bytes", limit_in_bytes);
+ return SetProcessGroupValue(uid, pid, "/memory.limit_in_bytes", limit_in_bytes);
}
diff --git a/libunwindstack/DexFiles.cpp b/libunwindstack/DexFiles.cpp
index c5f8138..430f6c5 100644
--- a/libunwindstack/DexFiles.cpp
+++ b/libunwindstack/DexFiles.cpp
@@ -77,7 +77,8 @@
uint64_t DexFiles::ReadEntryPtr32(uint64_t addr) {
uint32_t entry;
- if (!memory_->ReadFully(addr, &entry, sizeof(entry))) {
+ const uint32_t field_offset = 12; // offset of first_entry_ in the descriptor struct.
+ if (!memory_->ReadFully(addr + field_offset, &entry, sizeof(entry))) {
return 0;
}
return entry;
@@ -85,7 +86,8 @@
uint64_t DexFiles::ReadEntryPtr64(uint64_t addr) {
uint64_t entry;
- if (!memory_->ReadFully(addr, &entry, sizeof(entry))) {
+ const uint32_t field_offset = 16; // offset of first_entry_ in the descriptor struct.
+ if (!memory_->ReadFully(addr + field_offset, &entry, sizeof(entry))) {
return 0;
}
return entry;
@@ -122,7 +124,7 @@
initialized_ = true;
entry_addr_ = 0;
- const std::string dex_debug_name("__art_debug_dexfiles");
+ const std::string dex_debug_name("__dex_debug_descriptor");
for (MapInfo* info : *maps) {
if (!(info->flags & PROT_EXEC) || !(info->flags & PROT_READ) || info->offset != 0) {
continue;
diff --git a/libunwindstack/tests/DexFilesTest.cpp b/libunwindstack/tests/DexFilesTest.cpp
index dca5605..d029bb0 100644
--- a/libunwindstack/tests/DexFilesTest.cpp
+++ b/libunwindstack/tests/DexFilesTest.cpp
@@ -63,7 +63,7 @@
elf->FakeSetValid(true);
ElfInterfaceFake* interface = new ElfInterfaceFake(memory);
elf->FakeSetInterface(interface);
- interface->FakeSetGlobalVariable("__art_debug_dexfiles", 0x800);
+ interface->FakeSetGlobalVariable("__dex_debug_descriptor", 0x800);
map_info->elf.reset(elf);
// Global variable not set by default.
@@ -74,7 +74,7 @@
elf->FakeSetValid(true);
interface = new ElfInterfaceFake(memory);
elf->FakeSetInterface(interface);
- interface->FakeSetGlobalVariable("__art_debug_dexfiles", 0x800);
+ interface->FakeSetGlobalVariable("__dex_debug_descriptor", 0x800);
map_info->elf.reset(elf);
// Global variable set in this map.
@@ -85,10 +85,12 @@
elf->FakeSetValid(true);
interface = new ElfInterfaceFake(memory);
elf->FakeSetInterface(interface);
- interface->FakeSetGlobalVariable("__art_debug_dexfiles", 0x800);
+ interface->FakeSetGlobalVariable("__dex_debug_descriptor", 0x800);
map_info->elf.reset(elf);
}
+ void WriteDescriptor32(uint64_t addr, uint32_t head);
+ void WriteDescriptor64(uint64_t addr, uint64_t head);
void WriteEntry32(uint64_t entry_addr, uint32_t next, uint32_t prev, uint32_t dex_file);
void WriteEntry64(uint64_t entry_addr, uint64_t next, uint64_t prev, uint64_t dex_file);
void WriteDex(uint64_t dex_file);
@@ -105,6 +107,16 @@
std::unique_ptr<BufferMaps> maps_;
};
+void DexFilesTest::WriteDescriptor32(uint64_t addr, uint32_t head) {
+ // void* first_entry_
+ memory_->SetData32(addr + 12, head);
+}
+
+void DexFilesTest::WriteDescriptor64(uint64_t addr, uint64_t head) {
+ // void* first_entry_
+ memory_->SetData64(addr + 16, head);
+}
+
void DexFilesTest::WriteEntry32(uint64_t entry_addr, uint32_t next, uint32_t prev,
uint32_t dex_file) {
// Format of the 32 bit DEXFileEntry structure:
@@ -146,7 +158,7 @@
uint64_t method_offset = 0x124;
MapInfo* info = maps_->Get(kMapDexFiles);
- memory_->SetData32(0xf800, 0x200000);
+ WriteDescriptor32(0xf800, 0x200000);
WriteEntry32(0x200000, 0, 0, 0x300000);
WriteDex(0x300000);
@@ -161,7 +173,7 @@
MapInfo* info = maps_->Get(kMapDexFiles);
dex_files_->SetArch(ARCH_ARM64);
- memory_->SetData64(0xf800, 0x200000);
+ WriteDescriptor64(0xf800, 0x200000);
WriteEntry64(0x200000, 0, 0, 0x301000);
WriteDex(0x301000);
@@ -175,7 +187,7 @@
uint64_t method_offset = 0x124;
MapInfo* info = maps_->Get(kMapDexFiles);
- memory_->SetData32(0xf800, 0x200000);
+ WriteDescriptor32(0xf800, 0x200000);
WriteEntry32(0x200000, 0x200100, 0, 0x100000);
WriteEntry32(0x200100, 0, 0x200000, 0x300000);
WriteDex(0x300000);
@@ -191,7 +203,7 @@
MapInfo* info = maps_->Get(kMapDexFiles);
dex_files_->SetArch(ARCH_ARM64);
- memory_->SetData64(0xf800, 0x200000);
+ WriteDescriptor64(0xf800, 0x200000);
WriteEntry64(0x200000, 0x200100, 0, 0x100000);
WriteEntry64(0x200100, 0, 0x200000, 0x300000);
WriteDex(0x300000);
@@ -206,7 +218,7 @@
uint64_t method_offset = 0x124;
MapInfo* info = maps_->Get(kMapDexFiles);
- memory_->SetData32(0xf800, 0x200000);
+ WriteDescriptor32(0xf800, 0x200000);
WriteEntry32(0x200000, 0, 0, 0x300000);
WriteDex(0x300000);
@@ -226,7 +238,7 @@
uint64_t method_offset = 0x124;
MapInfo* info = maps_->Get(kMapDexFiles);
- memory_->SetData32(0xf800, 0x200000);
+ WriteDescriptor32(0xf800, 0x200000);
WriteEntry32(0x200000, 0x200100, 0, 0x100000);
WriteEntry32(0x200100, 0, 0x200000, 0x300000);
WriteDex(0x300000);
@@ -259,9 +271,9 @@
MapInfo* info = maps_->Get(kMapDexFiles);
// First global variable found, but value is zero.
- memory_->SetData32(0xc800, 0);
+ WriteDescriptor32(0xc800, 0);
- memory_->SetData32(0xf800, 0x200000);
+ WriteDescriptor32(0xf800, 0x200000);
WriteEntry32(0x200000, 0, 0, 0x300000);
WriteDex(0x300000);
@@ -274,7 +286,7 @@
dex_files_->SetArch(ARCH_ARM);
method_name = "fail";
method_offset = 0x123;
- memory_->SetData32(0xc800, 0x100000);
+ WriteDescriptor32(0xc800, 0x100000);
dex_files_->GetMethodInformation(maps_.get(), info, 0x300100, &method_name, &method_offset);
EXPECT_EQ("fail", method_name);
EXPECT_EQ(0x123U, method_offset);
@@ -286,9 +298,9 @@
MapInfo* info = maps_->Get(kMapDexFiles);
// First global variable found, but value is zero.
- memory_->SetData64(0xc800, 0);
+ WriteDescriptor64(0xc800, 0);
- memory_->SetData64(0xf800, 0x200000);
+ WriteDescriptor64(0xf800, 0x200000);
WriteEntry64(0x200000, 0, 0, 0x300000);
WriteDex(0x300000);
@@ -302,7 +314,7 @@
dex_files_->SetArch(ARCH_ARM64);
method_name = "fail";
method_offset = 0x123;
- memory_->SetData32(0xc800, 0x100000);
+ WriteDescriptor64(0xc800, 0x100000);
dex_files_->GetMethodInformation(maps_.get(), info, 0x300100, &method_name, &method_offset);
EXPECT_EQ("fail", method_name);
EXPECT_EQ(0x123U, method_offset);
diff --git a/libutils/Android.bp b/libutils/Android.bp
index 209bf9a..80dcdcb 100644
--- a/libutils/Android.bp
+++ b/libutils/Android.bp
@@ -201,5 +201,3 @@
"-Werror",
],
}
-
-subdirs = ["tests"]