Merge "ueventd: do not reference init's sehandle"
diff --git a/adb/Android.mk b/adb/Android.mk
index d17b063..112bc80 100644
--- a/adb/Android.mk
+++ b/adb/Android.mk
@@ -363,6 +363,7 @@
LOCAL_STRIP_MODULE := keep_symbols
LOCAL_STATIC_LIBRARIES := \
libadbd \
+ libavb_user \
libbase \
libbootloader_message \
libfs_mgr \
diff --git a/adb/adb_auth_host.cpp b/adb/adb_auth_host.cpp
index c3f1fe0..365bf77 100644
--- a/adb/adb_auth_host.cpp
+++ b/adb/adb_auth_host.cpp
@@ -82,16 +82,17 @@
return false;
}
- size_t base64_key_length;
- if (!EVP_EncodedLength(&base64_key_length, sizeof(binary_key_data))) {
+ size_t expected_length;
+ if (!EVP_EncodedLength(&expected_length, sizeof(binary_key_data))) {
LOG(ERROR) << "Public key too large to base64 encode";
return false;
}
std::string content;
- content.resize(base64_key_length);
- base64_key_length = EVP_EncodeBlock(reinterpret_cast<uint8_t*>(&content[0]), binary_key_data,
- sizeof(binary_key_data));
+ content.resize(expected_length);
+ size_t actual_length = EVP_EncodeBlock(reinterpret_cast<uint8_t*>(&content[0]), binary_key_data,
+ sizeof(binary_key_data));
+ content.resize(actual_length);
content += get_user_info();
diff --git a/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/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/set_verity_enable_state_service.cpp b/adb/set_verity_enable_state_service.cpp
index d4dd256..b2b1c18 100644
--- a/adb/set_verity_enable_state_service.cpp
+++ b/adb/set_verity_enable_state_service.cpp
@@ -20,6 +20,7 @@
#include <fcntl.h>
#include <inttypes.h>
+#include <libavb_user/libavb_user.h>
#include <stdarg.h>
#include <stdio.h>
#include <sys/stat.h>
@@ -45,13 +46,12 @@
#endif
/* Turn verity on/off */
-static int set_verity_enabled_state(int fd, const char *block_device,
- const char* mount_point, bool enable)
-{
+static bool set_verity_enabled_state(int fd, const char* block_device, const char* mount_point,
+ bool enable) {
if (!make_block_device_writable(block_device)) {
WriteFdFmt(fd, "Could not make block device %s writable (%s).\n",
block_device, strerror(errno));
- return -1;
+ return false;
}
fec::io fh(block_device, O_RDWR);
@@ -59,39 +59,84 @@
if (!fh) {
WriteFdFmt(fd, "Could not open block device %s (%s).\n", block_device, strerror(errno));
WriteFdFmt(fd, "Maybe run adb root?\n");
- return -1;
+ return false;
}
fec_verity_metadata metadata;
if (!fh.get_verity_metadata(metadata)) {
WriteFdFmt(fd, "Couldn't find verity metadata!\n");
- return -1;
+ return false;
}
if (!enable && metadata.disabled) {
WriteFdFmt(fd, "Verity already disabled on %s\n", mount_point);
- return -1;
+ return false;
}
if (enable && !metadata.disabled) {
WriteFdFmt(fd, "Verity already enabled on %s\n", mount_point);
- return -1;
+ return false;
}
if (!fh.set_verity_status(enable)) {
WriteFdFmt(fd, "Could not set verity %s flag on device %s with error %s\n",
enable ? "enabled" : "disabled",
block_device, strerror(errno));
- return -1;
+ return false;
}
WriteFdFmt(fd, "Verity %s on %s\n", enable ? "enabled" : "disabled", mount_point);
- return 0;
+ return true;
+}
+
+/* Helper function to get A/B suffix, if any. If the device isn't
+ * using A/B the empty string is returned. Otherwise either "_a",
+ * "_b", ... is returned.
+ *
+ * Note that since sometime in O androidboot.slot_suffix is deprecated
+ * and androidboot.slot should be used instead. Since bootloaders may
+ * be out of sync with the OS, we check both and for extra safety
+ * prepend a leading underscore if there isn't one already.
+ */
+static std::string get_ab_suffix() {
+ std::string ab_suffix = android::base::GetProperty("ro.boot.slot_suffix", "");
+ if (ab_suffix == "") {
+ ab_suffix = android::base::GetProperty("ro.boot.slot", "");
+ }
+ if (ab_suffix.size() > 0 && ab_suffix[0] != '_') {
+ ab_suffix = std::string("_") + ab_suffix;
+ }
+ return ab_suffix;
+}
+
+/* Use AVB to turn verity on/off */
+static bool set_avb_verity_enabled_state(int fd, AvbOps* ops, bool enable_verity) {
+ std::string ab_suffix = get_ab_suffix();
+
+ bool verity_enabled;
+ if (!avb_user_verity_get(ops, ab_suffix.c_str(), &verity_enabled)) {
+ WriteFdFmt(fd, "Error getting verity state\n");
+ return false;
+ }
+
+ if ((verity_enabled && enable_verity) || (!verity_enabled && !enable_verity)) {
+ WriteFdFmt(fd, "verity is already %s\n", verity_enabled ? "enabled" : "disabled");
+ return false;
+ }
+
+ if (!avb_user_verity_set(ops, ab_suffix.c_str(), enable_verity)) {
+ WriteFdFmt(fd, "Error setting verity\n");
+ return false;
+ }
+
+ WriteFdFmt(fd, "Successfully %s verity\n", enable_verity ? "enabled" : "disabled");
+ return true;
}
void set_verity_enabled_state_service(int fd, void* cookie) {
unique_fd closer(fd);
+ bool any_changed = false;
bool enable = (cookie != NULL);
if (!kAllowDisableVerity) {
@@ -108,21 +153,37 @@
return;
}
- // read all fstab entries at once from all sources
- fstab = fs_mgr_read_fstab_default();
- if (!fstab) {
- WriteFdFmt(fd, "Failed to read fstab\nMaybe run adb root?\n");
- return;
- }
+ // Figure out if we're using VB1.0 or VB2.0 (aka AVB).
+ std::string vbmeta_hash = android::base::GetProperty("ro.boot.vbmeta.digest", "");
+ if (vbmeta_hash != "") {
+ // Yep, the system is using AVB (by contract, androidboot.vbmeta.hash is
+ // set by the bootloader when using AVB).
+ AvbOps* ops = avb_ops_user_new();
+ if (ops == nullptr) {
+ WriteFdFmt(fd, "Error getting AVB ops\n");
+ return;
+ }
+ if (set_avb_verity_enabled_state(fd, ops, enable)) {
+ any_changed = true;
+ }
+ avb_ops_user_free(ops);
+ } else {
+ // Not using AVB - assume VB1.0.
- // Loop through entries looking for ones that vold manages.
- bool any_changed = false;
- for (int i = 0; i < fstab->num_entries; i++) {
- if (fs_mgr_is_verified(&fstab->recs[i])) {
- if (!set_verity_enabled_state(fd, fstab->recs[i].blk_device,
- fstab->recs[i].mount_point,
- enable)) {
- any_changed = true;
+ // read all fstab entries at once from all sources
+ fstab = fs_mgr_read_fstab_default();
+ if (!fstab) {
+ WriteFdFmt(fd, "Failed to read fstab\nMaybe run adb root?\n");
+ return;
+ }
+
+ // Loop through entries looking for ones that vold manages.
+ for (int i = 0; i < fstab->num_entries; i++) {
+ if (fs_mgr_is_verified(&fstab->recs[i])) {
+ if (set_verity_enabled_state(fd, fstab->recs[i].blk_device,
+ fstab->recs[i].mount_point, enable)) {
+ any_changed = true;
+ }
}
}
}
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/fs_mgr/fs_mgr_avb_ops.cpp b/fs_mgr/fs_mgr_avb_ops.cpp
index edcfd54..caee4ec 100644
--- a/fs_mgr/fs_mgr_avb_ops.cpp
+++ b/fs_mgr/fs_mgr_avb_ops.cpp
@@ -96,7 +96,9 @@
// We only need to provide the implementation of read_from_partition()
// operation since that's all what is being used by the avb_slot_verify().
// Other I/O operations are only required in bootloader but not in
- // user-space so we set them as dummy operations.
+ // user-space so we set them as dummy operations. Also zero the entire
+ // struct so operations added in the future will be set to NULL.
+ memset(&avb_ops_, 0, sizeof(AvbOps));
avb_ops_.read_from_partition = read_from_partition;
avb_ops_.read_rollback_index = dummy_read_rollback_index;
avb_ops_.validate_vbmeta_public_key = dummy_validate_vbmeta_public_key;
diff --git a/init/Android.mk b/init/Android.mk
index de3d076..537bbee 100644
--- a/init/Android.mk
+++ b/init/Android.mk
@@ -145,6 +145,7 @@
init_parser_test.cpp \
init_test.cpp \
property_service_test.cpp \
+ service_test.cpp \
util_test.cpp \
LOCAL_SHARED_LIBRARIES += \
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/service.cpp b/init/service.cpp
index 39f6709..3a9f622 100644
--- a/init/service.cpp
+++ b/init/service.cpp
@@ -158,6 +158,7 @@
namespace_flags_(0),
seclabel_(""),
onrestart_(false, "<Service '" + name + "' onrestart>", 0),
+ keychord_id_(0),
ioprio_class_(IoSchedClass_NONE),
ioprio_pri_(0),
priority_(0),
@@ -182,6 +183,7 @@
namespace_flags_(namespace_flags),
seclabel_(seclabel),
onrestart_(false, "<Service '" + name + "' onrestart>", 0),
+ keychord_id_(0),
ioprio_class_(IoSchedClass_NONE),
ioprio_pri_(0),
priority_(0),
diff --git a/init/service.h b/init/service.h
index 634fe4e..426577f 100644
--- a/init/service.h
+++ b/init/service.h
@@ -94,14 +94,19 @@
const std::set<std::string>& classnames() const { return classnames_; }
unsigned flags() const { return flags_; }
pid_t pid() const { return pid_; }
+ int crash_count() const { return crash_count_; }
uid_t uid() const { return uid_; }
gid_t gid() const { return gid_; }
- int priority() const { return priority_; }
+ unsigned namespace_flags() const { return namespace_flags_; }
const std::vector<gid_t>& supp_gids() const { return supp_gids_; }
const std::string& seclabel() const { return seclabel_; }
const std::vector<int>& keycodes() const { return keycodes_; }
int keychord_id() const { return keychord_id_; }
void set_keychord_id(int keychord_id) { keychord_id_ = keychord_id; }
+ IoSchedClass ioprio_class() const { return ioprio_class_; }
+ int ioprio_pri() const { return ioprio_pri_; }
+ int priority() const { return priority_; }
+ int oom_score_adjust() const { return oom_score_adjust_; }
const std::vector<std::string>& args() const { return args_; }
private:
@@ -181,6 +186,9 @@
public:
static ServiceManager& GetInstance();
+ // Exposed for testing
+ ServiceManager();
+
void AddService(std::unique_ptr<Service> service);
Service* MakeExecOneshotService(const std::vector<std::string>& args);
bool Exec(const std::vector<std::string>& args);
@@ -199,8 +207,6 @@
void DumpState() const;
private:
- ServiceManager();
-
// Cleans up a child process that exited.
// Returns true iff a children was cleaned up.
bool ReapOneProcess();
diff --git a/init/service_test.cpp b/init/service_test.cpp
new file mode 100644
index 0000000..4493f25
--- /dev/null
+++ b/init/service_test.cpp
@@ -0,0 +1,67 @@
+/*
+ * 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.
+ */
+
+#include "service.h"
+
+#include <algorithm>
+#include <memory>
+#include <type_traits>
+#include <vector>
+
+#include <gtest/gtest.h>
+
+TEST(service, pod_initialized) {
+ constexpr auto memory_size = sizeof(Service);
+ alignas(alignof(Service)) char old_memory[memory_size];
+
+ for (std::size_t i = 0; i < memory_size; ++i) {
+ old_memory[i] = 0xFF;
+ }
+
+ std::vector<std::string> dummy_args{"/bin/test"};
+ Service* service_in_old_memory = new (old_memory) Service("test_old_memory", dummy_args);
+
+ EXPECT_EQ(0U, service_in_old_memory->flags());
+ EXPECT_EQ(0, service_in_old_memory->pid());
+ EXPECT_EQ(0, service_in_old_memory->crash_count());
+ EXPECT_EQ(0U, service_in_old_memory->uid());
+ EXPECT_EQ(0U, service_in_old_memory->gid());
+ EXPECT_EQ(0U, service_in_old_memory->namespace_flags());
+ EXPECT_EQ(0, service_in_old_memory->keychord_id());
+ EXPECT_EQ(IoSchedClass_NONE, service_in_old_memory->ioprio_class());
+ EXPECT_EQ(0, service_in_old_memory->ioprio_pri());
+ EXPECT_EQ(0, service_in_old_memory->priority());
+ EXPECT_EQ(-1000, service_in_old_memory->oom_score_adjust());
+
+ for (std::size_t i = 0; i < memory_size; ++i) {
+ old_memory[i] = 0xFF;
+ }
+
+ Service* service_in_old_memory2 = new (old_memory)
+ Service("test_old_memory", 0U, 0U, 0U, std::vector<gid_t>(), CapSet(), 0U, "", dummy_args);
+
+ EXPECT_EQ(0U, service_in_old_memory2->flags());
+ EXPECT_EQ(0, service_in_old_memory2->pid());
+ EXPECT_EQ(0, service_in_old_memory2->crash_count());
+ EXPECT_EQ(0U, service_in_old_memory2->uid());
+ EXPECT_EQ(0U, service_in_old_memory2->gid());
+ EXPECT_EQ(0U, service_in_old_memory2->namespace_flags());
+ EXPECT_EQ(0, service_in_old_memory2->keychord_id());
+ EXPECT_EQ(IoSchedClass_NONE, service_in_old_memory2->ioprio_class());
+ EXPECT_EQ(0, service_in_old_memory2->ioprio_pri());
+ EXPECT_EQ(0, service_in_old_memory2->priority());
+ EXPECT_EQ(-1000, service_in_old_memory2->oom_score_adjust());
+}
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 86%
rename from libcutils/fs_config.c
rename to libcutils/fs_config.cpp
index e4541f7..a2dd677 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,17 +186,17 @@
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/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" },
@@ -208,7 +204,7 @@
CAP_MASK_LONG(CAP_SYS_NICE),
"vendor/bin/hw/android.hardware.bluetooth@1.0-service" },
- /* Support wifi_hal_legacy administering a network interface. */
+ // 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" },
@@ -216,8 +212,7 @@
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),
@@ -227,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*" },
@@ -241,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[]) {
@@ -254,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, "/");
@@ -278,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);
}
@@ -314,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;
@@ -325,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/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/Android.mk b/logd/Android.mk
index 9211037..fb51992 100644
--- a/logd/Android.mk
+++ b/logd/Android.mk
@@ -2,12 +2,9 @@
include $(CLEAR_VARS)
-LOCAL_MODULE:= logd
-
-LOCAL_INIT_RC := logd.rc
+LOCAL_MODULE:= liblogd
LOCAL_SRC_FILES := \
- main.cpp \
LogCommand.cpp \
CommandListener.cpp \
LogListener.cpp \
@@ -15,6 +12,7 @@
FlushCommand.cpp \
LogBuffer.cpp \
LogBufferElement.cpp \
+ LogBufferInterface.cpp \
LogTimes.cpp \
LogStatistics.cpp \
LogWhiteBlackList.cpp \
@@ -25,12 +23,9 @@
event.logtags
LOCAL_SHARED_LIBRARIES := \
- libsysutils \
- liblog \
- libcutils \
- libbase \
- libpackagelistparser \
- libcap
+ libbase
+
+LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)
# This is what we want to do:
# event_logtags = $(shell \
@@ -46,6 +41,30 @@
LOCAL_CFLAGS := -Werror $(event_flag)
+include $(BUILD_STATIC_LIBRARY)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE:= logd
+
+LOCAL_INIT_RC := logd.rc
+
+LOCAL_SRC_FILES := \
+ main.cpp
+
+LOCAL_STATIC_LIBRARIES := \
+ liblogd
+
+LOCAL_SHARED_LIBRARIES := \
+ libsysutils \
+ liblog \
+ libcutils \
+ libbase \
+ libpackagelistparser \
+ libcap
+
+LOCAL_CFLAGS := -Werror
+
include $(BUILD_EXECUTABLE)
include $(CLEAR_VARS)
diff --git a/logd/LogBuffer.h b/logd/LogBuffer.h
index 51edd86..e597754 100644
--- a/logd/LogBuffer.h
+++ b/logd/LogBuffer.h
@@ -27,6 +27,7 @@
#include <sysutils/SocketClient.h>
#include "LogBufferElement.h"
+#include "LogBufferInterface.h"
#include "LogStatistics.h"
#include "LogTags.h"
#include "LogTimes.h"
@@ -74,7 +75,7 @@
typedef std::list<LogBufferElement*> LogBufferElementCollection;
-class LogBuffer {
+class LogBuffer : public LogBufferInterface {
LogBufferElementCollection mLogElements;
pthread_rwlock_t mLogElementsLock;
@@ -107,14 +108,14 @@
LastLogTimes& mTimes;
explicit LogBuffer(LastLogTimes* times);
- ~LogBuffer();
+ ~LogBuffer() override;
void init();
bool isMonotonic() {
return monotonic;
}
int log(log_id_t log_id, log_time realtime, uid_t uid, pid_t pid, pid_t tid,
- const char* msg, unsigned short len);
+ const char* msg, unsigned short len) override;
// lastTid is an optional context to help detect if the last previous
// valid message was from the same source so we can differentiate chatty
// filter types (identical or expired)
diff --git a/logd/LogBufferInterface.cpp b/logd/LogBufferInterface.cpp
new file mode 100644
index 0000000..3cb2b89
--- /dev/null
+++ b/logd/LogBufferInterface.cpp
@@ -0,0 +1,22 @@
+/*
+ * 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.
+ */
+
+#include "LogBufferInterface.h"
+
+LogBufferInterface::LogBufferInterface() {
+}
+LogBufferInterface::~LogBufferInterface() {
+}
\ No newline at end of file
diff --git a/logd/LogBufferInterface.h b/logd/LogBufferInterface.h
new file mode 100644
index 0000000..7d82b91
--- /dev/null
+++ b/logd/LogBufferInterface.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2012-2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _LOGD_LOG_BUFFER_INTERFACE_H__
+#define _LOGD_LOG_BUFFER_INTERFACE_H__
+
+#include <sys/types.h>
+
+#include <android-base/macros.h>
+#include <log/log_id.h>
+#include <log/log_time.h>
+
+// Abstract interface that handles log when log available.
+class LogBufferInterface {
+ public:
+ LogBufferInterface();
+ virtual ~LogBufferInterface();
+ // Handles a log entry when available in LogListener.
+ // Returns the size of the handled log message.
+ virtual int log(log_id_t log_id, log_time realtime, uid_t uid, pid_t pid,
+ pid_t tid, const char* msg, unsigned short len) = 0;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(LogBufferInterface);
+};
+
+#endif // _LOGD_LOG_BUFFER_INTERFACE_H__
diff --git a/logd/LogListener.cpp b/logd/LogListener.cpp
index dadc75f..709646e 100644
--- a/logd/LogListener.cpp
+++ b/logd/LogListener.cpp
@@ -30,7 +30,7 @@
#include "LogListener.h"
#include "LogUtils.h"
-LogListener::LogListener(LogBuffer* buf, LogReader* reader)
+LogListener::LogListener(LogBufferInterface* buf, LogReader* reader)
: SocketListener(getLogSocket(), false), logbuf(buf), reader(reader) {
}
@@ -102,11 +102,14 @@
// NB: hdr.msg_flags & MSG_TRUNC is not tested, silently passing a
// truncated message to the logs.
- if (logbuf->log((log_id_t)header->id, header->realtime, cred->uid,
- cred->pid, header->tid, msg,
- ((size_t)n <= USHRT_MAX) ? (unsigned short)n : USHRT_MAX) >=
- 0) {
- reader->notifyNewLog();
+ if (logbuf != nullptr) {
+ int res = logbuf->log(
+ (log_id_t)header->id, header->realtime, cred->uid, cred->pid,
+ header->tid, msg,
+ ((size_t)n <= USHRT_MAX) ? (unsigned short)n : USHRT_MAX);
+ if (res > 0 && reader != nullptr) {
+ reader->notifyNewLog();
+ }
}
return true;
diff --git a/logd/LogListener.h b/logd/LogListener.h
index 2973b8b..e16c5fb 100644
--- a/logd/LogListener.h
+++ b/logd/LogListener.h
@@ -21,11 +21,11 @@
#include "LogReader.h"
class LogListener : public SocketListener {
- LogBuffer* logbuf;
+ LogBufferInterface* logbuf;
LogReader* reader;
public:
- LogListener(LogBuffer* buf, LogReader* reader);
+ LogListener(LogBufferInterface* buf, LogReader* reader /* nullable */);
protected:
virtual bool onDataAvailable(SocketClient* cli);