Merge "libkeymaster1 split"
diff --git a/adb/Android.mk b/adb/Android.mk
index 408b78d..1b201c8 100644
--- a/adb/Android.mk
+++ b/adb/Android.mk
@@ -17,11 +17,15 @@
-Wvla \
-DADB_REVISION='"$(adb_version)"' \
-ADB_COMMON_linux_CFLAGS := \
+ADB_COMMON_posix_CFLAGS := \
-Wexit-time-destructors \
+ -Wthread-safety
+
+ADB_COMMON_linux_CFLAGS := \
+ $(ADB_COMMON_posix_CFLAGS) \
ADB_COMMON_darwin_CFLAGS := \
- -Wexit-time-destructors \
+ $(ADB_COMMON_posix_CFLAGS) \
# Define windows.h and tchar.h Unicode preprocessor symbols so that
# CreateFile(), _tfopen(), etc. map to versions that take wchar_t*, breaking the
diff --git a/adb/bugreport.cpp b/adb/bugreport.cpp
index da2cfa2..d0cc072 100644
--- a/adb/bugreport.cpp
+++ b/adb/bugreport.cpp
@@ -48,7 +48,7 @@
show_progress_(show_progress),
status_(0),
line_(),
- last_progress_(0) {
+ last_progress_percentage_(0) {
SetLineMessage("generating");
}
@@ -147,13 +147,14 @@
size_t idx1 = line.rfind(BUGZ_PROGRESS_PREFIX) + strlen(BUGZ_PROGRESS_PREFIX);
size_t idx2 = line.rfind(BUGZ_PROGRESS_SEPARATOR);
int progress = std::stoi(line.substr(idx1, (idx2 - idx1)));
- if (progress <= last_progress_) {
+ int total = std::stoi(line.substr(idx2 + 1));
+ int progress_percentage = (progress * 100 / total);
+ if (progress_percentage <= last_progress_percentage_) {
// Ignore.
return;
}
- last_progress_ = progress;
- int total = std::stoi(line.substr(idx2 + 1));
- br_->UpdateProgress(line_message_, progress, total);
+ last_progress_percentage_ = progress_percentage;
+ br_->UpdateProgress(line_message_, progress_percentage);
} else {
invalid_lines_.push_back(line);
}
@@ -189,7 +190,7 @@
// Last displayed progress.
// Since dumpstate progress can recede, only forward progress should be displayed
- int last_progress_;
+ int last_progress_percentage_;
DISALLOW_COPY_AND_ASSIGN(BugreportStandardStreamsCallback);
};
@@ -267,8 +268,7 @@
return SendShellCommand(transport_type, serial, bugz_command, false, &bugz_callback);
}
-void Bugreport::UpdateProgress(const std::string& message, int progress, int total) {
- int progress_percentage = (progress * 100 / total);
+void Bugreport::UpdateProgress(const std::string& message, int progress_percentage) {
line_printer_.Print(
android::base::StringPrintf("[%3d%%] %s", progress_percentage, message.c_str()),
LinePrinter::INFO);
diff --git a/adb/bugreport.h b/adb/bugreport.h
index ee99cbc..d9a4468 100644
--- a/adb/bugreport.h
+++ b/adb/bugreport.h
@@ -43,7 +43,7 @@
const char* name);
private:
- virtual void UpdateProgress(const std::string& file_name, int progress, int total);
+ virtual void UpdateProgress(const std::string& file_name, int progress_percentage);
LinePrinter line_printer_;
DISALLOW_COPY_AND_ASSIGN(Bugreport);
};
diff --git a/adb/bugreport_test.cpp b/adb/bugreport_test.cpp
index b500c49..2b368d7 100644
--- a/adb/bugreport_test.cpp
+++ b/adb/bugreport_test.cpp
@@ -123,7 +123,7 @@
bool disable_shell_protocol, StandardStreamsCallbackInterface* callback));
MOCK_METHOD4(DoSyncPull, bool(const std::vector<const char*>& srcs, const char* dst,
bool copy_attrs, const char* name));
- MOCK_METHOD3(UpdateProgress, void(const std::string&, int, int));
+ MOCK_METHOD2(UpdateProgress, void(const std::string&, int));
};
class BugreportTest : public ::testing::Test {
@@ -142,8 +142,8 @@
WithArg<4>(ReturnCallbackDone(0))));
}
- void ExpectProgress(int progress, int total, const std::string& file = "file.zip") {
- EXPECT_CALL(br_, UpdateProgress(StrEq("generating " + file), progress, total));
+ void ExpectProgress(int progress_percentage, const std::string& file = "file.zip") {
+ EXPECT_CALL(br_, UpdateProgress(StrEq("generating " + file), progress_percentage));
}
BugreportMock br_;
@@ -200,7 +200,7 @@
ExpectBugreportzVersion("1.1");
std::string dest_file =
android::base::StringPrintf("%s%cda_bugreport.zip", cwd_.c_str(), OS_PATH_SEPARATOR);
- ExpectProgress(50, 100, "da_bugreport.zip");
+ ExpectProgress(50, "da_bugreport.zip");
EXPECT_CALL(br_, SendShellCommand(kTransportLocal, "HannibalLecter", "bugreportz -p", false, _))
.WillOnce(DoAll(WithArg<4>(WriteOnStdout("BEGIN:/device/da_bugreport.zip\n")),
WithArg<4>(WriteOnStdout("PROGRESS:50/100\n")),
@@ -247,10 +247,10 @@
// Tests 'adb bugreport file.zip' when it succeeds and displays progress.
TEST_F(BugreportTest, OkProgress) {
ExpectBugreportzVersion("1.1");
- ExpectProgress(1, 100);
- ExpectProgress(10, 100);
- ExpectProgress(50, 100);
- ExpectProgress(99, 100);
+ ExpectProgress(1);
+ ExpectProgress(10);
+ ExpectProgress(50);
+ ExpectProgress(99);
// clang-format off
EXPECT_CALL(br_, SendShellCommand(kTransportLocal, "HannibalLecter", "bugreportz -p", false, _))
// NOTE: DoAll accepts at most 10 arguments, and we're almost reached that limit...
@@ -283,21 +283,23 @@
// Tests 'adb bugreport file.zip' when it succeeds and displays progress, even if progress recedes.
TEST_F(BugreportTest, OkProgressAlwaysForward) {
ExpectBugreportzVersion("1.1");
- ExpectProgress(1, 100);
- ExpectProgress(50, 100);
- ExpectProgress(75, 100);
+ ExpectProgress(1);
+ ExpectProgress(50);
+ ExpectProgress(75);
// clang-format off
EXPECT_CALL(br_, SendShellCommand(kTransportLocal, "HannibalLecter", "bugreportz -p", false, _))
// NOTE: DoAll accepts at most 10 arguments, and we're almost reached that limit...
.WillOnce(DoAll(
WithArg<4>(WriteOnStdout("BEGIN:/device/bugreport.zip\n")),
- WithArg<4>(WriteOnStdout("PROGRESS:1/100\n")),
- WithArg<4>(WriteOnStdout("PROGRESS:50/100\n")),
- // 25 should be ignored becaused it receded.
- WithArg<4>(WriteOnStdout("PROGRESS:25/100\n")),
- WithArg<4>(WriteOnStdout("PROGRESS:75/100\n")),
- // 75 should be ignored becaused it didn't change.
- WithArg<4>(WriteOnStdout("PROGRESS:75/100\n")),
+ WithArg<4>(WriteOnStdout("PROGRESS:1/100\n")), // 1%
+ WithArg<4>(WriteOnStdout("PROGRESS:50/100\n")), // 50%
+ // 25% should be ignored becaused it receded.
+ WithArg<4>(WriteOnStdout("PROGRESS:25/100\n")), // 25%
+ WithArg<4>(WriteOnStdout("PROGRESS:75/100\n")), // 75%
+ // 75% should be ignored becaused it didn't change.
+ WithArg<4>(WriteOnStdout("PROGRESS:75/100\n")), // 75%
+ // Try a receeding percentage with a different max progress
+ WithArg<4>(WriteOnStdout("PROGRESS:700/1000\n")), // 70%
WithArg<4>(WriteOnStdout("OK:/device/bugreport.zip")),
WithArg<4>(ReturnCallbackDone())));
// clang-format on
diff --git a/adb/client/usb_dispatch.cpp b/adb/client/usb_dispatch.cpp
index bfc8e16..710a3ce 100644
--- a/adb/client/usb_dispatch.cpp
+++ b/adb/client/usb_dispatch.cpp
@@ -48,3 +48,9 @@
should_use_libusb() ? libusb::usb_kick(reinterpret_cast<libusb::usb_handle*>(h))
: native::usb_kick(reinterpret_cast<native::usb_handle*>(h));
}
+
+size_t usb_get_max_packet_size(usb_handle* h) {
+ return should_use_libusb()
+ ? libusb::usb_get_max_packet_size(reinterpret_cast<libusb::usb_handle*>(h))
+ : native::usb_get_max_packet_size(reinterpret_cast<native::usb_handle*>(h));
+}
diff --git a/adb/client/usb_libusb.cpp b/adb/client/usb_libusb.cpp
index fec4742..d39884a 100644
--- a/adb/client/usb_libusb.cpp
+++ b/adb/client/usb_libusb.cpp
@@ -91,7 +91,7 @@
struct usb_handle : public ::usb_handle {
usb_handle(const std::string& device_address, const std::string& serial,
unique_device_handle&& device_handle, uint8_t interface, uint8_t bulk_in,
- uint8_t bulk_out, size_t zero_mask)
+ uint8_t bulk_out, size_t zero_mask, size_t max_packet_size)
: device_address(device_address),
serial(serial),
closing(false),
@@ -100,7 +100,8 @@
write("write", zero_mask, true),
interface(interface),
bulk_in(bulk_in),
- bulk_out(bulk_out) {}
+ bulk_out(bulk_out),
+ max_packet_size(max_packet_size) {}
~usb_handle() {
Close();
@@ -143,6 +144,8 @@
uint8_t interface;
uint8_t bulk_in;
uint8_t bulk_out;
+
+ size_t max_packet_size;
};
static auto& usb_handles = *new std::unordered_map<std::string, std::unique_ptr<usb_handle>>();
@@ -206,6 +209,7 @@
size_t interface_num;
uint16_t zero_mask;
uint8_t bulk_in = 0, bulk_out = 0;
+ size_t packet_size = 0;
bool found_adb = false;
for (interface_num = 0; interface_num < config->bNumInterfaces; ++interface_num) {
@@ -252,6 +256,14 @@
found_in = true;
bulk_in = endpoint_addr;
}
+
+ size_t endpoint_packet_size = endpoint_desc.wMaxPacketSize;
+ CHECK(endpoint_packet_size != 0);
+ if (packet_size == 0) {
+ packet_size = endpoint_packet_size;
+ } else {
+ CHECK(packet_size == endpoint_packet_size);
+ }
}
if (found_in && found_out) {
@@ -280,7 +292,7 @@
}
libusb_device_handle* handle_raw;
- rc = libusb_open(list[i], &handle_raw);
+ rc = libusb_open(device, &handle_raw);
if (rc != 0) {
LOG(WARNING) << "failed to open usb device at " << device_address << ": "
<< libusb_error_name(rc);
@@ -324,9 +336,9 @@
}
}
- auto result =
- std::make_unique<usb_handle>(device_address, device_serial, std::move(handle),
- interface_num, bulk_in, bulk_out, zero_mask);
+ auto result = std::make_unique<usb_handle>(device_address, device_serial,
+ std::move(handle), interface_num, bulk_in,
+ bulk_out, zero_mask, packet_size);
usb_handle* usb_handle_raw = result.get();
{
@@ -507,4 +519,10 @@
void usb_kick(usb_handle* h) {
h->Close();
}
+
+size_t usb_get_max_packet_size(usb_handle* h) {
+ CHECK(h->max_packet_size != 0);
+ return h->max_packet_size;
+}
+
} // namespace libusb
diff --git a/adb/client/usb_linux.cpp b/adb/client/usb_linux.cpp
index 6efed27..f9ba7cb 100644
--- a/adb/client/usb_linux.cpp
+++ b/adb/client/usb_linux.cpp
@@ -65,6 +65,7 @@
unsigned char ep_in;
unsigned char ep_out;
+ size_t max_packet_size;
unsigned zero_mask;
unsigned writeable = 1;
@@ -120,9 +121,9 @@
}
static void find_usb_device(const std::string& base,
- void (*register_device_callback)
- (const char*, const char*, unsigned char, unsigned char, int, int, unsigned))
-{
+ void (*register_device_callback)(const char*, const char*,
+ unsigned char, unsigned char, int, int,
+ unsigned, size_t)) {
std::unique_ptr<DIR, int(*)(DIR*)> bus_dir(opendir(base.c_str()), closedir);
if (!bus_dir) return;
@@ -144,6 +145,7 @@
struct usb_interface_descriptor* interface;
struct usb_endpoint_descriptor *ep1, *ep2;
unsigned zero_mask = 0;
+ size_t max_packet_size = 0;
unsigned vid, pid;
if (contains_non_digit(de->d_name)) continue;
@@ -251,7 +253,8 @@
continue;
}
/* aproto 01 needs 0 termination */
- if(interface->bInterfaceProtocol == 0x01) {
+ if (interface->bInterfaceProtocol == 0x01) {
+ max_packet_size = ep1->wMaxPacketSize;
zero_mask = ep1->wMaxPacketSize - 1;
}
@@ -281,9 +284,9 @@
}
}
- register_device_callback(dev_name.c_str(), devpath,
- local_ep_in, local_ep_out,
- interface->bInterfaceNumber, device->iSerialNumber, zero_mask);
+ register_device_callback(dev_name.c_str(), devpath, local_ep_in,
+ local_ep_out, interface->bInterfaceNumber,
+ device->iSerialNumber, zero_mask, max_packet_size);
break;
}
} else {
@@ -497,10 +500,13 @@
return 0;
}
-static void register_device(const char* dev_name, const char* dev_path,
- unsigned char ep_in, unsigned char ep_out,
- int interface, int serial_index,
- unsigned zero_mask) {
+size_t usb_get_max_packet_size(usb_handle* h) {
+ return h->max_packet_size;
+}
+
+static void register_device(const char* dev_name, const char* dev_path, unsigned char ep_in,
+ unsigned char ep_out, int interface, int serial_index,
+ unsigned zero_mask, size_t max_packet_size) {
// Since Linux will not reassign the device ID (and dev_name) as long as the
// device is open, we can add to the list here once we open it and remove
// from the list when we're finally closed and everything will work out
@@ -523,6 +529,7 @@
usb->ep_in = ep_in;
usb->ep_out = ep_out;
usb->zero_mask = zero_mask;
+ usb->max_packet_size = max_packet_size;
// Initialize mark so we don't get garbage collected after the device scan.
usb->mark = true;
diff --git a/adb/client/usb_osx.cpp b/adb/client/usb_osx.cpp
index fcd0bc0..e4a543b 100644
--- a/adb/client/usb_osx.cpp
+++ b/adb/client/usb_osx.cpp
@@ -51,15 +51,21 @@
UInt8 bulkOut;
IOUSBInterfaceInterface190** interface;
unsigned int zero_mask;
+ size_t max_packet_size;
// For garbage collecting disconnected devices.
bool mark;
std::string devpath;
std::atomic<bool> dead;
- usb_handle() : bulkIn(0), bulkOut(0), interface(nullptr),
- zero_mask(0), mark(false), dead(false) {
- }
+ usb_handle()
+ : bulkIn(0),
+ bulkOut(0),
+ interface(nullptr),
+ zero_mask(0),
+ max_packet_size(0),
+ mark(false),
+ dead(false) {}
};
static std::atomic<bool> usb_inited_flag;
@@ -390,6 +396,7 @@
}
handle->zero_mask = maxPacketSize - 1;
+ handle->max_packet_size = maxPacketSize;
}
handle->interface = interface;
@@ -558,4 +565,9 @@
std::lock_guard<std::mutex> lock_guard(g_usb_handles_mutex);
usb_kick_locked(handle);
}
+
+size_t usb_get_max_packet_size(usb_handle* handle) {
+ return handle->max_packet_size;
+}
+
} // namespace native
diff --git a/adb/client/usb_windows.cpp b/adb/client/usb_windows.cpp
index ee7f802..ec55b0e 100644
--- a/adb/client/usb_windows.cpp
+++ b/adb/client/usb_windows.cpp
@@ -65,6 +65,9 @@
/// Interface name
wchar_t* interface_name;
+ /// Maximum packet size.
+ unsigned max_packet_size;
+
/// Mask for determining when to use zero length packets
unsigned zero_mask;
};
@@ -522,6 +525,10 @@
return 0;
}
+size_t usb_get_max_packet_size(usb_handle* handle) {
+ return handle->max_packet_size;
+}
+
int recognized_device(usb_handle* handle) {
if (NULL == handle)
return 0;
@@ -557,6 +564,7 @@
AdbEndpointInformation endpoint_info;
// assuming zero is a valid bulk endpoint ID
if (AdbGetEndpointInformation(handle->adb_interface, 0, &endpoint_info)) {
+ handle->max_packet_size = endpoint_info.max_packet_size;
handle->zero_mask = endpoint_info.max_packet_size - 1;
D("device zero_mask: 0x%x", handle->zero_mask);
} else {
diff --git a/adb/commandline.cpp b/adb/commandline.cpp
index b8f790d..a9b1540 100644
--- a/adb/commandline.cpp
+++ b/adb/commandline.cpp
@@ -761,55 +761,46 @@
return RemoteShell(use_shell_protocol, shell_type_arg, escape_char, command);
}
-static int adb_download_buffer(const char* service, const char* filename) {
- std::string content;
- if (!android::base::ReadFileToString(filename, &content)) {
- fprintf(stderr, "error: couldn't read %s: %s\n", filename, strerror(errno));
- return -1;
- }
-
- const uint8_t* data = reinterpret_cast<const uint8_t*>(content.data());
- unsigned sz = content.size();
-
+static int adb_sideload_legacy(const char* filename, int in_fd, int size) {
std::string error;
- int fd = adb_connect(android::base::StringPrintf("%s:%d", service, sz), &error);
- if (fd < 0) {
- fprintf(stderr,"error: %s\n", error.c_str());
+ int out_fd = adb_connect(android::base::StringPrintf("sideload:%d", size), &error);
+ if (out_fd < 0) {
+ fprintf(stderr, "adb: pre-KitKat sideload connection failed: %s\n", error.c_str());
return -1;
}
int opt = CHUNK_SIZE;
- opt = adb_setsockopt(fd, SOL_SOCKET, SO_SNDBUF, (const void *) &opt, sizeof(opt));
+ opt = adb_setsockopt(out_fd, SOL_SOCKET, SO_SNDBUF, &opt, sizeof(opt));
- unsigned total = sz;
- const uint8_t* ptr = reinterpret_cast<const uint8_t*>(data);
-
- const char* x = strrchr(service, ':');
- if (x) service = x + 1;
-
- while (sz > 0) {
- unsigned xfer = (sz > CHUNK_SIZE) ? CHUNK_SIZE : sz;
- if (!WriteFdExactly(fd, ptr, xfer)) {
- std::string error;
- adb_status(fd, &error);
- fprintf(stderr,"* failed to write data '%s' *\n", error.c_str());
- adb_close(fd);
+ char buf[CHUNK_SIZE];
+ int total = size;
+ while (size > 0) {
+ unsigned xfer = (size > CHUNK_SIZE) ? CHUNK_SIZE : size;
+ if (!ReadFdExactly(in_fd, buf, xfer)) {
+ fprintf(stderr, "adb: failed to read data from %s: %s\n", filename, strerror(errno));
+ adb_close(out_fd);
return -1;
}
- sz -= xfer;
- ptr += xfer;
- printf("sending: '%s' %4d%% \r", filename, (int)(100LL - ((100LL * sz) / (total))));
+ if (!WriteFdExactly(out_fd, buf, xfer)) {
+ std::string error;
+ adb_status(out_fd, &error);
+ fprintf(stderr, "adb: failed to write data: %s\n", error.c_str());
+ adb_close(out_fd);
+ return -1;
+ }
+ size -= xfer;
+ printf("sending: '%s' %4d%% \r", filename, (int)(100LL - ((100LL * size) / (total))));
fflush(stdout);
}
printf("\n");
- if (!adb_status(fd, &error)) {
- fprintf(stderr,"* error response '%s' *\n", error.c_str());
- adb_close(fd);
+ if (!adb_status(out_fd, &error)) {
+ fprintf(stderr, "adb: error response: %s\n", error.c_str());
+ adb_close(out_fd);
return -1;
}
- adb_close(fd);
+ adb_close(out_fd);
return 0;
}
@@ -836,22 +827,17 @@
*/
static int adb_sideload_host(const char* filename) {
// TODO: use a LinePrinter instead...
- fprintf(stdout, "opening '%s'...\n", filename);
- fflush(stdout);
-
struct stat sb;
if (stat(filename, &sb) == -1) {
- fprintf(stderr, "failed to stat file %s: %s\n", filename, strerror(errno));
+ fprintf(stderr, "adb: failed to stat file %s: %s\n", filename, strerror(errno));
return -1;
}
unique_fd package_fd(adb_open(filename, O_RDONLY));
if (package_fd == -1) {
- fprintf(stderr, "failed to open file %s: %s\n", filename, strerror(errno));
+ fprintf(stderr, "adb: failed to open file %s: %s\n", filename, strerror(errno));
return -1;
}
- fprintf(stdout, "connecting...\n");
- fflush(stdout);
std::string service = android::base::StringPrintf(
"sideload-host:%d:%d", static_cast<int>(sb.st_size), SIDELOAD_HOST_BLOCK_SIZE);
std::string error;
@@ -859,8 +845,9 @@
if (device_fd < 0) {
// Try falling back to the older (<= K) sideload method. Maybe this
// is an older device that doesn't support sideload-host.
- fprintf(stderr, "falling back to older sideload method...\n");
- return adb_download_buffer("sideload", filename);
+ fprintf(stderr, "adb: sideload connection failed: %s\n", error.c_str());
+ fprintf(stderr, "adb: trying pre-KitKat sideload method...\n");
+ return adb_sideload_legacy(filename, package_fd, static_cast<int>(sb.st_size));
}
int opt = SIDELOAD_HOST_BLOCK_SIZE;
@@ -872,7 +859,7 @@
int last_percent = -1;
while (true) {
if (!ReadFdExactly(device_fd, buf, 8)) {
- fprintf(stderr, "* failed to read command: %s\n", strerror(errno));
+ fprintf(stderr, "adb: failed to read command: %s\n", strerror(errno));
return -1;
}
buf[8] = '\0';
@@ -888,7 +875,7 @@
size_t offset = block * SIDELOAD_HOST_BLOCK_SIZE;
if (offset >= static_cast<size_t>(sb.st_size)) {
- fprintf(stderr, "* attempt to read block %d past end\n", block);
+ fprintf(stderr, "adb: failed to read block %d past end\n", block);
return -1;
}
@@ -898,17 +885,17 @@
}
if (adb_lseek(package_fd, offset, SEEK_SET) != static_cast<int>(offset)) {
- fprintf(stderr, "* failed to seek to package block: %s\n", strerror(errno));
+ fprintf(stderr, "adb: failed to seek to package block: %s\n", strerror(errno));
return -1;
}
if (!ReadFdExactly(package_fd, buf, to_write)) {
- fprintf(stderr, "* failed to read package block: %s\n", strerror(errno));
+ fprintf(stderr, "adb: failed to read package block: %s\n", strerror(errno));
return -1;
}
if (!WriteFdExactly(device_fd, buf, to_write)) {
adb_status(device_fd, &error);
- fprintf(stderr,"* failed to write data '%s' *\n", error.c_str());
+ fprintf(stderr, "adb: failed to write data '%s' *\n", error.c_str());
return -1;
}
xfer += to_write;
diff --git a/adb/sysdeps_test.cpp b/adb/sysdeps_test.cpp
index edb0fb3..fd19882 100644
--- a/adb/sysdeps_test.cpp
+++ b/adb/sysdeps_test.cpp
@@ -201,55 +201,6 @@
}
}
-TEST(sysdeps_mutex, mutex_smoke) {
- static std::atomic<bool> finished(false);
- static std::mutex &m = *new std::mutex();
- m.lock();
- ASSERT_FALSE(m.try_lock());
- std::thread thread([]() {
- ASSERT_FALSE(m.try_lock());
- m.lock();
- finished.store(true);
- std::this_thread::sleep_for(200ms);
- m.unlock();
- });
-
- ASSERT_FALSE(finished.load());
- std::this_thread::sleep_for(100ms);
- ASSERT_FALSE(finished.load());
- m.unlock();
- std::this_thread::sleep_for(100ms);
- m.lock();
- ASSERT_TRUE(finished.load());
- m.unlock();
-
- thread.join();
-}
-
-TEST(sysdeps_mutex, recursive_mutex_smoke) {
- static std::recursive_mutex &m = *new std::recursive_mutex();
-
- m.lock();
- ASSERT_TRUE(m.try_lock());
- m.unlock();
-
- std::thread thread([]() {
- ASSERT_FALSE(m.try_lock());
- m.lock();
- std::this_thread::sleep_for(500ms);
- m.unlock();
- });
-
- std::this_thread::sleep_for(100ms);
- m.unlock();
- std::this_thread::sleep_for(100ms);
- ASSERT_FALSE(m.try_lock());
- m.lock();
- m.unlock();
-
- thread.join();
-}
-
TEST(sysdeps_condition_variable, smoke) {
static std::mutex &m = *new std::mutex;
static std::condition_variable &cond = *new std::condition_variable;
diff --git a/adb/test_device.py b/adb/test_device.py
index a30972e..e44cc83 100644
--- a/adb/test_device.py
+++ b/adb/test_device.py
@@ -1259,6 +1259,26 @@
self.assertEqual(self._get_device_state(serialno), 'device')
+ def test_packet_size_regression(self):
+ """Test for http://b/37783561
+
+ Receiving packets of a length divisible by 512 but not 1024 resulted in
+ the adb client waiting indefinitely for more input.
+ """
+ # The values that trigger things are 507 (512 - 5 bytes from shell protocol) + 1024*n
+ # Probe some surrounding values as well, for the hell of it.
+ for length in [506, 507, 508, 1018, 1019, 1020, 1530, 1531, 1532]:
+ cmd = ['dd', 'if=/dev/zero', 'bs={}'.format(length), 'count=1', '2>/dev/null;'
+ 'echo', 'foo']
+ rc, stdout, _ = self.device.shell_nocheck(cmd)
+
+ self.assertEqual(0, rc)
+
+ # Output should be '\0' * length, followed by "foo\n"
+ self.assertEqual(length, len(stdout) - 4)
+ self.assertEqual(stdout, "\0" * length + "foo\n")
+
+
def main():
random.seed(0)
if len(adb.get_devices()) > 0:
diff --git a/adb/transport_usb.cpp b/adb/transport_usb.cpp
index ce419b8..885d723 100644
--- a/adb/transport_usb.cpp
+++ b/adb/transport_usb.cpp
@@ -27,57 +27,43 @@
#if ADB_HOST
-static constexpr size_t MAX_USB_BULK_PACKET_SIZE = 1024u;
-
-// Call usb_read using a buffer having a multiple of MAX_USB_BULK_PACKET_SIZE bytes
+// Call usb_read using a buffer having a multiple of usb_get_max_packet_size() bytes
// to avoid overflow. See http://libusb.sourceforge.net/api-1.0/packetoverflow.html.
static int UsbReadMessage(usb_handle* h, amessage* msg) {
D("UsbReadMessage");
- char buffer[MAX_USB_BULK_PACKET_SIZE];
- int n = usb_read(h, buffer, sizeof(buffer));
- if (n == sizeof(*msg)) {
- memcpy(msg, buffer, sizeof(*msg));
+
+ size_t usb_packet_size = usb_get_max_packet_size(h);
+ CHECK(usb_packet_size >= sizeof(*msg));
+ CHECK(usb_packet_size < 4096);
+
+ char buffer[4096];
+ int n = usb_read(h, buffer, usb_packet_size);
+ if (n != sizeof(*msg)) {
+ D("usb_read returned unexpected length %d (expected %zu)", n, sizeof(*msg));
+ return -1;
}
+ memcpy(msg, buffer, sizeof(*msg));
return n;
}
-// Call usb_read using a buffer having a multiple of MAX_USB_BULK_PACKET_SIZE bytes
+// Call usb_read using a buffer having a multiple of usb_get_max_packet_size() bytes
// to avoid overflow. See http://libusb.sourceforge.net/api-1.0/packetoverflow.html.
static int UsbReadPayload(usb_handle* h, apacket* p) {
- D("UsbReadPayload");
- size_t need_size = p->msg.data_length;
- size_t data_pos = 0u;
- while (need_size > 0u) {
- int n = 0;
- if (data_pos + MAX_USB_BULK_PACKET_SIZE <= sizeof(p->data)) {
- // Read directly to p->data.
- size_t rem_size = need_size % MAX_USB_BULK_PACKET_SIZE;
- size_t direct_read_size = need_size - rem_size;
- if (rem_size &&
- data_pos + direct_read_size + MAX_USB_BULK_PACKET_SIZE <= sizeof(p->data)) {
- direct_read_size += MAX_USB_BULK_PACKET_SIZE;
- }
- n = usb_read(h, &p->data[data_pos], direct_read_size);
- if (n < 0) {
- D("usb_read(size %zu) failed", direct_read_size);
- return n;
- }
- } else {
- // Read indirectly using a buffer.
- char buffer[MAX_USB_BULK_PACKET_SIZE];
- n = usb_read(h, buffer, sizeof(buffer));
- if (n < 0) {
- D("usb_read(size %zu) failed", sizeof(buffer));
- return -1;
- }
- size_t copy_size = std::min(static_cast<size_t>(n), need_size);
- D("usb read %d bytes, need %zu bytes, copy %zu bytes", n, need_size, copy_size);
- memcpy(&p->data[data_pos], buffer, copy_size);
- }
- data_pos += n;
- need_size -= std::min(static_cast<size_t>(n), need_size);
+ D("UsbReadPayload(%d)", p->msg.data_length);
+
+ size_t usb_packet_size = usb_get_max_packet_size(h);
+ CHECK(sizeof(p->data) % usb_packet_size == 0);
+
+ // Round the data length up to the nearest packet size boundary.
+ // The device won't send a zero packet for packet size aligned payloads,
+ // so don't read any more packets than needed.
+ size_t len = p->msg.data_length;
+ size_t rem_size = len % usb_packet_size;
+ if (rem_size) {
+ len += usb_packet_size - rem_size;
}
- return static_cast<int>(data_pos);
+ CHECK(len <= sizeof(p->data));
+ return usb_read(h, &p->data, len);
}
static int remote_read(apacket* p, atransport* t) {
diff --git a/adb/usb.h b/adb/usb.h
index ba70de4..e867ec8 100644
--- a/adb/usb.h
+++ b/adb/usb.h
@@ -16,6 +16,8 @@
#pragma once
+#include <sys/types.h>
+
// USB host/client interface.
#define ADB_USB_INTERFACE(handle_ref_type) \
@@ -23,7 +25,8 @@
int usb_write(handle_ref_type h, const void* data, int len); \
int usb_read(handle_ref_type h, void* data, int len); \
int usb_close(handle_ref_type h); \
- void usb_kick(handle_ref_type h)
+ void usb_kick(handle_ref_type h); \
+ size_t usb_get_max_packet_size(handle_ref_type)
#if defined(_WIN32) || !ADB_HOST
// Windows and the daemon have a single implementation.
diff --git a/debuggerd/Android.bp b/debuggerd/Android.bp
index 4783d6e..79d5c08 100644
--- a/debuggerd/Android.bp
+++ b/debuggerd/Android.bp
@@ -9,10 +9,6 @@
"-Os",
],
- // util.cpp gets async signal safe logging via libc_logging,
- // which defines its interface in bionic private headers.
- include_dirs: ["bionic/libc"],
-
local_include_dirs: ["include"],
}
@@ -26,7 +22,7 @@
],
whole_static_libs: [
- "libc_logging",
+ "libasync_safe",
"libcutils",
"libbase",
],
@@ -39,7 +35,7 @@
srcs: ["handler/debuggerd_handler.cpp"],
whole_static_libs: [
- "libc_logging",
+ "libasync_safe",
"libdebuggerd",
],
@@ -70,6 +66,7 @@
whole_static_libs: [
"libdebuggerd_handler_core",
"libtombstoned_client",
+ "libasync_safe",
"libbase",
"libdebuggerd",
"libbacktrace",
@@ -166,6 +163,7 @@
"tombstoned_client.cpp",
"util.cpp"
],
+ static_libs: ["libasync_safe"],
},
},
@@ -178,7 +176,6 @@
static_libs: [
"libdebuggerd",
- "libc_logging",
],
local_include_dirs: [
diff --git a/debuggerd/handler/debuggerd_fallback.cpp b/debuggerd/handler/debuggerd_fallback.cpp
index 5c6c59c..47c98d1 100644
--- a/debuggerd/handler/debuggerd_fallback.cpp
+++ b/debuggerd/handler/debuggerd_fallback.cpp
@@ -39,6 +39,7 @@
#include <android-base/file.h>
#include <android-base/unique_fd.h>
+#include <async_safe/log.h>
#include "debuggerd/handler.h"
#include "debuggerd/tombstoned.h"
@@ -47,8 +48,6 @@
#include "backtrace.h"
#include "tombstone.h"
-#include "private/libc_logging.h"
-
using android::base::unique_fd;
extern "C" void __linker_enable_fallback_allocator();
@@ -81,7 +80,7 @@
DIR* dir = opendir(buf);
if (!dir) {
- __libc_format_log(ANDROID_LOG_ERROR, "libc", "failed to open %s: %s", buf, strerror(errno));
+ async_safe_format_log(ANDROID_LOG_ERROR, "libc", "failed to open %s: %s", buf, strerror(errno));
return;
}
@@ -145,7 +144,8 @@
static pthread_mutex_t trace_mutex = PTHREAD_MUTEX_INITIALIZER;
int ret = pthread_mutex_trylock(&trace_mutex);
if (ret != 0) {
- __libc_format_log(ANDROID_LOG_INFO, "libc", "pthread_mutex_try_lock failed: %s", strerror(ret));
+ async_safe_format_log(ANDROID_LOG_INFO, "libc", "pthread_mutex_try_lock failed: %s",
+ strerror(ret));
return;
}
@@ -167,7 +167,8 @@
// receiving our signal.
unique_fd pipe_read, pipe_write;
if (!Pipe(&pipe_read, &pipe_write)) {
- __libc_format_log(ANDROID_LOG_ERROR, "libc", "failed to create pipe: %s", strerror(errno));
+ async_safe_format_log(ANDROID_LOG_ERROR, "libc", "failed to create pipe: %s",
+ strerror(errno));
return false;
}
@@ -180,8 +181,8 @@
siginfo.si_uid = getuid();
if (syscall(__NR_rt_tgsigqueueinfo, getpid(), tid, DEBUGGER_SIGNAL, &siginfo) != 0) {
- __libc_format_log(ANDROID_LOG_ERROR, "libc", "failed to send trace signal to %d: %s", tid,
- strerror(errno));
+ async_safe_format_log(ANDROID_LOG_ERROR, "libc", "failed to send trace signal to %d: %s",
+ tid, strerror(errno));
return false;
}
@@ -209,7 +210,7 @@
static pthread_mutex_t crash_mutex = PTHREAD_MUTEX_INITIALIZER;
int ret = pthread_mutex_lock(&crash_mutex);
if (ret != 0) {
- __libc_format_log(ANDROID_LOG_INFO, "libc", "pthread_mutex_lock failed: %s", strerror(ret));
+ async_safe_format_log(ANDROID_LOG_INFO, "libc", "pthread_mutex_lock failed: %s", strerror(ret));
return;
}
diff --git a/debuggerd/handler/debuggerd_handler.cpp b/debuggerd/handler/debuggerd_handler.cpp
index b70554f..6e3e6ac 100644
--- a/debuggerd/handler/debuggerd_handler.cpp
+++ b/debuggerd/handler/debuggerd_handler.cpp
@@ -48,8 +48,7 @@
#include <sys/wait.h>
#include <unistd.h>
-#include "private/bionic_futex.h"
-#include "private/libc_logging.h"
+#include <async_safe/log.h>
// see man(2) prctl, specifically the section about PR_GET_NAME
#define MAX_TASK_NAME_LEN (16)
@@ -62,6 +61,10 @@
#define CRASH_DUMP_PATH "/system/bin/" CRASH_DUMP_NAME
+static inline void futex_wait(volatile void* ftx, int value) {
+ syscall(__NR_futex, ftx, FUTEX_WAIT, value, nullptr, nullptr, 0);
+}
+
class ErrnoRestorer {
public:
ErrnoRestorer() : saved_errno_(errno) {
@@ -82,11 +85,12 @@
// Mutex to ensure only one crashing thread dumps itself.
static pthread_mutex_t crash_mutex = PTHREAD_MUTEX_INITIALIZER;
-// Don't use __libc_fatal because it exits via abort, which might put us back into a signal handler.
+// Don't use async_safe_fatal because it exits via abort, which might put us back into
+// a signal handler.
static void __noreturn __printflike(1, 2) fatal(const char* fmt, ...) {
va_list args;
va_start(args, fmt);
- __libc_format_log_va_list(ANDROID_LOG_FATAL, "libc", fmt, args);
+ async_safe_format_log_va_list(ANDROID_LOG_FATAL, "libc", fmt, args);
_exit(1);
}
@@ -96,7 +100,7 @@
va_start(args, fmt);
char buf[4096];
- __libc_format_buffer_va_list(buf, sizeof(buf), fmt, args);
+ async_safe_format_buffer_va_list(buf, sizeof(buf), fmt, args);
fatal("%s: %s", buf, strerror(err));
}
@@ -120,8 +124,8 @@
}
if (signum == DEBUGGER_SIGNAL) {
- __libc_format_log(ANDROID_LOG_INFO, "libc", "Requested dump for tid %d (%s)", gettid(),
- thread_name);
+ async_safe_format_log(ANDROID_LOG_INFO, "libc", "Requested dump for tid %d (%s)", gettid(),
+ thread_name);
return;
}
@@ -166,14 +170,14 @@
char addr_desc[32]; // ", fault addr 0x1234"
addr_desc[0] = code_desc[0] = 0;
if (info != nullptr) {
- __libc_format_buffer(code_desc, sizeof(code_desc), ", code %d", info->si_code);
+ async_safe_format_buffer(code_desc, sizeof(code_desc), ", code %d", info->si_code);
if (has_address) {
- __libc_format_buffer(addr_desc, sizeof(addr_desc), ", fault addr %p", info->si_addr);
+ async_safe_format_buffer(addr_desc, sizeof(addr_desc), ", fault addr %p", info->si_addr);
}
}
- __libc_format_log(ANDROID_LOG_FATAL, "libc", "Fatal signal %d (%s)%s%s in tid %d (%s)", signum,
- signal_name, code_desc, addr_desc, gettid(), thread_name);
+ async_safe_format_log(ANDROID_LOG_FATAL, "libc", "Fatal signal %d (%s)%s%s in tid %d (%s)",
+ signum, signal_name, code_desc, addr_desc, gettid(), thread_name);
}
/*
@@ -182,8 +186,8 @@
static bool have_siginfo(int signum) {
struct sigaction old_action;
if (sigaction(signum, nullptr, &old_action) < 0) {
- __libc_format_log(ANDROID_LOG_WARN, "libc", "Failed testing for SA_SIGINFO: %s",
- strerror(errno));
+ async_safe_format_log(ANDROID_LOG_WARN, "libc", "Failed testing for SA_SIGINFO: %s",
+ strerror(errno));
return false;
}
return (old_action.sa_flags & SA_SIGINFO) != 0;
@@ -207,7 +211,7 @@
capdata[1].inheritable = capdata[1].permitted;
if (capset(&capheader, &capdata[0]) == -1) {
- __libc_format_log(ANDROID_LOG_ERROR, "libc", "capset failed: %s", strerror(errno));
+ async_safe_format_log(ANDROID_LOG_ERROR, "libc", "capset failed: %s", strerror(errno));
}
}
@@ -217,8 +221,8 @@
for (unsigned long i = 0; i < 64; ++i) {
if (capmask & (1ULL << i)) {
if (prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_RAISE, i, 0, 0) != 0) {
- __libc_format_log(ANDROID_LOG_ERROR, "libc", "failed to raise ambient capability %lu: %s",
- i, strerror(errno));
+ async_safe_format_log(ANDROID_LOG_ERROR, "libc",
+ "failed to raise ambient capability %lu: %s", i, strerror(errno));
}
}
}
@@ -260,8 +264,8 @@
// Don't use fork(2) to avoid calling pthread_atfork handlers.
int forkpid = clone(nullptr, nullptr, 0, nullptr);
if (forkpid == -1) {
- __libc_format_log(ANDROID_LOG_FATAL, "libc", "failed to fork in debuggerd signal handler: %s",
- strerror(errno));
+ async_safe_format_log(ANDROID_LOG_FATAL, "libc",
+ "failed to fork in debuggerd signal handler: %s", strerror(errno));
} else if (forkpid == 0) {
TEMP_FAILURE_RETRY(dup2(pipefds[1], STDOUT_FILENO));
close(pipefds[0]);
@@ -271,8 +275,9 @@
char main_tid[10];
char pseudothread_tid[10];
- __libc_format_buffer(main_tid, sizeof(main_tid), "%d", thread_info->crashing_tid);
- __libc_format_buffer(pseudothread_tid, sizeof(pseudothread_tid), "%d", thread_info->pseudothread_tid);
+ async_safe_format_buffer(main_tid, sizeof(main_tid), "%d", thread_info->crashing_tid);
+ async_safe_format_buffer(pseudothread_tid, sizeof(pseudothread_tid), "%d",
+ thread_info->pseudothread_tid);
execl(CRASH_DUMP_PATH, CRASH_DUMP_NAME, main_tid, pseudothread_tid, nullptr);
@@ -282,15 +287,16 @@
char buf[4];
ssize_t rc = TEMP_FAILURE_RETRY(read(pipefds[0], &buf, sizeof(buf)));
if (rc == -1) {
- __libc_format_log(ANDROID_LOG_FATAL, "libc", "read of IPC pipe failed: %s", strerror(errno));
+ async_safe_format_log(ANDROID_LOG_FATAL, "libc", "read of IPC pipe failed: %s",
+ strerror(errno));
} else if (rc == 0) {
- __libc_format_log(ANDROID_LOG_FATAL, "libc", "crash_dump helper failed to exec");
+ async_safe_format_log(ANDROID_LOG_FATAL, "libc", "crash_dump helper failed to exec");
} else if (rc != 1) {
- __libc_format_log(ANDROID_LOG_FATAL, "libc",
- "read of IPC pipe returned unexpected value: %zd", rc);
+ async_safe_format_log(ANDROID_LOG_FATAL, "libc",
+ "read of IPC pipe returned unexpected value: %zd", rc);
} else {
if (buf[0] != '\1') {
- __libc_format_log(ANDROID_LOG_FATAL, "libc", "crash_dump helper reported failure");
+ async_safe_format_log(ANDROID_LOG_FATAL, "libc", "crash_dump helper reported failure");
} else {
thread_info->crash_dump_started = true;
}
@@ -300,10 +306,10 @@
// Don't leave a zombie child.
int status;
if (TEMP_FAILURE_RETRY(waitpid(forkpid, &status, 0)) == -1) {
- __libc_format_log(ANDROID_LOG_FATAL, "libc", "failed to wait for crash_dump helper: %s",
- strerror(errno));
+ async_safe_format_log(ANDROID_LOG_FATAL, "libc", "failed to wait for crash_dump helper: %s",
+ strerror(errno));
} else if (WIFSTOPPED(status) || WIFSIGNALED(status)) {
- __libc_format_log(ANDROID_LOG_FATAL, "libc", "crash_dump helper crashed or stopped");
+ async_safe_format_log(ANDROID_LOG_FATAL, "libc", "crash_dump helper crashed or stopped");
thread_info->crash_dump_started = false;
}
}
@@ -383,7 +389,7 @@
// Only allow one thread to handle a signal at a time.
int ret = pthread_mutex_lock(&crash_mutex);
if (ret != 0) {
- __libc_format_log(ANDROID_LOG_INFO, "libc", "pthread_mutex_lock failed: %s", strerror(ret));
+ async_safe_format_log(ANDROID_LOG_INFO, "libc", "pthread_mutex_lock failed: %s", strerror(ret));
return;
}
@@ -419,10 +425,10 @@
}
// Wait for the child to start...
- __futex_wait(&thread_info.pseudothread_tid, -1, nullptr);
+ futex_wait(&thread_info.pseudothread_tid, -1);
// and then wait for it to finish.
- __futex_wait(&thread_info.pseudothread_tid, child_pid, nullptr);
+ futex_wait(&thread_info.pseudothread_tid, child_pid);
// Restore PR_SET_DUMPABLE to its original value.
if (prctl(PR_SET_DUMPABLE, orig_dumpable) != 0) {
diff --git a/debuggerd/tombstoned_client.cpp b/debuggerd/tombstoned_client.cpp
index 03b4a20..4741fa6 100644
--- a/debuggerd/tombstoned_client.cpp
+++ b/debuggerd/tombstoned_client.cpp
@@ -22,11 +22,11 @@
#include <utility>
#include <android-base/unique_fd.h>
+#include <async_safe/log.h>
#include <cutils/sockets.h>
#include "debuggerd/protocol.h"
#include "debuggerd/util.h"
-#include "private/libc_logging.h"
using android::base::unique_fd;
@@ -34,8 +34,8 @@
unique_fd sockfd(socket_local_client(kTombstonedCrashSocketName,
ANDROID_SOCKET_NAMESPACE_RESERVED, SOCK_SEQPACKET));
if (sockfd == -1) {
- __libc_format_log(ANDROID_LOG_ERROR, "libc", "failed to connect to tombstoned: %s",
- strerror(errno));
+ async_safe_format_log(ANDROID_LOG_ERROR, "libc", "failed to connect to tombstoned: %s",
+ strerror(errno));
return false;
}
@@ -43,22 +43,22 @@
packet.packet_type = CrashPacketType::kDumpRequest;
packet.packet.dump_request.pid = pid;
if (TEMP_FAILURE_RETRY(write(sockfd, &packet, sizeof(packet))) != sizeof(packet)) {
- __libc_format_log(ANDROID_LOG_ERROR, "libc", "failed to write DumpRequest packet: %s",
- strerror(errno));
+ async_safe_format_log(ANDROID_LOG_ERROR, "libc", "failed to write DumpRequest packet: %s",
+ strerror(errno));
return false;
}
unique_fd tmp_output_fd;
ssize_t rc = recv_fd(sockfd, &packet, sizeof(packet), &tmp_output_fd);
if (rc == -1) {
- __libc_format_log(ANDROID_LOG_ERROR, "libc",
- "failed to read response to DumpRequest packet: %s", strerror(errno));
+ async_safe_format_log(ANDROID_LOG_ERROR, "libc",
+ "failed to read response to DumpRequest packet: %s", strerror(errno));
return false;
} else if (rc != sizeof(packet)) {
- __libc_format_log(
- ANDROID_LOG_ERROR, "libc",
- "received DumpRequest response packet of incorrect length (expected %zu, got %zd)",
- sizeof(packet), rc);
+ async_safe_format_log(
+ ANDROID_LOG_ERROR, "libc",
+ "received DumpRequest response packet of incorrect length (expected %zu, got %zd)",
+ sizeof(packet), rc);
return false;
}
@@ -67,8 +67,8 @@
// a regular fd, and writing to an fd with O_APPEND).
int flags = fcntl(tmp_output_fd.get(), F_GETFL);
if (fcntl(tmp_output_fd.get(), F_SETFL, flags | O_APPEND) != 0) {
- __libc_format_log(ANDROID_LOG_WARN, "libc", "failed to set output fd flags: %s",
- strerror(errno));
+ async_safe_format_log(ANDROID_LOG_WARN, "libc", "failed to set output fd flags: %s",
+ strerror(errno));
}
*tombstoned_socket = std::move(sockfd);
diff --git a/debuggerd/util.cpp b/debuggerd/util.cpp
index 4c015d7..32d2f18 100644
--- a/debuggerd/util.cpp
+++ b/debuggerd/util.cpp
@@ -24,8 +24,6 @@
#include <cutils/sockets.h>
#include <debuggerd/protocol.h>
-#include "private/libc_logging.h"
-
using android::base::unique_fd;
ssize_t send_fd(int sockfd, const void* data, size_t len, unique_fd fd) {
diff --git a/fastboot/fastboot.cpp b/fastboot/fastboot.cpp
index 982545c..dc6e698 100644
--- a/fastboot/fastboot.cpp
+++ b/fastboot/fastboot.cpp
@@ -124,6 +124,7 @@
{"vendor.img", "vendor.sig", "vendor", true, false},
{"vendor_other.img", "vendor.sig", "vendor", true, true},
{"vbmeta.img", "vbmeta.sig", "vbmeta", true, false},
+ {"dtbo.img", "dtbo.sig", "dtbo", true, false},
};
static std::string find_item_given_name(const char* img_name, const char* product) {
@@ -155,6 +156,8 @@
fn = "vendor.img";
} else if(!strcmp(item,"vbmeta")) {
fn = "vbmeta.img";
+ } else if(!strcmp(item,"dtbo")) {
+ fn = "dtbo.img";
} else if(!strcmp(item,"userdata")) {
fn = "userdata.img";
} else if(!strcmp(item,"cache")) {
diff --git a/init/builtins.cpp b/init/builtins.cpp
index 04cf4dc..9a2355b 100644
--- a/init/builtins.cpp
+++ b/init/builtins.cpp
@@ -205,7 +205,7 @@
mode = std::strtoul(args[2].c_str(), 0, 8);
}
- ret = make_dir(args[1].c_str(), mode);
+ ret = make_dir(args[1].c_str(), mode, sehandle);
/* chmod in case the directory already exists */
if (ret == -1 && errno == EEXIST) {
ret = fchmodat(AT_FDCWD, args[1].c_str(), mode, AT_SYMLINK_NOFOLLOW);
@@ -826,7 +826,7 @@
* Callback to make a directory from the ext4 code
*/
static int do_installkeys_ensure_dir_exists(const char* dir) {
- if (make_dir(dir, 0700) && errno != EEXIST) {
+ if (make_dir(dir, 0700, sehandle) && errno != EEXIST) {
return -1;
}
@@ -852,7 +852,9 @@
}
static int do_init_user0(const std::vector<std::string>& args) {
- return e4crypt_do_init_user0();
+ std::vector<std::string> exec_args = {"exec", "/system/bin/vdc", "--wait", "cryptfs",
+ "init_user0"};
+ return do_exec(exec_args);
}
const BuiltinFunctionMap::Map& BuiltinFunctionMap::map() const {
diff --git a/init/descriptors.cpp b/init/descriptors.cpp
index bc6bc8d..b2142ca 100644
--- a/init/descriptors.cpp
+++ b/init/descriptors.cpp
@@ -80,7 +80,7 @@
int flags = ((type() == "stream" ? SOCK_STREAM :
(type() == "dgram" ? SOCK_DGRAM :
SOCK_SEQPACKET)));
- return create_socket(name().c_str(), flags, perm(), uid(), gid(), context.c_str());
+ return create_socket(name().c_str(), flags, perm(), uid(), gid(), context.c_str(), sehandle);
}
const std::string SocketInfo::key() const {
diff --git a/init/devices.cpp b/init/devices.cpp
index 11687f0..74f099a 100644
--- a/init/devices.cpp
+++ b/init/devices.cpp
@@ -54,7 +54,11 @@
#include "ueventd.h"
#include "util.h"
-extern struct selabel_handle *sehandle;
+#ifdef _INIT_INIT_H
+#error "Do not include init.h in files used by ueventd or watchdogd; it will expose init's globals"
+#endif
+
+static selabel_handle* sehandle;
static android::base::unique_fd device_fd;
@@ -554,7 +558,7 @@
}
static void make_link_init(const std::string& oldpath, const std::string& newpath) {
- if (mkdir_recursive(dirname(newpath.c_str()), 0755)) {
+ if (mkdir_recursive(dirname(newpath.c_str()), 0755, sehandle)) {
PLOG(ERROR) << "Failed to create directory " << dirname(newpath.c_str());
}
@@ -599,7 +603,7 @@
if (uevent->major < 0 || uevent->minor < 0) return;
const char* base = "/dev/block/";
- make_dir(base, 0755);
+ make_dir(base, 0755, sehandle);
std::string name = android::base::Basename(uevent->path);
std::string devpath = base + name;
@@ -641,7 +645,7 @@
devpath = "/dev/" + android::base::Basename(uevent->path);
}
- mkdir_recursive(android::base::Dirname(devpath), 0755);
+ mkdir_recursive(android::base::Dirname(devpath), 0755, sehandle);
auto links = get_character_device_symlinks(uevent);
diff --git a/init/init.cpp b/init/init.cpp
index 731269f..e7d01f4 100644
--- a/init/init.cpp
+++ b/init/init.cpp
@@ -21,6 +21,7 @@
#include <errno.h>
#include <fcntl.h>
#include <inttypes.h>
+#include <keyutils.h>
#include <libgen.h>
#include <paths.h>
#include <signal.h>
@@ -881,9 +882,9 @@
}
}
-// The files and directories that were created before initial sepolicy load
-// need to have their security context restored to the proper value.
-// This must happen before /dev is populated by ueventd.
+// The files and directories that were created before initial sepolicy load or
+// files on ramdisk need to have their security context restored to the proper
+// value. This must happen before /dev is populated by ueventd.
static void selinux_restore_context() {
LOG(INFO) << "Running restorecon...";
restorecon("/dev");
@@ -913,6 +914,9 @@
restorecon("/sys", SELINUX_ANDROID_RESTORECON_RECURSE);
restorecon("/dev/block", SELINUX_ANDROID_RESTORECON_RECURSE);
restorecon("/dev/device-mapper");
+
+ restorecon("/sbin/mke2fs");
+ restorecon("/sbin/e2fsdroid");
}
// Set the UDC controller for the ConfigFS USB Gadgets.
@@ -1046,6 +1050,11 @@
InitKernelLogging(argv);
LOG(INFO) << "init second stage started!";
+ // Set up a session keyring that all processes will have access to. It
+ // will hold things like FBE encryption keys. No process should override
+ // its session keyring.
+ keyctl(KEYCTL_GET_KEYRING_ID, KEY_SPEC_SESSION_KEYRING, 1);
+
// Indicate that booting is in progress to background fw loaders, etc.
close(open("/dev/.booting", O_WRONLY | O_CREAT | O_CLOEXEC, 0000));
diff --git a/init/init.h b/init/init.h
index 6add75f..6725a70 100644
--- a/init/init.h
+++ b/init/init.h
@@ -19,6 +19,9 @@
#include <string>
+// Note: These globals are *only* valid in init, so they should not be used in ueventd,
+// watchdogd, or any files that may be included in those, such as devices.cpp and util.cpp.
+// TODO: Have an Init class and remove all globals.
extern const char *ENV[32];
extern std::string default_console;
extern struct selabel_handle *sehandle;
diff --git a/init/init_first_stage.cpp b/init/init_first_stage.cpp
index 43f1c15..2fa790d 100644
--- a/init/init_first_stage.cpp
+++ b/init/init_first_stage.cpp
@@ -143,8 +143,11 @@
if (!GetRequiredDevices(&devices_partition_names, &need_dm_verity)) return false;
if (need_dm_verity) {
- device_init("/sys/devices/virtual/misc/device-mapper",
- [&](uevent* uevent) -> coldboot_action_t { return COLDBOOT_STOP; });
+ const std::string dm_path = "/devices/virtual/misc/device-mapper";
+ device_init(("/sys" + dm_path).c_str(), [&dm_path](uevent* uevent) -> coldboot_action_t {
+ if (uevent->path == dm_path) return COLDBOOT_STOP;
+ return COLDBOOT_CONTINUE; // dm_path not found, continue to find it.
+ });
}
bool success = false;
diff --git a/init/keyutils.h b/init/keyutils.h
new file mode 100644
index 0000000..de01beb
--- /dev/null
+++ b/init/keyutils.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2017 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.
+ */
+
+/* Miniature version of a header-only keyutils.h (no library required) */
+
+#ifndef _INIT_KEYUTILS_H_
+#define _INIT_KEYUTILS_H_
+
+#ifndef KEYUTILS_H /* walk away if the _real_ one exists */
+
+#include <linux/keyctl.h>
+#include <stdarg.h>
+#include <sys/syscall.h>
+#include <unistd.h>
+
+static inline long keyctl(int cmd, ...) {
+ va_list va;
+ unsigned long arg2, arg3, arg4, arg5;
+
+ va_start(va, cmd);
+ arg2 = va_arg(va, unsigned long);
+ arg3 = va_arg(va, unsigned long);
+ arg4 = va_arg(va, unsigned long);
+ arg5 = va_arg(va, unsigned long);
+ va_end(va);
+ return syscall(__NR_keyctl, cmd, arg2, arg3, arg4, arg5);
+}
+
+#endif
+
+#endif
diff --git a/init/property_service.cpp b/init/property_service.cpp
index aa47976..6f40d1c 100644
--- a/init/property_service.cpp
+++ b/init/property_service.cpp
@@ -659,7 +659,7 @@
property_set("ro.property_service.version", "2");
property_set_fd = create_socket(PROP_SERVICE_NAME, SOCK_STREAM | SOCK_CLOEXEC | SOCK_NONBLOCK,
- 0666, 0, 0, NULL);
+ 0666, 0, 0, nullptr, sehandle);
if (property_set_fd == -1) {
PLOG(ERROR) << "start_property_service socket creation failed";
exit(1);
diff --git a/init/util.cpp b/init/util.cpp
index a101ce5..87b8d9d 100644
--- a/init/util.cpp
+++ b/init/util.cpp
@@ -40,11 +40,13 @@
#include <cutils/android_reboot.h>
#include <cutils/sockets.h>
#include <selinux/android.h>
-#include <selinux/label.h>
-#include "init.h"
#include "reboot.h"
+#ifdef _INIT_INIT_H
+#error "Do not include init.h in files used by ueventd or watchdogd; it will expose init's globals"
+#endif
+
using android::base::boot_clock;
static unsigned int do_decode_uid(const char *s)
@@ -87,9 +89,8 @@
* daemon. We communicate the file descriptor's value via the environment
* variable ANDROID_SOCKET_ENV_PREFIX<name> ("ANDROID_SOCKET_foo").
*/
-int create_socket(const char *name, int type, mode_t perm, uid_t uid,
- gid_t gid, const char *socketcon)
-{
+int create_socket(const char* name, int type, mode_t perm, uid_t uid, gid_t gid,
+ const char* socketcon, selabel_handle* sehandle) {
if (socketcon) {
if (setsockcreatecon(socketcon) == -1) {
PLOG(ERROR) << "setsockcreatecon(\"" << socketcon << "\") failed";
@@ -194,17 +195,17 @@
return success;
}
-int mkdir_recursive(const std::string& path, mode_t mode) {
+int mkdir_recursive(const std::string& path, mode_t mode, selabel_handle* sehandle) {
std::string::size_type slash = 0;
while ((slash = path.find('/', slash + 1)) != std::string::npos) {
auto directory = path.substr(0, slash);
struct stat info;
if (stat(directory.c_str(), &info) != 0) {
- auto ret = make_dir(directory.c_str(), mode);
+ auto ret = make_dir(directory.c_str(), mode, sehandle);
if (ret && errno != EEXIST) return ret;
}
}
- auto ret = make_dir(path.c_str(), mode);
+ auto ret = make_dir(path.c_str(), mode, sehandle);
if (ret && errno != EEXIST) return ret;
return 0;
}
@@ -233,8 +234,7 @@
}
}
-int make_dir(const char *path, mode_t mode)
-{
+int make_dir(const char* path, mode_t mode, selabel_handle* sehandle) {
int rc;
char *secontext = NULL;
diff --git a/init/util.h b/init/util.h
index 92b3a1d..55ebded 100644
--- a/init/util.h
+++ b/init/util.h
@@ -26,6 +26,7 @@
#include <string>
#include <android-base/chrono_utils.h>
+#include <selinux/label.h>
#define COLDBOOT_DONE "/dev/.coldboot_done"
@@ -34,8 +35,8 @@
using android::base::boot_clock;
using namespace std::chrono_literals;
-int create_socket(const char *name, int type, mode_t perm,
- uid_t uid, gid_t gid, const char *socketcon);
+int create_socket(const char* name, int type, mode_t perm, uid_t uid, gid_t gid,
+ const char* socketcon, selabel_handle* sehandle);
bool read_file(const std::string& path, std::string* content);
bool write_file(const std::string& path, const std::string& content);
@@ -62,11 +63,11 @@
unsigned int decode_uid(const char *s);
-int mkdir_recursive(const std::string& pathname, mode_t mode);
+int mkdir_recursive(const std::string& pathname, mode_t mode, selabel_handle* sehandle);
int wait_for_file(const char *filename, std::chrono::nanoseconds timeout);
void import_kernel_cmdline(bool in_qemu,
const std::function<void(const std::string&, const std::string&, bool)>&);
-int make_dir(const char *path, mode_t mode);
+int make_dir(const char* path, mode_t mode, selabel_handle* sehandle);
int restorecon(const char *pathname, int flags = 0);
std::string bytes_to_hex(const uint8_t *bytes, size_t bytes_len);
bool is_dir(const char* pathname);
diff --git a/init/util_test.cpp b/init/util_test.cpp
index b8b409a..ac23a32 100644
--- a/init/util_test.cpp
+++ b/init/util_test.cpp
@@ -128,15 +128,10 @@
EXPECT_FALSE(is_dir(tf.path));
}
-// sehandle is needed for make_dir()
-// TODO: Remove once sehandle is encapsulated
-#include <selinux/label.h>
-selabel_handle* sehandle;
-
TEST(util, mkdir_recursive) {
TemporaryDir test_dir;
std::string path = android::base::StringPrintf("%s/three/directories/deep", test_dir.path);
- EXPECT_EQ(0, mkdir_recursive(path, 0755));
+ EXPECT_EQ(0, mkdir_recursive(path, 0755, nullptr));
std::string path1 = android::base::StringPrintf("%s/three", test_dir.path);
EXPECT_TRUE(is_dir(path1.c_str()));
std::string path2 = android::base::StringPrintf("%s/three/directories", test_dir.path);
@@ -148,7 +143,7 @@
TEST(util, mkdir_recursive_extra_slashes) {
TemporaryDir test_dir;
std::string path = android::base::StringPrintf("%s/three////directories/deep//", test_dir.path);
- EXPECT_EQ(0, mkdir_recursive(path, 0755));
+ EXPECT_EQ(0, mkdir_recursive(path, 0755, nullptr));
std::string path1 = android::base::StringPrintf("%s/three", test_dir.path);
EXPECT_TRUE(is_dir(path1.c_str()));
std::string path2 = android::base::StringPrintf("%s/three/directories", test_dir.path);
diff --git a/init/watchdogd.cpp b/init/watchdogd.cpp
index 21c1e5b..7baa487 100644
--- a/init/watchdogd.cpp
+++ b/init/watchdogd.cpp
@@ -24,7 +24,10 @@
#include <android-base/logging.h>
#include "log.h"
-#include "util.h"
+
+#ifdef _INIT_INIT_H
+#error "Do not include init.h in files used by ueventd or watchdogd; it will expose init's globals"
+#endif
#define DEV_NAME "/dev/watchdog"
diff --git a/libcutils/Android.bp b/libcutils/Android.bp
index 58170ec..245deb1 100644
--- a/libcutils/Android.bp
+++ b/libcutils/Android.bp
@@ -53,7 +53,7 @@
host_supported: true,
srcs: [
"config_utils.c",
- "fs_config.c",
+ "fs_config.cpp",
"canned_fs_config.c",
"hashmap.c",
"iosched_policy.c",
@@ -94,6 +94,9 @@
shared: {
enabled: false,
},
+ cflags: [
+ "-D_GNU_SOURCE",
+ ],
},
android: {
diff --git a/libcutils/fs_config.c b/libcutils/fs_config.cpp
similarity index 85%
rename from libcutils/fs_config.c
rename to libcutils/fs_config.cpp
index d98a923..55e393c 100644
--- a/libcutils/fs_config.c
+++ b/libcutils/fs_config.cpp
@@ -14,15 +14,12 @@
* limitations under the License.
*/
-/* This file is used to define the properties of the filesystem
-** images generated by build tools (mkbootfs and mkyaffs2image) and
-** by the device side of adb.
-*/
+// This file is used to define the properties of the filesystem
+// images generated by build tools (mkbootfs and mkyaffs2image) and
+// by the device side of adb.
#define LOG_TAG "fs_config"
-#define _GNU_SOURCE
-
#include <errno.h>
#include <fcntl.h>
#include <stdbool.h>
@@ -42,8 +39,10 @@
#define O_BINARY 0
#endif
-/* My kingdom for <endian.h> */
-static inline uint16_t get2LE(const uint8_t* src) { return src[0] | (src[1] << 8); }
+// My kingdom for <endian.h>
+static inline uint16_t get2LE(const uint8_t* src) {
+ return src[0] | (src[1] << 8);
+}
static inline uint64_t get8LE(const uint8_t* src) {
uint32_t low, high;
@@ -55,14 +54,13 @@
#define ALIGN(x, alignment) (((x) + ((alignment)-1)) & ~((alignment)-1))
-/* Rules for directories.
-** These rules are applied based on "first match", so they
-** should start with the most specific path and work their
-** way up to the root.
-*/
+// Rules for directories.
+// These rules are applied based on "first match", so they
+// should start with the most specific path and work their
+// way up to the root.
static const struct fs_path_config android_dirs[] = {
- /* clang-format off */
+ // clang-format off
{ 00770, AID_SYSTEM, AID_CACHE, 0, "cache" },
{ 00500, AID_ROOT, AID_ROOT, 0, "config" },
{ 00771, AID_SYSTEM, AID_SYSTEM, 0, "data/app" },
@@ -92,25 +90,23 @@
{ 00755, AID_ROOT, AID_SHELL, 0, "system/xbin" },
{ 00755, AID_ROOT, AID_SHELL, 0, "vendor" },
{ 00755, AID_ROOT, AID_ROOT, 0, 0 },
- /* clang-format on */
+ // clang-format on
};
-/* Rules for files.
-** These rules are applied based on "first match", so they
-** should start with the most specific path and work their
-** way up to the root. Prefixes ending in * denotes wildcard
-** and will allow partial matches.
-*/
+// Rules for files.
+// These rules are applied based on "first match", so they
+// should start with the most specific path and work their
+// way up to the root. Prefixes ending in * denotes wildcard
+// and will allow partial matches.
static const char sys_conf_dir[] = "/system/etc/fs_config_dirs";
static const char sys_conf_file[] = "/system/etc/fs_config_files";
-/* No restrictions are placed on the vendor and oem file-system config files,
- * although the developer is advised to restrict the scope to the /vendor or
- * oem/ file-system since the intent is to provide support for customized
- * portions of a separate vendor.img or oem.img. Has to remain open so that
- * customization can also land on /system/vendor, /system/oem or /system/odm.
- * We expect build-time checking or filtering when constructing the associated
- * fs_config_* files (see build/tools/fs_config/fs_config_generate.c)
- */
+// No restrictions are placed on the vendor and oem file-system config files,
+// although the developer is advised to restrict the scope to the /vendor or
+// oem/ file-system since the intent is to provide support for customized
+// portions of a separate vendor.img or oem.img. Has to remain open so that
+// customization can also land on /system/vendor, /system/oem or /system/odm.
+// We expect build-time checking or filtering when constructing the associated
+// fs_config_* files (see build/tools/fs_config/fs_config_generate.c)
static const char ven_conf_dir[] = "/vendor/etc/fs_config_dirs";
static const char ven_conf_file[] = "/vendor/etc/fs_config_files";
static const char oem_conf_dir[] = "/oem/etc/fs_config_dirs";
@@ -125,7 +121,7 @@
};
static const struct fs_path_config android_files[] = {
- /* clang-format off */
+ // clang-format off
{ 00644, AID_SYSTEM, AID_SYSTEM, 0, "data/app/*" },
{ 00644, AID_SYSTEM, AID_SYSTEM, 0, "data/app-ephemeral/*" },
{ 00644, AID_SYSTEM, AID_SYSTEM, 0, "data/app-private/*" },
@@ -173,13 +169,13 @@
{ 00444, AID_ROOT, AID_ROOT, 0, ven_conf_dir + 1 },
{ 00444, AID_ROOT, AID_ROOT, 0, ven_conf_file + 1 },
- /* the following two files are INTENTIONALLY set-uid, but they
- * are NOT included on user builds. */
+ // the following two files are INTENTIONALLY set-uid, but they
+ // are NOT included on user builds.
{ 06755, AID_ROOT, AID_ROOT, 0, "system/xbin/procmem" },
{ 04750, AID_ROOT, AID_SHELL, 0, "system/xbin/su" },
- /* the following files have enhanced capabilities and ARE included
- * in user builds. */
+ // the following files have enhanced capabilities and ARE included
+ // in user builds.
{ 00700, AID_SYSTEM, AID_SHELL, CAP_MASK_LONG(CAP_BLOCK_SUSPEND),
"system/bin/inputflinger" },
{ 00550, AID_LOGD, AID_LOGD, CAP_MASK_LONG(CAP_SYSLOG) |
@@ -190,11 +186,11 @@
CAP_MASK_LONG(CAP_SETGID),
"system/bin/run-as" },
- /* Support FIFO scheduling mode in SurfaceFlinger. */
+ // Support FIFO scheduling mode in SurfaceFlinger.
{ 00755, AID_SYSTEM, AID_GRAPHICS, CAP_MASK_LONG(CAP_SYS_NICE),
"system/bin/surfaceflinger" },
- /* Support hostapd administering a network interface. */
+ // Support hostapd administering a network interface.
{ 00755, AID_WIFI, AID_WIFI, CAP_MASK_LONG(CAP_NET_ADMIN) |
CAP_MASK_LONG(CAP_NET_RAW),
"system/vendor/bin/hostapd" },
@@ -202,8 +198,8 @@
CAP_MASK_LONG(CAP_NET_RAW),
"vendor/bin/hostapd" },
- /* Support Bluetooth legacy hal accessing /sys/class/rfkill
- * Support RT scheduling in Bluetooth */
+ // Support Bluetooth legacy hal accessing /sys/class/rfkill
+ // Support RT scheduling in Bluetooth
{ 00700, AID_BLUETOOTH, AID_BLUETOOTH, CAP_MASK_LONG(CAP_NET_ADMIN) |
CAP_MASK_LONG(CAP_SYS_NICE),
"system/vendor/bin/hw/android.hardware.bluetooth@1.0-service" },
@@ -211,16 +207,12 @@
CAP_MASK_LONG(CAP_SYS_NICE),
"vendor/bin/hw/android.hardware.bluetooth@1.0-service" },
- /* Support wifi_hal_legacy administering a network interface. */
- { 00755, AID_WIFI, AID_WIFI, CAP_MASK_LONG(CAP_NET_ADMIN) |
- CAP_MASK_LONG(CAP_NET_RAW),
- "system/vendor/bin/hw/android.hardware.wifi@1.0-service" },
+ // Support wifi_hal_legacy administering a network interface.
{ 00755, AID_WIFI, AID_WIFI, CAP_MASK_LONG(CAP_NET_ADMIN) |
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. */
+ // 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),
@@ -230,7 +222,7 @@
CAP_MASK_LONG(CAP_SETPCAP),
"system/bin/webview_zygote64" },
- /* generic defaults */
+ // generic defaults
{ 00755, AID_ROOT, AID_ROOT, 0, "bin/*" },
{ 00640, AID_ROOT, AID_SHELL, 0, "fstab.*" },
{ 00750, AID_ROOT, AID_SHELL, 0, "init*" },
@@ -244,7 +236,7 @@
{ 00755, AID_ROOT, AID_SHELL, 0, "vendor/bin/*" },
{ 00755, AID_ROOT, AID_SHELL, 0, "vendor/xbin/*" },
{ 00644, AID_ROOT, AID_ROOT, 0, 0 },
- /* clang-format on */
+ // clang-format on
};
static size_t strip(const char* path, size_t len, const char suffix[]) {
@@ -257,9 +249,9 @@
int fd = -1;
if (target_out_path && *target_out_path) {
- /* target_out_path is the path to the directory holding content of
- * system partition but as we cannot guarantee it ends with '/system'
- * or with or without a trailing slash, need to strip them carefully. */
+ // target_out_path is the path to the directory holding content of
+ // system partition but as we cannot guarantee it ends with '/system'
+ // or with or without a trailing slash, need to strip them carefully.
char* name = NULL;
size_t len = strlen(target_out_path);
len = strip(target_out_path, len, "/");
@@ -281,7 +273,7 @@
return false;
}
} else {
- /* If name ends in * then allow partial matches. */
+ // If name ends in * then allow partial matches.
if (prefix[len - 1] == '*') {
return !strncmp(prefix, path, len - 1);
}
@@ -317,7 +309,7 @@
ALOGE("%s len is corrupted", conf[which][dir]);
break;
}
- prefix = calloc(1, remainder);
+ prefix = static_cast<char*>(calloc(1, remainder));
if (!prefix) {
ALOGE("%s out of memory", conf[which][dir]);
break;
@@ -328,7 +320,7 @@
break;
}
len = strnlen(prefix, remainder);
- if (len >= remainder) { /* missing a terminating null */
+ if (len >= remainder) { // missing a terminating null
free(prefix);
ALOGE("%s is corrupted", conf[which][dir]);
break;
diff --git a/libcutils/native_handle.c b/libcutils/native_handle.c
index 9f4840a..95bbc41 100644
--- a/libcutils/native_handle.c
+++ b/libcutils/native_handle.c
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-#define LOG_TAG "NativeHandle"
+#include <cutils/native_handle.h>
#include <errno.h>
#include <stdint.h>
@@ -22,15 +22,12 @@
#include <string.h>
#include <unistd.h>
-#include <android/log.h>
-#include <cutils/native_handle.h>
-
static const int kMaxNativeFds = 1024;
static const int kMaxNativeInts = 1024;
-native_handle_t* native_handle_init(char* storage, int numFds, int numInts)
-{
+native_handle_t* native_handle_init(char* storage, int numFds, int numInts) {
if ((uintptr_t) storage % alignof(native_handle_t)) {
+ errno = EINVAL;
return NULL;
}
@@ -38,13 +35,12 @@
handle->version = sizeof(native_handle_t);
handle->numFds = numFds;
handle->numInts = numInts;
-
return handle;
}
-native_handle_t* native_handle_create(int numFds, int numInts)
-{
+native_handle_t* native_handle_create(int numFds, int numInts) {
if (numFds < 0 || numInts < 0 || numFds > kMaxNativeFds || numInts > kMaxNativeInts) {
+ errno = EINVAL;
return NULL;
}
@@ -58,14 +54,13 @@
return h;
}
-native_handle_t* native_handle_clone(const native_handle_t* handle)
-{
+native_handle_t* native_handle_clone(const native_handle_t* handle) {
native_handle_t* clone = native_handle_create(handle->numFds, handle->numInts);
- int i;
+ if (clone == NULL) return NULL;
- for (i = 0; i < handle->numFds; i++) {
+ for (int i = 0; i < handle->numFds; i++) {
clone->data[i] = dup(handle->data[i]);
- if (clone->data[i] < 0) {
+ if (clone->data[i] == -1) {
clone->numFds = i;
native_handle_close(clone);
native_handle_delete(clone);
@@ -74,30 +69,27 @@
}
memcpy(&clone->data[handle->numFds], &handle->data[handle->numFds],
- sizeof(int) * handle->numInts);
+ sizeof(int) * handle->numInts);
return clone;
}
-int native_handle_delete(native_handle_t* h)
-{
+int native_handle_delete(native_handle_t* h) {
if (h) {
- if (h->version != sizeof(native_handle_t))
- return -EINVAL;
+ if (h->version != sizeof(native_handle_t)) return -EINVAL;
free(h);
}
return 0;
}
-int native_handle_close(const native_handle_t* h)
-{
- if (h->version != sizeof(native_handle_t))
- return -EINVAL;
+int native_handle_close(const native_handle_t* h) {
+ if (h->version != sizeof(native_handle_t)) return -EINVAL;
+ int saved_errno = errno;
const int numFds = h->numFds;
- int i;
- for (i=0 ; i<numFds ; i++) {
+ for (int i = 0; i < numFds; ++i) {
close(h->data[i]);
}
+ errno = saved_errno;
return 0;
}
diff --git a/libgrallocusage/Android.bp b/libgrallocusage/Android.bp
index 54bfee5..cf03868 100644
--- a/libgrallocusage/Android.bp
+++ b/libgrallocusage/Android.bp
@@ -14,6 +14,7 @@
cc_library_static {
name: "libgrallocusage",
+ vendor_available: true,
cppflags: [
"-Weverything",
"-Werror",
@@ -26,4 +27,5 @@
srcs: ["GrallocUsageConversion.cpp"],
export_include_dirs: ["include"],
shared_libs: ["android.hardware.graphics.allocator@2.0"],
+ header_libs: ["libhardware_headers"],
}
diff --git a/liblog/tests/Android.mk b/liblog/tests/Android.mk
index 0e6432c..ab96429 100644
--- a/liblog/tests/Android.mk
+++ b/liblog/tests/Android.mk
@@ -55,6 +55,7 @@
-fno-builtin \
test_src_files := \
+ libc_test.cpp \
liblog_test_default.cpp \
liblog_test_local.cpp \
liblog_test_stderr.cpp \
@@ -65,14 +66,6 @@
log_system_test.cpp \
log_time_test.cpp
-# to prevent breaking the build if bionic not relatively visible to us
-ifneq ($(wildcard $(LOCAL_PATH)/../../../../bionic/libc/bionic/libc_logging.cpp),)
-
-test_src_files += \
- libc_test.cpp
-
-endif
-
# Build tests for the device (with .so). Run with:
# adb shell /data/nativetest/liblog-unit-tests/liblog-unit-tests
include $(CLEAR_VARS)
diff --git a/libmemunreachable/Android.bp b/libmemunreachable/Android.bp
index 4662368..2867f64 100644
--- a/libmemunreachable/Android.bp
+++ b/libmemunreachable/Android.bp
@@ -30,7 +30,6 @@
static_libs: [
"libc_malloc_debug_backtrace",
- "libc_logging",
],
// Only need this for arm since libc++ uses its own unwind code that
// doesn't mix with the other default unwind code.
diff --git a/logd/logd.rc b/logd/logd.rc
index ee89b83..7494d8f 100644
--- a/logd/logd.rc
+++ b/logd/logd.rc
@@ -5,7 +5,7 @@
file /proc/kmsg r
file /dev/kmsg w
user logd
- group logd system readproc
+ group logd system package_info readproc
writepid /dev/cpuset/system-background/tasks
service logd-reinit /system/bin/logd --reinit
diff --git a/logd/main.cpp b/logd/main.cpp
index 18029eb..c8183f0 100644
--- a/logd/main.cpp
+++ b/logd/main.cpp
@@ -240,23 +240,36 @@
set_sched_policy(0, SP_BACKGROUND);
setpriority(PRIO_PROCESS, 0, ANDROID_PRIORITY_BACKGROUND);
+ // We should drop to AID_LOGD, if we are anything else, we have
+ // even lesser privileges and accept our fate.
+ gid_t groups[] = {
+ AID_SYSTEM, // search access to /data/system path
+ AID_PACKAGE_INFO, // readonly access to /data/system/packages.list
+ };
+ if (setgroups(arraysize(groups), groups) == -1) {
+ android::prdebug(
+ "logd.daemon: failed to set AID_SYSTEM AID_PACKAGE_INFO groups");
+ }
+ if (setgid(AID_LOGD) != 0) {
+ android::prdebug("logd.daemon: failed to set AID_LOGD gid");
+ }
+ if (setuid(AID_LOGD) != 0) {
+ android::prdebug("logd.daemon: failed to set AID_LOGD uid");
+ }
+
cap_t caps = cap_init();
(void)cap_clear(caps);
(void)cap_set_proc(caps);
(void)cap_free(caps);
- // If we are AID_ROOT, we should drop to AID_LOGD+AID_SYSTEM, if we are
- // anything else, we have even lesser privileges and accept our fate. Not
- // worth checking for error returns setting this thread's privileges.
- (void)setgid(AID_SYSTEM); // readonly access to /data/system/packages.list
- (void)setuid(AID_LOGD); // access to everything logd, eg /data/misc/logd
-
while (reinit_running && !sem_wait(&reinit) && reinit_running) {
// uidToName Privileged Worker
if (uid) {
name = nullptr;
- packagelist_parse(package_list_parser_cb, nullptr);
+ // if we got the perms wrong above, this would spam if we reported
+ // problems with acquisition of an uid name from the packages.
+ (void)packagelist_parse(package_list_parser_cb, nullptr);
uid = 0;
sem_post(&uidName);
diff --git a/logd/tests/logd_test.cpp b/logd/tests/logd_test.cpp
index bd9fa93..f90c9fb 100644
--- a/logd/tests/logd_test.cpp
+++ b/logd/tests/logd_test.cpp
@@ -14,6 +14,7 @@
* limitations under the License.
*/
+#include <ctype.h>
#include <fcntl.h>
#include <inttypes.h>
#include <poll.h>
@@ -26,6 +27,7 @@
#include <string>
+#include <android-base/file.h>
#include <android-base/macros.h>
#include <android-base/stringprintf.h>
#include <cutils/sockets.h>
@@ -85,7 +87,7 @@
size_t ret = atol(buf) + 1;
if (ret < 4) {
delete[] buf;
- buf = NULL;
+ buf = nullptr;
break;
}
bool check = ret <= len;
@@ -107,7 +109,7 @@
// UID PACKAGE BYTES LINES
// 0 root 54164 147569
//
- char* benchmark = NULL;
+ char* benchmark = nullptr;
do {
static const char signature[] = "\n0 root ";
@@ -122,7 +124,7 @@
benchmark = cp;
#ifdef DEBUG
char* end = strstr(benchmark, "\n");
- if (end == NULL) {
+ if (end == nullptr) {
end = benchmark + strlen(benchmark);
}
fprintf(stderr, "parse for spam counter in \"%.*s\"\n",
@@ -154,7 +156,7 @@
if (value > 10UL) {
break;
}
- benchmark = NULL;
+ benchmark = nullptr;
} while (*cp);
return benchmark;
}
@@ -165,9 +167,14 @@
size_t len;
char* buf;
+ // Drop cache so that any access problems can be discovered.
+ if (!android::base::WriteStringToFile("3\n", "/proc/sys/vm/drop_caches")) {
+ GTEST_LOG_(INFO) << "Could not open trigger dropping inode cache";
+ }
+
alloc_statistics(&buf, &len);
- ASSERT_TRUE(NULL != buf);
+ ASSERT_TRUE(nullptr != buf);
// remove trailing FF
char* cp = buf + len - 1;
@@ -192,19 +199,38 @@
EXPECT_EQ(0, truncated);
char* main_logs = strstr(cp, "\nChattiest UIDs in main ");
- EXPECT_TRUE(NULL != main_logs);
+ EXPECT_TRUE(nullptr != main_logs);
char* radio_logs = strstr(cp, "\nChattiest UIDs in radio ");
if (!radio_logs)
- GTEST_LOG_(INFO) << "Value of: NULL != radio_logs\n"
+ GTEST_LOG_(INFO) << "Value of: nullptr != radio_logs\n"
"Actual: false\n"
"Expected: false\n";
char* system_logs = strstr(cp, "\nChattiest UIDs in system ");
- EXPECT_TRUE(NULL != system_logs);
+ EXPECT_TRUE(nullptr != system_logs);
char* events_logs = strstr(cp, "\nChattiest UIDs in events ");
- EXPECT_TRUE(NULL != events_logs);
+ EXPECT_TRUE(nullptr != events_logs);
+
+ // Check if there is any " u0_a#### " as this means packagelistparser broken
+ char* used_getpwuid = nullptr;
+ int used_getpwuid_len;
+ char* uid_name = cp;
+ static const char getpwuid_prefix[] = " u0_a";
+ while ((uid_name = strstr(uid_name, getpwuid_prefix)) != nullptr) {
+ used_getpwuid = uid_name + 1;
+ uid_name += strlen(getpwuid_prefix);
+ while (isdigit(*uid_name)) ++uid_name;
+ used_getpwuid_len = uid_name - used_getpwuid;
+ if (isspace(*uid_name)) break;
+ used_getpwuid = nullptr;
+ }
+ EXPECT_TRUE(nullptr == used_getpwuid);
+ if (used_getpwuid) {
+ fprintf(stderr, "libpackagelistparser failed to pick up %.*s\n",
+ used_getpwuid_len, used_getpwuid);
+ }
delete[] buf;
#else
@@ -352,7 +378,7 @@
}
alarm(old_alarm);
- sigaction(SIGALRM, &old_sigaction, NULL);
+ sigaction(SIGALRM, &old_sigaction, nullptr);
close(fd);
}
@@ -434,7 +460,7 @@
// Introduce some extreme spam for the worst UID filter
ASSERT_TRUE(
- NULL !=
+ nullptr !=
(fp = popen("/data/nativetest/liblog-benchmarks/liblog-benchmarks"
" BM_log_maximum_retry"
" BM_log_maximum"
@@ -505,10 +531,10 @@
bool collected_statistics = !!buf;
EXPECT_EQ(true, collected_statistics);
- ASSERT_TRUE(NULL != buf);
+ ASSERT_TRUE(nullptr != buf);
char* benchmark_statistics_found = find_benchmark_spam(buf);
- ASSERT_TRUE(benchmark_statistics_found != NULL);
+ ASSERT_TRUE(benchmark_statistics_found != nullptr);
// Check how effective the SPAM filter is, parse out Now size.
// 0 root 54164 147569
@@ -603,7 +629,7 @@
written = write(fd, ask.c_str(), len) == (ssize_t)len;
if (!written) {
alarm(old_alarm);
- sigaction(SIGALRM, &old_sigaction, NULL);
+ sigaction(SIGALRM, &old_sigaction, nullptr);
close(fd);
continue;
}
@@ -625,7 +651,7 @@
: (old_alarm > (1 + 3 - alarm_wrap))
? old_alarm - 3 + alarm_wrap
: 2);
- sigaction(SIGALRM, &old_sigaction, NULL);
+ sigaction(SIGALRM, &old_sigaction, nullptr);
close(fd);
@@ -648,7 +674,7 @@
EXPECT_TRUE(content_timeout);
EXPECT_NE(0U, alarm_timeout);
#else
- command = NULL;
+ command = nullptr;
GTEST_LOG_(INFO) << "This test does nothing.\n";
#endif
}
@@ -713,7 +739,7 @@
written = write(fd, ask.c_str(), len) == (ssize_t)len;
if (!written) {
alarm(old_alarm);
- sigaction(SIGALRM, &old_sigaction, NULL);
+ sigaction(SIGALRM, &old_sigaction, nullptr);
close(fd);
continue;
}
@@ -735,7 +761,7 @@
: (old_alarm > (1 + 3 - alarm_wrap))
? old_alarm - 3 + alarm_wrap
: 2);
- sigaction(SIGALRM, &old_sigaction, NULL);
+ sigaction(SIGALRM, &old_sigaction, nullptr);
close(fd);
@@ -837,7 +863,7 @@
int save_errno = (recv_ret < 0) ? errno : 0;
EXPECT_NE(0U, alarm(old_alarm));
- sigaction(SIGALRM, &old_sigaction, NULL);
+ sigaction(SIGALRM, &old_sigaction, nullptr);
EXPECT_EQ(0, recv_ret);
if (recv_ret > 0) {
@@ -876,8 +902,8 @@
char* cp;
long ret = strtol(buffer, &cp, 10);
EXPECT_GT(ret, 16);
- EXPECT_TRUE(strstr(buffer, "\t(to life the universe etc|3)") != NULL);
- EXPECT_TRUE(strstr(buffer, "answer") != NULL);
+ EXPECT_TRUE(strstr(buffer, "\t(to life the universe etc|3)") != nullptr);
+ EXPECT_TRUE(strstr(buffer, "answer") != nullptr);
#else
GTEST_LOG_(INFO) << "This test does nothing.\n";
#endif
@@ -897,8 +923,8 @@
char* cp;
long ret = strtol(buffer, &cp, 10);
EXPECT_GT(ret, 16);
- EXPECT_TRUE(strstr(buffer, "\t(new|1)") != NULL);
- EXPECT_TRUE(strstr(buffer, name) != NULL);
+ EXPECT_TRUE(strstr(buffer, "\t(new|1)") != nullptr);
+ EXPECT_TRUE(strstr(buffer, name) != nullptr);
// ToDo: also look for this in /data/misc/logd/event-log-tags and
// /dev/event-log-tags.
#else
@@ -942,7 +968,7 @@
ASSERT_EQ(0, info.si_status);
struct logger_list* logger_list;
- ASSERT_TRUE(NULL !=
+ ASSERT_TRUE(nullptr !=
(logger_list = android_logger_list_open(
LOG_ID_EVENTS, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK,
0, pid)));
diff --git a/rootdir/etc/ld.config.txt b/rootdir/etc/ld.config.txt
index 21179fb..3e23d98 100644
--- a/rootdir/etc/ld.config.txt
+++ b/rootdir/etc/ld.config.txt
@@ -67,7 +67,7 @@
namespace.sphal.link.default.shared_libs = libc.so:libz.so:libm.so:libdl.so:libstdc++.so:liblog.so:libnativewindow.so:libEGL.so:libsync.so:libbacktrace.so:libGLESv1_CM.so:libGLESv2.so
# WARNING: only VNDK-SP libs can be listed here. DO NOT EDIT this line.
-namespace.sphal.link.vndk.shared_libs = android.hardware.renderscript@1.0.so:android.hardware.graphics.allocator@2.0.so:android.hardware.graphics.mapper@2.0.so:android.hardware.graphics.common@1.0.so:android.hidl.base@1.0.so:libhwbinder.so:libbase.so:libcutils.so:libhardware.so:libhidlbase.so:libhidltransport.so:libutils.so:libc++.so
+namespace.sphal.link.vndk.shared_libs = android.hardware.renderscript@1.0.so:android.hardware.graphics.allocator@2.0.so:android.hardware.graphics.mapper@2.0.so:android.hardware.graphics.common@1.0.so:libhwbinder.so:libbase.so:libcutils.so:libhardware.so:libhidlbase.so:libhidltransport.so:libutils.so:libc++.so
# Renderscript gets separate namespace
namespace.sphal.link.rs.shared_libs = libRS_internal.so
@@ -86,7 +86,7 @@
namespace.rs.links = default,vndk
namespace.rs.link.default.shared_libs = libc.so:libz.so:libm.so:libdl.so:libstdc++.so:liblog.so:libnativewindow.so:libEGL.so:libsync.so:libbacktrace.so:libGLESv1_CM.so:libGLESv2.so:libmediandk.so:libui.so
-namespace.rs.link.vndk.shared_libs = android.hardware.renderscript@1.0.so:android.hardware.graphics.allocator@2.0.so:android.hardware.graphics.mapper@2.0.so:android.hardware.graphics.common@1.0.so:android.hidl.base@1.0.so:libhwbinder.so:libbase.so:libcutils.so:libhardware.so:libhidlbase.so:libhidltransport.so:libutils.so:libc++.so
+namespace.rs.link.vndk.shared_libs = android.hardware.renderscript@1.0.so:android.hardware.graphics.allocator@2.0.so:android.hardware.graphics.mapper@2.0.so:android.hardware.graphics.common@1.0.so:libhwbinder.so:libbase.so:libcutils.so:libhardware.so:libhidlbase.so:libhidltransport.so:libutils.so:libc++.so
###############################################################################
# "vndk" namespace
@@ -97,7 +97,7 @@
namespace.vndk.search.paths = /system/${LIB}/vndk-sp:/vendor/${LIB}
namespace.vndk.permitted.paths = /vendor/${LIB}/hw:/vendor/${LIB}/egl
-namespace.vndk.asan.search.paths = /data/asan/vendor/${LIB}/vndk-sp:/vendor/${LIB}/vndk-sp:/data/asan/vendor/${LIB}:/vendor/${LIB}
+namespace.vndk.asan.search.paths = /data/asan/system/${LIB}/vndk-sp:/system/${LIB}/vndk-sp:/data/asan/vendor/${LIB}:/vendor/${LIB}
namespace.vndk.asan.permitted.paths = /data/asan/vendor/${LIB}/hw:/vendor/${LIB}/hw:/data/asan/vendor/${LIB}/egl:/vendor/${LIB}/egl
# When these NDK libs are required inside this namespace, then it is redirected
@@ -115,6 +115,6 @@
[vendor]
namespace.default.isolated = false
-namespace.default.search.paths = /vendor/${LIB}:/vendor/${LIB}/vndk-sp:/system/${LIB}
+namespace.default.search.paths = /vendor/${LIB}:/system/${LIB}/vndk-sp:/system/${LIB}
-namespace.default.asan.search.paths = /data/asan/vendor/${LIB}:/vendor/${LIB}:/data/asan/vendor/${LIB}/vndk-sp:/vendor/${LIB}/vndk-sp:/data/asan/system/${LIB}:/system/${LIB}
+namespace.default.asan.search.paths = /data/asan/vendor/${LIB}:/vendor/${LIB}:/data/asan/system/${LIB}/vndk-sp:/system/${LIB}/vndk-sp:/data/asan/system/${LIB}:/system/${LIB}
diff --git a/rootdir/init.rc b/rootdir/init.rc
index def686b..acb0557 100644
--- a/rootdir/init.rc
+++ b/rootdir/init.rc
@@ -422,7 +422,6 @@
# For security reasons, /data/local/tmp should always be empty.
# Do not place files or directories in /data/local/tmp
mkdir /data/local/tmp 0771 shell shell
- mkdir /data/data 0771 system system
mkdir /data/app-private 0771 system system
mkdir /data/app-ephemeral 0771 system system
mkdir /data/app-asec 0700 root root
@@ -475,7 +474,8 @@
mkdir /data/user 0711 system system
mkdir /data/user_de 0711 system system
- symlink /data/data /data/user/0
+ mkdir /data/user/0 0711 system system
+ symlink /data/user/0 /data/data
mkdir /data/media 0770 media_rw media_rw
mkdir /data/media/obb 0770 media_rw media_rw