Merge "Allow building with Python 3.x"
diff --git a/adb/Android.mk b/adb/Android.mk
index e0997ea..2dba41d 100644
--- a/adb/Android.mk
+++ b/adb/Android.mk
@@ -79,10 +79,12 @@
LIBADB_darwin_SRC_FILES := \
get_my_path_darwin.cpp \
+ sysdeps_unix.cpp \
usb_osx.cpp \
LIBADB_linux_SRC_FILES := \
get_my_path_linux.cpp \
+ sysdeps_unix.cpp \
usb_linux.cpp \
LIBADB_windows_SRC_FILES := \
@@ -99,7 +101,6 @@
LOCAL_SRC_FILES := \
$(LIBADB_SRC_FILES) \
adb_auth_client.cpp \
- fdevent.cpp \
jdwp_service.cpp \
usb_linux_client.cpp \
diff --git a/adb/adb_auth_client.cpp b/adb/adb_auth_client.cpp
index c4ffc85..128c3df 100644
--- a/adb/adb_auth_client.cpp
+++ b/adb/adb_auth_client.cpp
@@ -44,6 +44,7 @@
};
static fdevent listener_fde;
+static fdevent framework_fde;
static int framework_fd = -1;
static void usb_disconnected(void* unused, atransport* t);
@@ -161,29 +162,30 @@
return ret;
}
-static void usb_disconnected(void* unused, atransport* t)
-{
+static void usb_disconnected(void* unused, atransport* t) {
D("USB disconnect");
usb_transport = NULL;
needs_retry = false;
}
-static void adb_auth_event(int fd, unsigned events, void *data)
-{
+static void framework_disconnected() {
+ D("Framework disconnect");
+ fdevent_remove(&framework_fde);
+ framework_fd = -1;
+}
+
+static void adb_auth_event(int fd, unsigned events, void*) {
char response[2];
int ret;
if (events & FDE_READ) {
ret = unix_read(fd, response, sizeof(response));
if (ret <= 0) {
- D("Framework disconnect");
- if (usb_transport)
- fdevent_remove(&usb_transport->auth_fde);
- framework_fd = -1;
- }
- else if (ret == 2 && response[0] == 'O' && response[1] == 'K') {
- if (usb_transport)
+ framework_disconnected();
+ } else if (ret == 2 && response[0] == 'O' && response[1] == 'K') {
+ if (usb_transport) {
adb_auth_verified(usb_transport);
+ }
}
}
}
@@ -221,13 +223,9 @@
D("Failed to write PK, errno=%d", errno);
return;
}
-
- fdevent_install(&t->auth_fde, framework_fd, adb_auth_event, t);
- fdevent_add(&t->auth_fde, FDE_READ);
}
-static void adb_auth_listener(int fd, unsigned events, void *data)
-{
+static void adb_auth_listener(int fd, unsigned events, void* data) {
sockaddr_storage addr;
socklen_t alen;
int s;
@@ -240,7 +238,14 @@
return;
}
+ if (framework_fd >= 0) {
+ LOG(WARNING) << "adb received framework auth socket connection again";
+ framework_disconnected();
+ }
+
framework_fd = s;
+ fdevent_install(&framework_fde, framework_fd, adb_auth_event, nullptr);
+ fdevent_add(&framework_fde, FDE_READ);
if (needs_retry) {
needs_retry = false;
diff --git a/adb/commandline.cpp b/adb/commandline.cpp
index 8e76168..37d1146 100644
--- a/adb/commandline.cpp
+++ b/adb/commandline.cpp
@@ -1106,8 +1106,9 @@
}
fprintf(stderr,"- waiting for device -\n");
- adb_sleep_ms(1000);
- wait_for_device("wait-for-device", transport_type, serial);
+ if (!wait_for_device("wait-for-device", transport_type, serial)) {
+ return 1;
+ }
}
int exit_code = read_and_dump(fd, use_shell_protocol);
diff --git a/adb/daemon/main.cpp b/adb/daemon/main.cpp
index 4721e2f..7f40b96 100644
--- a/adb/daemon/main.cpp
+++ b/adb/daemon/main.cpp
@@ -43,24 +43,15 @@
static const char* root_seclabel = nullptr;
-static void drop_capabilities_bounding_set_if_needed() {
-#ifdef ALLOW_ADBD_ROOT
+static void drop_capabilities_bounding_set_if_needed(struct minijail *j) {
+#if defined(ALLOW_ADBD_ROOT)
char value[PROPERTY_VALUE_MAX];
property_get("ro.debuggable", value, "");
if (strcmp(value, "1") == 0) {
return;
}
#endif
- for (int i = 0; prctl(PR_CAPBSET_READ, i, 0, 0, 0) >= 0; i++) {
- if (i == CAP_SETUID || i == CAP_SETGID) {
- // CAP_SETUID CAP_SETGID needed by /system/bin/run-as
- continue;
- }
-
- if (prctl(PR_CAPBSET_DROP, i, 0, 0, 0) == -1) {
- PLOG(FATAL) << "Could not drop capabilities";
- }
- }
+ minijail_capbset_drop(j, CAP_TO_MASK(CAP_SETUID) | CAP_TO_MASK(CAP_SETGID));
}
static bool should_drop_privileges() {
@@ -131,7 +122,7 @@
// Don't listen on a port (default 5037) if running in secure mode.
// Don't run as root if running in secure mode.
if (should_drop_privileges()) {
- drop_capabilities_bounding_set_if_needed();
+ drop_capabilities_bounding_set_if_needed(jail.get());
minijail_change_gid(jail.get(), AID_SHELL);
minijail_change_uid(jail.get(), AID_SHELL);
diff --git a/adb/file_sync_client.cpp b/adb/file_sync_client.cpp
index 85aaa61..3a81ce6 100644
--- a/adb/file_sync_client.cpp
+++ b/adb/file_sync_client.cpp
@@ -517,12 +517,6 @@
if (!sc.SendRequest(ID_RECV, rpath)) return false;
adb_unlink(lpath);
- const std::string dirpath = adb_dirname(lpath);
- if (!mkdirs(dirpath.c_str())) {
- sc.Error("failed to create parent directory '%s': %s", dirpath.c_str(), strerror(errno));
- return false;
- }
-
int lfd = adb_creat(lpath, 0644);
if (lfd < 0) {
sc.Error("cannot create '%s': %s", lpath, strerror(errno));
@@ -803,13 +797,14 @@
return S_ISDIR(mode);
}
-static bool remote_build_list(SyncConnection& sc,
- std::vector<copyinfo>* file_list,
- const std::string& rpath,
- const std::string& lpath) {
+static bool remote_build_list(SyncConnection& sc, std::vector<copyinfo>* file_list,
+ const std::string& rpath, const std::string& lpath) {
std::vector<copyinfo> dirlist;
std::vector<copyinfo> linklist;
- bool empty_dir = true;
+
+ // Add an entry for the current directory to ensure it gets created before pulling its contents.
+ copyinfo ci(adb_dirname(lpath), adb_dirname(rpath), adb_basename(rpath), S_IFDIR);
+ file_list->push_back(ci);
// Put the files/dirs in rpath on the lists.
auto callback = [&](unsigned mode, unsigned size, unsigned time, const char* name) {
@@ -817,9 +812,6 @@
return;
}
- // We found a child that isn't '.' or '..'.
- empty_dir = false;
-
copyinfo ci(lpath, rpath, name, mode);
if (S_ISDIR(mode)) {
dirlist.push_back(ci);
@@ -836,13 +828,6 @@
return false;
}
- // Add the current directory to the list if it was empty, to ensure that it gets created.
- if (empty_dir) {
- copyinfo ci(adb_dirname(lpath), adb_dirname(rpath), adb_basename(rpath), S_IFDIR);
- file_list->push_back(ci);
- return true;
- }
-
// Check each symlink we found to see whether it's a file or directory.
for (copyinfo& link_ci : linklist) {
if (remote_symlink_isdir(sc, link_ci.rpath)) {
diff --git a/adb/services.cpp b/adb/services.cpp
index 2eef1c2..d5e963b 100644
--- a/adb/services.cpp
+++ b/adb/services.cpp
@@ -421,6 +421,11 @@
close_on_exec(fd);
disable_tcp_nagle(fd);
+ // Send a TCP keepalive ping to the device every second so we can detect disconnects.
+ if (!set_tcp_keepalive(fd, 1)) {
+ D("warning: failed to configure TCP keepalives (%s)", strerror(errno));
+ }
+
int ret = register_socket_transport(fd, serial.c_str(), port, 0);
if (ret < 0) {
adb_close(fd);
diff --git a/adb/sysdeps.h b/adb/sysdeps.h
index 7af2979..ce0f289 100644
--- a/adb/sysdeps.h
+++ b/adb/sysdeps.h
@@ -841,4 +841,9 @@
adb_setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &off, sizeof(off));
}
+// Sets TCP socket |fd| to send a keepalive TCP message every |interval_sec| seconds. Set
+// |interval_sec| to 0 to disable keepalives. If keepalives are enabled, the connection will be
+// configured to drop after 10 missed keepalives. Returns true on success.
+bool set_tcp_keepalive(int fd, int interval_sec);
+
#endif /* _ADB_SYSDEPS_H */
diff --git a/adb/sysdeps_unix.cpp b/adb/sysdeps_unix.cpp
new file mode 100644
index 0000000..4445a44
--- /dev/null
+++ b/adb/sysdeps_unix.cpp
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2016 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 "sysdeps.h"
+
+bool set_tcp_keepalive(int fd, int interval_sec) {
+ int enable = (interval_sec > 0);
+ if (adb_setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, &enable, sizeof(enable))) {
+ return false;
+ }
+
+ if (!enable) {
+ return true;
+ }
+
+ // Idle time before sending the first keepalive is TCP_KEEPIDLE on Linux, TCP_KEEPALIVE on Mac.
+#if defined(TCP_KEEPIDLE)
+ if (adb_setsockopt(fd, IPPROTO_TCP, TCP_KEEPIDLE, &interval_sec, sizeof(interval_sec))) {
+ return false;
+ }
+#elif defined(TCP_KEEPALIVE)
+ if (adb_setsockopt(fd, IPPROTO_TCP, TCP_KEEPALIVE, &interval_sec, sizeof(interval_sec))) {
+ return false;
+ }
+#endif
+
+ // TCP_KEEPINTVL and TCP_KEEPCNT are available on Linux 2.4+ and OS X 10.8+ (Mountain Lion).
+#if defined(TCP_KEEPINTVL)
+ if (adb_setsockopt(fd, IPPROTO_TCP, TCP_KEEPINTVL, &interval_sec, sizeof(interval_sec))) {
+ return false;
+ }
+#endif
+
+#if defined(TCP_KEEPCNT)
+ // On Windows this value is hardcoded to 10. This is a reasonable value, so we do the same here
+ // to match behavior. See SO_KEEPALIVE documentation at
+ // https://msdn.microsoft.com/en-us/library/windows/desktop/ee470551(v=vs.85).aspx.
+ const int keepcnt = 10;
+ if (adb_setsockopt(fd, IPPROTO_TCP, TCP_KEEPCNT, &keepcnt, sizeof(keepcnt))) {
+ return false;
+ }
+#endif
+
+ return true;
+}
diff --git a/adb/sysdeps_win32.cpp b/adb/sysdeps_win32.cpp
index 7eae186..a2f34fb 100644
--- a/adb/sysdeps_win32.cpp
+++ b/adb/sysdeps_win32.cpp
@@ -1228,6 +1228,33 @@
}
}
+bool set_tcp_keepalive(int fd, int interval_sec) {
+ FH fh = _fh_from_int(fd, __func__);
+
+ if (!fh || fh->clazz != &_fh_socket_class) {
+ D("set_tcp_keepalive(%d) failed: invalid fd", fd);
+ errno = EBADF;
+ return false;
+ }
+
+ tcp_keepalive keepalive;
+ keepalive.onoff = (interval_sec > 0);
+ keepalive.keepalivetime = interval_sec * 1000;
+ keepalive.keepaliveinterval = interval_sec * 1000;
+
+ DWORD bytes_returned = 0;
+ if (WSAIoctl(fh->fh_socket, SIO_KEEPALIVE_VALS, &keepalive, sizeof(keepalive), nullptr, 0,
+ &bytes_returned, nullptr, nullptr) != 0) {
+ const DWORD err = WSAGetLastError();
+ D("set_tcp_keepalive(%d) failed: %s", fd,
+ android::base::SystemErrorCodeToString(err).c_str());
+ _socket_set_errno(err);
+ return false;
+ }
+
+ return true;
+}
+
static adb_mutex_t g_console_output_buffer_lock;
void
diff --git a/adb/transport.h b/adb/transport.h
index 76d6afa..4c0c008 100644
--- a/adb/transport.h
+++ b/adb/transport.h
@@ -50,7 +50,6 @@
// it's better to do this piece by piece.
atransport() {
- auth_fde = {};
transport_fde = {};
protocol_version = A_VERSION;
max_payload = MAX_PAYLOAD;
@@ -87,7 +86,6 @@
void* key = nullptr;
unsigned char token[TOKEN_SIZE] = {};
- fdevent auth_fde;
size_t failed_auth_attempts = 0;
const std::string connection_state_name() const;
diff --git a/adb/transport_test.cpp b/adb/transport_test.cpp
index 97fc069..1bdea2a 100644
--- a/adb/transport_test.cpp
+++ b/adb/transport_test.cpp
@@ -53,7 +53,6 @@
EXPECT_EQ(key, rhs.key);
EXPECT_EQ(0, memcmp(token, rhs.token, TOKEN_SIZE));
- EXPECT_EQ(0, memcmp(&auth_fde, &rhs.auth_fde, sizeof(fdevent)));
EXPECT_EQ(failed_auth_attempts, rhs.failed_auth_attempts);
EXPECT_EQ(features(), rhs.features());
diff --git a/bootstat/README.md b/bootstat/README.md
index b3964ce..76ea6c1 100644
--- a/bootstat/README.md
+++ b/bootstat/README.md
@@ -12,6 +12,7 @@
-p, --print Dump the boot event records to the console
-r, --record Record the timestamp of a named boot event
--record_boot_reason Record the reason why the device booted
+ --record_time_since_factory_reset Record the time since the device was reset
## Relative time ##
diff --git a/bootstat/bootstat.cpp b/bootstat/bootstat.cpp
index 0c49f82..c199190 100644
--- a/bootstat/bootstat.cpp
+++ b/bootstat/bootstat.cpp
@@ -80,7 +80,8 @@
" -l, --log Log all metrics to logstorage\n"
" -p, --print Dump the boot event records to the console\n"
" -r, --record Record the timestamp of a named boot event\n"
- " --record_boot_reason Record the reason why the device booted\n");
+ " --record_boot_reason Record the reason why the device booted\n"
+ " --record_time_since_factory_reset Record the time since the device was reset\n");
}
// Constructs a readable, printable string from the givencommand line
@@ -192,7 +193,7 @@
int option_index = 0;
static const char boot_reason_str[] = "record_boot_reason";
- static const char factory_reset_str[] = "record_factory_reset";
+ static const char factory_reset_str[] = "record_time_since_factory_reset";
static const struct option long_options[] = {
{ "help", no_argument, NULL, 'h' },
{ "log", no_argument, NULL, 'l' },
diff --git a/bootstat/bootstat.rc b/bootstat/bootstat.rc
index 218b9f8..13ef27e 100644
--- a/bootstat/bootstat.rc
+++ b/bootstat/bootstat.rc
@@ -13,5 +13,8 @@
# Record the boot reason.
exec - root root -- /system/bin/bootstat --record_boot_reason
+ # Record time since factory reset.
+ exec - root root -- /system/bin/bootstat --record_time_since_factory_reset
+
# Log all boot events.
exec - root root -- /system/bin/bootstat -l
diff --git a/crash_reporter/crash_collector.cc b/crash_reporter/crash_collector.cc
index b3fdcb4..31d9f0f 100644
--- a/crash_reporter/crash_collector.cc
+++ b/crash_reporter/crash_collector.cc
@@ -36,6 +36,7 @@
#include <base/strings/string_util.h>
#include <base/strings/stringprintf.h>
#include <brillo/key_value_store.h>
+#include <brillo/osrelease_reader.h>
#include <brillo/process.h>
namespace {
@@ -52,6 +53,11 @@
const char kUploadVarPrefix[] = "upload_var_";
const char kUploadFilePrefix[] = "upload_file_";
+// Product information keys in the /etc/os-release.d folder.
+static const char kBdkVersionKey[] = "bdk_version";
+static const char kProductIDKey[] = "product_id";
+static const char kProductVersionKey[] = "product_version";
+
// Normally this path is not used. Unfortunately, there are a few edge cases
// where we need this. Any process that runs as kDefaultUserName that crashes
// is consider a "user crash". That includes the initial Chrome browser that
@@ -384,14 +390,49 @@
const std::string &payload_path) {
int64_t payload_size = -1;
base::GetFileSize(FilePath(payload_path), &payload_size);
+
+ brillo::OsReleaseReader reader;
+ if (!forced_osreleased_directory_.empty()) {
+ reader.LoadTestingOnly(forced_osreleased_directory_);
+ } else {
+ reader.Load();
+ }
+ std::string bdk_version = "undefined";
+ std::string product_id = "undefined";
+ std::string product_version = "undefined";
+
+ if (!reader.GetString(kBdkVersionKey, &bdk_version)) {
+ LOG(ERROR) << "Could not read " << kBdkVersionKey
+ << " from /etc/os-release.d/";
+ }
+
+ if (!reader.GetString(kProductIDKey, &product_id)) {
+ LOG(ERROR) << "Could not read " << kProductIDKey
+ << " from /etc/os-release.d/";
+ }
+
+ if (!reader.GetString(kProductVersionKey, &product_version)) {
+ LOG(ERROR) << "Could not read " << kProductVersionKey
+ << " from /etc/os-release.d/";
+ }
+
std::string meta_data = StringPrintf("%sexec_name=%s\n"
"payload=%s\n"
"payload_size=%" PRId64 "\n"
+ "%s=%s\n"
+ "%s=%s\n"
+ "%s=%s\n"
"done=1\n",
extra_metadata_.c_str(),
exec_name.c_str(),
payload_path.c_str(),
- payload_size);
+ payload_size,
+ kBdkVersionKey,
+ bdk_version.c_str(),
+ kProductIDKey,
+ product_id.c_str(),
+ kProductVersionKey,
+ product_version.c_str());
// We must use WriteNewFile instead of base::WriteFile as we
// do not want to write with root access to a symlink that an attacker
// might have created.
diff --git a/crash_reporter/crash_collector.h b/crash_reporter/crash_collector.h
index 24cbfb3..21b9198 100644
--- a/crash_reporter/crash_collector.h
+++ b/crash_reporter/crash_collector.h
@@ -84,6 +84,12 @@
forced_crash_directory_ = forced_directory;
}
+ // For testing, set the root directory to read etc/os-release.d properties
+ // from.
+ void ForceOsReleaseDDirectory(const base::FilePath &forced_directory) {
+ forced_osreleased_directory_ = forced_directory;
+ }
+
base::FilePath GetCrashDirectoryInfo(mode_t *mode,
uid_t *directory_owner,
gid_t *directory_group);
@@ -158,6 +164,7 @@
IsFeedbackAllowedFunction is_feedback_allowed_function_;
std::string extra_metadata_;
base::FilePath forced_crash_directory_;
+ base::FilePath forced_osreleased_directory_;
base::FilePath log_config_path_;
private:
diff --git a/crash_reporter/crash_collector_test.cc b/crash_reporter/crash_collector_test.cc
index 11c8c0d..a386cd1 100644
--- a/crash_reporter/crash_collector_test.cc
+++ b/crash_reporter/crash_collector_test.cc
@@ -74,10 +74,11 @@
TEST_F(CrashCollectorTest, WriteNewFile) {
FilePath test_file = test_dir_.path().Append("test_new");
const char kBuffer[] = "buffer";
- EXPECT_EQ(strlen(kBuffer),
- collector_.WriteNewFile(test_file,
- kBuffer,
- strlen(kBuffer)));
+ unsigned int numBytesWritten = collector_.WriteNewFile(
+ test_file,
+ kBuffer,
+ strlen(kBuffer));
+ EXPECT_EQ(strlen(kBuffer), numBytesWritten);
EXPECT_LT(collector_.WriteNewFile(test_file,
kBuffer,
strlen(kBuffer)), 0);
@@ -94,7 +95,7 @@
}
TEST_F(CrashCollectorTest, FormatDumpBasename) {
- struct tm tm = {0};
+ struct tm tm = {};
tm.tm_sec = 15;
tm.tm_min = 50;
tm.tm_hour = 13;
@@ -182,9 +183,26 @@
const char kMetaFileBasename[] = "generated.meta";
FilePath meta_file = test_dir_.path().Append(kMetaFileBasename);
FilePath payload_file = test_dir_.path().Append("payload-file");
+ FilePath osreleased_directory =
+ test_dir_.path().Append("etc").Append("os-release.d");
+ ASSERT_TRUE(base::CreateDirectory(osreleased_directory));
+ collector_.ForceOsReleaseDDirectory(test_dir_.path());
+
std::string contents;
const char kPayload[] = "foo";
ASSERT_TRUE(base::WriteFile(payload_file, kPayload, strlen(kPayload)));
+ const char kBdkVersion[] = "1";
+ ASSERT_TRUE(base::WriteFile(osreleased_directory.Append("bdk_version"),
+ kBdkVersion,
+ strlen(kBdkVersion)));
+ const char kProductId[] = "baz";
+ ASSERT_TRUE(base::WriteFile(osreleased_directory.Append("product_id"),
+ kProductId,
+ strlen(kProductId)));
+ const char kProductVersion[] = "1.2.3.4";
+ ASSERT_TRUE(base::WriteFile(osreleased_directory.Append("product_version"),
+ kProductVersion,
+ strlen(kProductVersion)));
collector_.AddCrashMetaData("foo", "bar");
collector_.WriteCrashMetaData(meta_file, "kernel", payload_file.value());
EXPECT_TRUE(base::ReadFileToString(meta_file, &contents));
@@ -193,6 +211,9 @@
"exec_name=kernel\n"
"payload=%s\n"
"payload_size=3\n"
+ "bdk_version=1\n"
+ "product_id=baz\n"
+ "product_version=1.2.3.4\n"
"done=1\n",
test_dir_.path().Append("payload-file").value().c_str());
EXPECT_EQ(kExpectedMeta, contents);
diff --git a/crash_reporter/kernel_collector_test.cc b/crash_reporter/kernel_collector_test.cc
index 015f624..60fd832 100644
--- a/crash_reporter/kernel_collector_test.cc
+++ b/crash_reporter/kernel_collector_test.cc
@@ -49,7 +49,9 @@
protected:
void WriteStringToFile(const FilePath &file_path,
const char *data) {
- ASSERT_EQ(strlen(data), base::WriteFile(file_path, data, strlen(data)));
+ unsigned int numBytesWritten =
+ base::WriteFile(file_path, data, strlen(data));
+ ASSERT_EQ(strlen(data), numBytesWritten);
}
void SetUpSuccessfulCollect();
@@ -284,7 +286,7 @@
size_t end_pos = filename.find_first_of("\n");
ASSERT_NE(std::string::npos, end_pos);
filename = filename.substr(0, end_pos);
- ASSERT_EQ(0, filename.find(test_crash_directory().value()));
+ ASSERT_EQ(0U, filename.find(test_crash_directory().value()));
ASSERT_TRUE(base::PathExists(FilePath(filename)));
std::string contents;
ASSERT_TRUE(base::ReadFileToString(FilePath(filename), &contents));
diff --git a/crash_reporter/unclean_shutdown_collector_test.cc b/crash_reporter/unclean_shutdown_collector_test.cc
index 56d2704..36372ae 100644
--- a/crash_reporter/unclean_shutdown_collector_test.cc
+++ b/crash_reporter/unclean_shutdown_collector_test.cc
@@ -73,7 +73,9 @@
protected:
void WriteStringToFile(const FilePath &file_path,
const char *data) {
- ASSERT_EQ(strlen(data), base::WriteFile(file_path, data, strlen(data)));
+ unsigned int numBytesWritten =
+ base::WriteFile(file_path, data, strlen(data));
+ ASSERT_EQ(strlen(data), numBytesWritten);
}
UncleanShutdownCollectorMock collector_;
diff --git a/crash_reporter/user_collector.cc b/crash_reporter/user_collector.cc
index 98d7448..48b64e9 100644
--- a/crash_reporter/user_collector.cc
+++ b/crash_reporter/user_collector.cc
@@ -37,7 +37,6 @@
#include <base/strings/string_split.h>
#include <base/strings/string_util.h>
#include <base/strings/stringprintf.h>
-#include <brillo/osrelease_reader.h>
#include <brillo/process.h>
#include <brillo/syslog_logging.h>
#include <cutils/properties.h>
@@ -59,11 +58,6 @@
const char *UserCollector::kUserId = "Uid:\t";
const char *UserCollector::kGroupId = "Gid:\t";
-// Product information keys in the /etc/os-release.d folder.
-static const char kBdkVersionKey[] = "bdk_version";
-static const char kProductIDKey[] = "product_id";
-static const char kProductVersionKey[] = "product_version";
-
using base::FilePath;
using base::StringPrintf;
@@ -505,29 +499,6 @@
if (GetLogContents(FilePath(log_config_path_), exec, log_path))
AddCrashMetaData("log", log_path.value());
- brillo::OsReleaseReader reader;
- reader.Load();
- std::string value = "undefined";
- if (!reader.GetString(kBdkVersionKey, &value)) {
- LOG(ERROR) << "Could not read " << kBdkVersionKey
- << " from /etc/os-release.d/";
- }
- AddCrashMetaData(kBdkVersionKey, value);
-
- value = "undefined";
- if (!reader.GetString(kProductIDKey, &value)) {
- LOG(ERROR) << "Could not read " << kProductIDKey
- << " from /etc/os-release.d/";
- }
- AddCrashMetaData(kProductIDKey, value);
-
- value = "undefined";
- if (!reader.GetString(kProductVersionKey, &value)) {
- LOG(ERROR) << "Could not read " << kProductVersionKey
- << " from /etc/os-release.d/";
- }
- AddCrashMetaData(kProductVersionKey, value);
-
ErrorType error_type =
ConvertCoreToMinidump(pid, container_dir, core_path, minidump_path);
if (error_type != kErrorNone) {
diff --git a/crash_reporter/user_collector_test.cc b/crash_reporter/user_collector_test.cc
index d9c9a5b..16a5cd5 100644
--- a/crash_reporter/user_collector_test.cc
+++ b/crash_reporter/user_collector_test.cc
@@ -101,15 +101,15 @@
&pid, &signal, &uid, &gid, &exec_name));
EXPECT_EQ(123456, pid);
EXPECT_EQ(11, signal);
- EXPECT_EQ(1000, uid);
- EXPECT_EQ(2000, gid);
+ EXPECT_EQ(1000U, uid);
+ EXPECT_EQ(2000U, gid);
EXPECT_EQ("foobar", exec_name);
EXPECT_TRUE(collector_.ParseCrashAttributes("4321:6:barfoo",
&pid, &signal, &uid, &gid, &exec_name));
EXPECT_EQ(4321, pid);
EXPECT_EQ(6, signal);
- EXPECT_EQ(-1, uid);
- EXPECT_EQ(-1, gid);
+ EXPECT_EQ(-1U, uid);
+ EXPECT_EQ(-1U, gid);
EXPECT_EQ("barfoo", exec_name);
EXPECT_FALSE(collector_.ParseCrashAttributes("123456:11",
@@ -186,10 +186,10 @@
test_dir_.path().Append("test/this_link").value().c_str();
this_link.assign(long_link.c_str(), len);
ASSERT_EQ(len, this_link.size());
- unlink(kLink);
ASSERT_EQ(0, symlink(this_link.c_str(), kLink));
ASSERT_TRUE(collector_.GetSymlinkTarget(FilePath(kLink), &result));
ASSERT_EQ(this_link, result.value());
+ unlink(kLink);
}
}
@@ -333,8 +333,8 @@
gid_t gid = 100;
uid_t uid = 100;
EXPECT_TRUE(collector_.GetUserInfoFromName("root", &uid, &gid));
- EXPECT_EQ(0, uid);
- EXPECT_EQ(0, gid);
+ EXPECT_EQ(0U, uid);
+ EXPECT_EQ(0U, gid);
}
TEST_F(UserCollectorTest, CopyOffProcFilesBadPath) {
@@ -387,7 +387,9 @@
// maps file is not empty
const char data[] = "test data";
- ASSERT_EQ(sizeof(data), base::WriteFile(maps_file, data, sizeof(data)));
+ unsigned int numBytesWritten =
+ base::WriteFile(maps_file, data, sizeof(data));
+ ASSERT_EQ(sizeof(data), numBytesWritten);
ASSERT_TRUE(base::PathExists(maps_file));
EXPECT_TRUE(collector_.ValidateProcFiles(container_dir));
}
diff --git a/include/log/log.h b/include/log/log.h
index 6ad6f0a..e606a84 100644
--- a/include/log/log.h
+++ b/include/log/log.h
@@ -589,6 +589,8 @@
int android_log_write_int32(android_log_context ctx, int32_t value);
int android_log_write_int64(android_log_context ctx, int64_t value);
int android_log_write_string8(android_log_context ctx, const char *value);
+int android_log_write_string8_len(android_log_context ctx,
+ const char *value, size_t maxlen);
int android_log_write_float32(android_log_context ctx, float value);
/* Submit the composed list context to the specified logger id */
diff --git a/include/private/android_filesystem_config.h b/include/private/android_filesystem_config.h
index 85d6c19..53966d5 100644
--- a/include/private/android_filesystem_config.h
+++ b/include/private/android_filesystem_config.h
@@ -88,6 +88,10 @@
#define AID_WEBSERV 1044 /* webservd process */
#define AID_DEBUGGERD 1045 /* debuggerd unprivileged user */
#define AID_MEDIA_CODEC 1046 /* mediacodec process */
+#define AID_CAMERASERVER 1047 /* cameraserver process */
+#define AID_FIREWALL 1048 /* firewalld process */
+#define AID_TRUNKS 1049 /* trunksd process (TPM daemon) */
+/* Changes to this file must be made in AOSP, *not* in internal branches. */
#define AID_SHELL 2000 /* adb and debug shell user */
#define AID_CACHE 2001 /* cache access */
@@ -194,6 +198,9 @@
{ "webserv", AID_WEBSERV },
{ "debuggerd", AID_DEBUGGERD, },
{ "mediacodec", AID_MEDIA_CODEC, },
+ { "cameraserver", AID_CAMERASERVER, },
+ { "firewall", AID_FIREWALL, },
+ { "trunks", AID_TRUNKS, },
{ "shell", AID_SHELL, },
{ "cache", AID_CACHE, },
diff --git a/init/perfboot.py b/init/perfboot.py
index 91e6c2b..713290b 100755
--- a/init/perfboot.py
+++ b/init/perfboot.py
@@ -191,9 +191,9 @@
def init_perf(device, output, record_list, tags):
device.wait()
- build_type = device.get_prop('ro.build.type')
+ debuggable = device.get_prop('ro.debuggable')
original_dropbox_max_files = None
- if build_type != 'user':
+ if debuggable == '1':
# Workaround for Dropbox issue (http://b/20890386).
original_dropbox_max_files = disable_dropbox(device)
diff --git a/init/util.cpp b/init/util.cpp
index aefdf8f..84b4155 100644
--- a/init/util.cpp
+++ b/init/util.cpp
@@ -102,7 +102,7 @@
gid_t gid, const char *socketcon)
{
struct sockaddr_un addr;
- int fd, ret;
+ int fd, ret, savederrno;
char *filecon;
if (socketcon) {
@@ -140,16 +140,26 @@
}
ret = bind(fd, (struct sockaddr *) &addr, sizeof (addr));
- if (ret) {
- ERROR("Failed to bind socket '%s': %s\n", name, strerror(errno));
- goto out_unlink;
- }
+ savederrno = errno;
setfscreatecon(NULL);
freecon(filecon);
- chown(addr.sun_path, uid, gid);
- chmod(addr.sun_path, perm);
+ if (ret) {
+ ERROR("Failed to bind socket '%s': %s\n", name, strerror(savederrno));
+ goto out_unlink;
+ }
+
+ ret = lchown(addr.sun_path, uid, gid);
+ if (ret) {
+ ERROR("Failed to lchown socket '%s': %s\n", addr.sun_path, strerror(errno));
+ goto out_unlink;
+ }
+ ret = fchmodat(AT_FDCWD, addr.sun_path, perm, AT_SYMLINK_NOFOLLOW);
+ if (ret) {
+ ERROR("Failed to fchmodat socket '%s': %s\n", addr.sun_path, strerror(errno));
+ goto out_unlink;
+ }
INFO("Created socket '%s' with mode '%o', user '%d', group '%d'\n",
addr.sun_path, perm, uid, gid);
diff --git a/libcutils/tests/Android.mk b/libcutils/tests/Android.mk
index 4da5ed6..52cf5f4 100644
--- a/libcutils/tests/Android.mk
+++ b/libcutils/tests/Android.mk
@@ -23,8 +23,9 @@
test_target_only_src_files := \
MemsetTest.cpp \
PropertiesTest.cpp \
+ trace-dev_test.cpp \
-test_libraries := libcutils liblog
+test_libraries := libcutils liblog libbase
#
diff --git a/libcutils/tests/trace-dev_test.cpp b/libcutils/tests/trace-dev_test.cpp
new file mode 100644
index 0000000..edf981b
--- /dev/null
+++ b/libcutils/tests/trace-dev_test.cpp
@@ -0,0 +1,295 @@
+/*
+ * Copyright (C) 2016 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 <sys/types.h>
+#include <unistd.h>
+
+#include <memory>
+#include <string>
+
+#include <android-base/file.h>
+#include <android-base/stringprintf.h>
+#include <android-base/test_utils.h>
+#include <gtest/gtest.h>
+
+#include "../trace-dev.c"
+
+class TraceDevTest : public ::testing::Test {
+ protected:
+ void SetUp() override {
+ lseek(tmp_file_.fd, 0, SEEK_SET);
+ atrace_marker_fd = tmp_file_.fd;
+ }
+
+ void TearDown() override {
+ atrace_marker_fd = -1;
+ }
+
+ TemporaryFile tmp_file_;
+
+ static std::string MakeName(size_t length) {
+ std::string name;
+ for (size_t i = 0; i < length; i++) {
+ name += '0' + (i % 10);
+ }
+ return name;
+ }
+};
+
+TEST_F(TraceDevTest, atrace_begin_body_normal) {
+ atrace_begin_body("fake_name");
+
+ ASSERT_EQ(0, lseek(atrace_marker_fd, 0, SEEK_SET));
+
+ std::string actual;
+ ASSERT_TRUE(android::base::ReadFdToString(atrace_marker_fd, &actual));
+ std::string expected = android::base::StringPrintf("B|%d|fake_name", getpid());
+ ASSERT_STREQ(expected.c_str(), actual.c_str());
+}
+
+TEST_F(TraceDevTest, atrace_begin_body_exact) {
+ std::string expected = android::base::StringPrintf("B|%d|", getpid());
+ std::string name = MakeName(ATRACE_MESSAGE_LENGTH - expected.length() - 1);
+ atrace_begin_body(name.c_str());
+
+ ASSERT_EQ(ATRACE_MESSAGE_LENGTH - 1, lseek(atrace_marker_fd, 0, SEEK_CUR));
+ ASSERT_EQ(0, lseek(atrace_marker_fd, 0, SEEK_SET));
+
+ std::string actual;
+ ASSERT_TRUE(android::base::ReadFdToString(atrace_marker_fd, &actual));
+ expected += name;
+ ASSERT_STREQ(expected.c_str(), actual.c_str());
+
+ // Add a single character and verify we get the exact same value as before.
+ ASSERT_EQ(0, lseek(atrace_marker_fd, 0, SEEK_SET));
+ name += '*';
+ atrace_begin_body(name.c_str());
+ EXPECT_EQ(ATRACE_MESSAGE_LENGTH - 1, lseek(atrace_marker_fd, 0, SEEK_CUR));
+ ASSERT_EQ(0, lseek(atrace_marker_fd, 0, SEEK_SET));
+ ASSERT_TRUE(android::base::ReadFdToString(atrace_marker_fd, &actual));
+ ASSERT_STREQ(expected.c_str(), actual.c_str());
+}
+
+TEST_F(TraceDevTest, atrace_begin_body_truncated) {
+ std::string expected = android::base::StringPrintf("B|%d|", getpid());
+ std::string name = MakeName(2 * ATRACE_MESSAGE_LENGTH);
+ atrace_begin_body(name.c_str());
+
+ ASSERT_EQ(ATRACE_MESSAGE_LENGTH - 1, lseek(atrace_marker_fd, 0, SEEK_CUR));
+ ASSERT_EQ(0, lseek(atrace_marker_fd, 0, SEEK_SET));
+
+ std::string actual;
+ ASSERT_TRUE(android::base::ReadFdToString(atrace_marker_fd, &actual));
+ int expected_len = ATRACE_MESSAGE_LENGTH - expected.length() - 1;
+ expected += android::base::StringPrintf("%.*s", expected_len, name.c_str());
+ ASSERT_STREQ(expected.c_str(), actual.c_str());
+}
+
+TEST_F(TraceDevTest, atrace_async_begin_body_normal) {
+ atrace_async_begin_body("fake_name", 12345);
+
+ ASSERT_EQ(0, lseek(atrace_marker_fd, 0, SEEK_SET));
+
+ std::string actual;
+ ASSERT_TRUE(android::base::ReadFdToString(atrace_marker_fd, &actual));
+ std::string expected = android::base::StringPrintf("S|%d|fake_name|12345", getpid());
+ ASSERT_STREQ(expected.c_str(), actual.c_str());
+}
+
+TEST_F(TraceDevTest, atrace_async_begin_body_exact) {
+ std::string expected = android::base::StringPrintf("S|%d|", getpid());
+ std::string name = MakeName(ATRACE_MESSAGE_LENGTH - expected.length() - 7);
+ atrace_async_begin_body(name.c_str(), 12345);
+
+ ASSERT_EQ(ATRACE_MESSAGE_LENGTH - 1, lseek(atrace_marker_fd, 0, SEEK_CUR));
+ ASSERT_EQ(0, lseek(atrace_marker_fd, 0, SEEK_SET));
+
+ std::string actual;
+ ASSERT_TRUE(android::base::ReadFdToString(atrace_marker_fd, &actual));
+ expected += name + "|12345";
+ ASSERT_STREQ(expected.c_str(), actual.c_str());
+
+ // Add a single character and verify we get the exact same value as before.
+ ASSERT_EQ(0, lseek(atrace_marker_fd, 0, SEEK_SET));
+ name += '*';
+ atrace_async_begin_body(name.c_str(), 12345);
+ EXPECT_EQ(ATRACE_MESSAGE_LENGTH - 1, lseek(atrace_marker_fd, 0, SEEK_CUR));
+ ASSERT_EQ(0, lseek(atrace_marker_fd, 0, SEEK_SET));
+ ASSERT_TRUE(android::base::ReadFdToString(atrace_marker_fd, &actual));
+ ASSERT_STREQ(expected.c_str(), actual.c_str());
+}
+
+TEST_F(TraceDevTest, atrace_async_begin_body_truncated) {
+ std::string expected = android::base::StringPrintf("S|%d|", getpid());
+ std::string name = MakeName(2 * ATRACE_MESSAGE_LENGTH);
+ atrace_async_begin_body(name.c_str(), 12345);
+
+ ASSERT_EQ(ATRACE_MESSAGE_LENGTH - 1, lseek(atrace_marker_fd, 0, SEEK_CUR));
+ ASSERT_EQ(0, lseek(atrace_marker_fd, 0, SEEK_SET));
+
+ std::string actual;
+ ASSERT_TRUE(android::base::ReadFdToString(atrace_marker_fd, &actual));
+ int expected_len = ATRACE_MESSAGE_LENGTH - expected.length() - 7;
+ expected += android::base::StringPrintf("%.*s|12345", expected_len, name.c_str());
+ ASSERT_STREQ(expected.c_str(), actual.c_str());
+}
+
+TEST_F(TraceDevTest, atrace_async_end_body_normal) {
+ atrace_async_end_body("fake_name", 12345);
+
+ ASSERT_EQ(0, lseek(atrace_marker_fd, 0, SEEK_SET));
+
+ std::string actual;
+ ASSERT_TRUE(android::base::ReadFdToString(atrace_marker_fd, &actual));
+ std::string expected = android::base::StringPrintf("F|%d|fake_name|12345", getpid());
+ ASSERT_STREQ(expected.c_str(), actual.c_str());
+}
+
+TEST_F(TraceDevTest, atrace_async_end_body_exact) {
+ std::string expected = android::base::StringPrintf("F|%d|", getpid());
+ std::string name = MakeName(ATRACE_MESSAGE_LENGTH - expected.length() - 7);
+ atrace_async_end_body(name.c_str(), 12345);
+
+ ASSERT_EQ(ATRACE_MESSAGE_LENGTH - 1, lseek(atrace_marker_fd, 0, SEEK_CUR));
+ ASSERT_EQ(0, lseek(atrace_marker_fd, 0, SEEK_SET));
+
+ std::string actual;
+ ASSERT_TRUE(android::base::ReadFdToString(atrace_marker_fd, &actual));
+ expected += name + "|12345";
+ ASSERT_STREQ(expected.c_str(), actual.c_str());
+
+ // Add a single character and verify we get the exact same value as before.
+ ASSERT_EQ(0, lseek(atrace_marker_fd, 0, SEEK_SET));
+ name += '*';
+ atrace_async_end_body(name.c_str(), 12345);
+ EXPECT_EQ(ATRACE_MESSAGE_LENGTH - 1, lseek(atrace_marker_fd, 0, SEEK_CUR));
+ ASSERT_EQ(0, lseek(atrace_marker_fd, 0, SEEK_SET));
+ ASSERT_TRUE(android::base::ReadFdToString(atrace_marker_fd, &actual));
+ ASSERT_STREQ(expected.c_str(), actual.c_str());
+}
+
+TEST_F(TraceDevTest, atrace_async_end_body_truncated) {
+ std::string expected = android::base::StringPrintf("F|%d|", getpid());
+ std::string name = MakeName(2 * ATRACE_MESSAGE_LENGTH);
+ atrace_async_end_body(name.c_str(), 12345);
+
+ ASSERT_EQ(ATRACE_MESSAGE_LENGTH - 1, lseek(atrace_marker_fd, 0, SEEK_CUR));
+ ASSERT_EQ(0, lseek(atrace_marker_fd, 0, SEEK_SET));
+
+ std::string actual;
+ ASSERT_TRUE(android::base::ReadFdToString(atrace_marker_fd, &actual));
+ int expected_len = ATRACE_MESSAGE_LENGTH - expected.length() - 7;
+ expected += android::base::StringPrintf("%.*s|12345", expected_len, name.c_str());
+ ASSERT_STREQ(expected.c_str(), actual.c_str());
+}
+
+TEST_F(TraceDevTest, atrace_int_body_normal) {
+ atrace_int_body("fake_name", 12345);
+
+ ASSERT_EQ(0, lseek(atrace_marker_fd, 0, SEEK_SET));
+
+ std::string actual;
+ ASSERT_TRUE(android::base::ReadFdToString(atrace_marker_fd, &actual));
+ std::string expected = android::base::StringPrintf("C|%d|fake_name|12345", getpid());
+ ASSERT_STREQ(expected.c_str(), actual.c_str());
+}
+
+TEST_F(TraceDevTest, atrace_int_body_exact) {
+ std::string expected = android::base::StringPrintf("C|%d|", getpid());
+ std::string name = MakeName(ATRACE_MESSAGE_LENGTH - expected.length() - 7);
+ atrace_int_body(name.c_str(), 12345);
+
+ ASSERT_EQ(ATRACE_MESSAGE_LENGTH - 1, lseek(atrace_marker_fd, 0, SEEK_CUR));
+ ASSERT_EQ(0, lseek(atrace_marker_fd, 0, SEEK_SET));
+
+ std::string actual;
+ ASSERT_TRUE(android::base::ReadFdToString(atrace_marker_fd, &actual));
+ expected += name + "|12345";
+ ASSERT_STREQ(expected.c_str(), actual.c_str());
+
+ // Add a single character and verify we get the exact same value as before.
+ ASSERT_EQ(0, lseek(atrace_marker_fd, 0, SEEK_SET));
+ name += '*';
+ atrace_int_body(name.c_str(), 12345);
+ EXPECT_EQ(ATRACE_MESSAGE_LENGTH - 1, lseek(atrace_marker_fd, 0, SEEK_CUR));
+ ASSERT_EQ(0, lseek(atrace_marker_fd, 0, SEEK_SET));
+ ASSERT_TRUE(android::base::ReadFdToString(atrace_marker_fd, &actual));
+ ASSERT_STREQ(expected.c_str(), actual.c_str());
+}
+
+TEST_F(TraceDevTest, atrace_int_body_truncated) {
+ std::string expected = android::base::StringPrintf("C|%d|", getpid());
+ std::string name = MakeName(2 * ATRACE_MESSAGE_LENGTH);
+ atrace_int_body(name.c_str(), 12345);
+
+ ASSERT_EQ(ATRACE_MESSAGE_LENGTH - 1, lseek(atrace_marker_fd, 0, SEEK_CUR));
+ ASSERT_EQ(0, lseek(atrace_marker_fd, 0, SEEK_SET));
+
+ std::string actual;
+ ASSERT_TRUE(android::base::ReadFdToString(atrace_marker_fd, &actual));
+ int expected_len = ATRACE_MESSAGE_LENGTH - expected.length() - 7;
+ expected += android::base::StringPrintf("%.*s|12345", expected_len, name.c_str());
+ ASSERT_STREQ(expected.c_str(), actual.c_str());
+}
+
+TEST_F(TraceDevTest, atrace_int64_body_normal) {
+ atrace_int64_body("fake_name", 17179869183L);
+
+ ASSERT_EQ(0, lseek(atrace_marker_fd, 0, SEEK_SET));
+
+ std::string actual;
+ ASSERT_TRUE(android::base::ReadFdToString(atrace_marker_fd, &actual));
+ std::string expected = android::base::StringPrintf("C|%d|fake_name|17179869183", getpid());
+ ASSERT_STREQ(expected.c_str(), actual.c_str());
+}
+
+TEST_F(TraceDevTest, atrace_int64_body_exact) {
+ std::string expected = android::base::StringPrintf("C|%d|", getpid());
+ std::string name = MakeName(ATRACE_MESSAGE_LENGTH - expected.length() - 13);
+ atrace_int64_body(name.c_str(), 17179869183L);
+
+ ASSERT_EQ(ATRACE_MESSAGE_LENGTH - 1, lseek(atrace_marker_fd, 0, SEEK_CUR));
+ ASSERT_EQ(0, lseek(atrace_marker_fd, 0, SEEK_SET));
+
+ std::string actual;
+ ASSERT_TRUE(android::base::ReadFdToString(atrace_marker_fd, &actual));
+ expected += name + "|17179869183";
+ ASSERT_STREQ(expected.c_str(), actual.c_str());
+
+ // Add a single character and verify we get the exact same value as before.
+ ASSERT_EQ(0, lseek(atrace_marker_fd, 0, SEEK_SET));
+ name += '*';
+ atrace_int64_body(name.c_str(), 17179869183L);
+ EXPECT_EQ(ATRACE_MESSAGE_LENGTH - 1, lseek(atrace_marker_fd, 0, SEEK_CUR));
+ ASSERT_EQ(0, lseek(atrace_marker_fd, 0, SEEK_SET));
+ ASSERT_TRUE(android::base::ReadFdToString(atrace_marker_fd, &actual));
+ ASSERT_STREQ(expected.c_str(), actual.c_str());
+}
+
+TEST_F(TraceDevTest, atrace_int64_body_truncated) {
+ std::string expected = android::base::StringPrintf("C|%d|", getpid());
+ std::string name = MakeName(2 * ATRACE_MESSAGE_LENGTH);
+ atrace_int64_body(name.c_str(), 17179869183L);
+
+ ASSERT_EQ(ATRACE_MESSAGE_LENGTH - 1, lseek(atrace_marker_fd, 0, SEEK_CUR));
+ ASSERT_EQ(0, lseek(atrace_marker_fd, 0, SEEK_SET));
+
+ std::string actual;
+ ASSERT_TRUE(android::base::ReadFdToString(atrace_marker_fd, &actual));
+ int expected_len = ATRACE_MESSAGE_LENGTH - expected.length() - 13;
+ expected += android::base::StringPrintf("%.*s|17179869183", expected_len, name.c_str());
+ ASSERT_STREQ(expected.c_str(), actual.c_str());
+}
diff --git a/libcutils/trace-dev.c b/libcutils/trace-dev.c
index f025256..5df1c5a 100644
--- a/libcutils/trace-dev.c
+++ b/libcutils/trace-dev.c
@@ -194,49 +194,47 @@
void atrace_begin_body(const char* name)
{
char buf[ATRACE_MESSAGE_LENGTH];
- size_t len;
- len = snprintf(buf, ATRACE_MESSAGE_LENGTH, "B|%d|%s", getpid(), name);
+ int len = snprintf(buf, sizeof(buf), "B|%d|%s", getpid(), name);
+ if (len >= (int) sizeof(buf)) {
+ ALOGW("Truncated name in %s: %s\n", __FUNCTION__, name);
+ len = sizeof(buf) - 1;
+ }
write(atrace_marker_fd, buf, len);
}
+#define WRITE_MSG(format_begin, format_end, pid, name, value) { \
+ char buf[ATRACE_MESSAGE_LENGTH]; \
+ int len = snprintf(buf, sizeof(buf), format_begin "%s" format_end, pid, \
+ name, value); \
+ if (len >= (int) sizeof(buf)) { \
+ /* Given the sizeof(buf), and all of the current format buffers, \
+ * it is impossible for name_len to be < 0 if len >= sizeof(buf). */ \
+ int name_len = strlen(name) - (len - sizeof(buf)) - 1; \
+ /* Truncate the name to make the message fit. */ \
+ ALOGW("Truncated name in %s: %s\n", __FUNCTION__, name); \
+ len = snprintf(buf, sizeof(buf), format_begin "%.*s" format_end, pid, \
+ name_len, name, value); \
+ } \
+ write(atrace_marker_fd, buf, len); \
+}
void atrace_async_begin_body(const char* name, int32_t cookie)
{
- char buf[ATRACE_MESSAGE_LENGTH];
- size_t len;
-
- len = snprintf(buf, ATRACE_MESSAGE_LENGTH, "S|%d|%s|%" PRId32,
- getpid(), name, cookie);
- write(atrace_marker_fd, buf, len);
+ WRITE_MSG("S|%d|", "|%" PRId32, getpid(), name, cookie);
}
void atrace_async_end_body(const char* name, int32_t cookie)
{
- char buf[ATRACE_MESSAGE_LENGTH];
- size_t len;
-
- len = snprintf(buf, ATRACE_MESSAGE_LENGTH, "F|%d|%s|%" PRId32,
- getpid(), name, cookie);
- write(atrace_marker_fd, buf, len);
+ WRITE_MSG("F|%d|", "|%" PRId32, getpid(), name, cookie);
}
void atrace_int_body(const char* name, int32_t value)
{
- char buf[ATRACE_MESSAGE_LENGTH];
- size_t len;
-
- len = snprintf(buf, ATRACE_MESSAGE_LENGTH, "C|%d|%s|%" PRId32,
- getpid(), name, value);
- write(atrace_marker_fd, buf, len);
+ WRITE_MSG("C|%d|", "|%" PRId32, getpid(), name, value);
}
void atrace_int64_body(const char* name, int64_t value)
{
- char buf[ATRACE_MESSAGE_LENGTH];
- size_t len;
-
- len = snprintf(buf, ATRACE_MESSAGE_LENGTH, "C|%d|%s|%" PRId64,
- getpid(), name, value);
- write(atrace_marker_fd, buf, len);
+ WRITE_MSG("C|%d|", "|%" PRId64, getpid(), name, value);
}
diff --git a/liblog/Android.bp b/liblog/Android.bp
index ee883f0..607d667 100644
--- a/liblog/Android.bp
+++ b/liblog/Android.bp
@@ -14,15 +14,16 @@
// limitations under the License.
//
-liblog_host_sources = [
+liblog_sources = [
"logd_write.c",
+ "log_event_list.c",
"log_event_write.c",
+]
+liblog_host_sources = [
"fake_log_device.c",
//"event.logtags",
]
liblog_target_sources = [
- "logd_write.c",
- "log_event_write.c",
"event_tag_map.c",
"log_time.cpp",
"log_is_loggable.c",
@@ -36,6 +37,8 @@
name: "liblog",
host_supported: true,
+ srcs: liblog_sources,
+
target: {
host: {
srcs: liblog_host_sources,
@@ -71,7 +74,6 @@
// $(LOCAL_PATH)/event.logtags)
// so make sure we do not regret hard-coding it as follows:
"-DLIBLOG_LOG_TAG=1005",
- "-DSNET_EVENT_LOG_TAG=1397638484",
],
compile_multilib: "both",
stl: "none",
diff --git a/liblog/Android.mk b/liblog/Android.mk
index c7b76d8..dd5b518 100644
--- a/liblog/Android.mk
+++ b/liblog/Android.mk
@@ -24,11 +24,10 @@
# so make sure we do not regret hard-coding it as follows:
liblog_cflags := -DLIBLOG_LOG_TAG=1005
-liblog_host_sources := logd_write.c log_event_write.c fake_log_device.c event.logtags
-liblog_target_sources := logd_write.c log_event_write.c event_tag_map.c log_time.cpp log_is_loggable.c
-liblog_target_sources += logprint.c
-liblog_target_sources += log_read.c
-liblog_target_sources += log_event_list.c
+liblog_sources := logd_write.c log_event_list.c log_event_write.c
+liblog_host_sources := $(liblog_sources) fake_log_device.c event.logtags
+liblog_target_sources := $(liblog_sources) event_tag_map.c
+liblog_target_sources += log_time.cpp log_is_loggable.c logprint.c log_read.c
# Shared and static library for host
# ========================================================
diff --git a/liblog/log_event_list.c b/liblog/log_event_list.c
index 50a27c0..2213f21 100644
--- a/liblog/log_event_list.c
+++ b/liblog/log_event_list.c
@@ -195,9 +195,10 @@
return 0;
}
-int android_log_write_string8(android_log_context ctx, const char *value) {
+int android_log_write_string8_len(android_log_context ctx,
+ const char *value, size_t maxlen) {
size_t needed;
- int32_t len;
+ ssize_t len;
android_log_context_internal *context;
context = (android_log_context_internal *)ctx;
@@ -208,13 +209,13 @@
return -EIO;
}
if (!value) {
- return -EINVAL;
+ value = "";
}
- len = strlen(value);
- needed = sizeof(uint8_t) + sizeof(len) + len;
+ len = strnlen(value, maxlen);
+ needed = sizeof(uint8_t) + sizeof(int32_t) + len;
if ((context->pos + needed) > MAX_EVENT_PAYLOAD) {
/* Truncate string for delivery */
- len = MAX_EVENT_PAYLOAD - context->pos - 1 - sizeof(len);
+ len = MAX_EVENT_PAYLOAD - context->pos - 1 - sizeof(int32_t);
if (len <= 0) {
context->overflow = true;
return -EIO;
@@ -223,9 +224,15 @@
context->count[context->list_nest_depth]++;
context->storage[context->pos + 0] = EVENT_TYPE_STRING;
copy4LE(&context->storage[context->pos + 1], len);
- memcpy(&context->storage[context->pos + 5], value, len);
+ if (len) {
+ memcpy(&context->storage[context->pos + 5], value, len);
+ }
context->pos += needed;
- return 0;
+ return len;
+}
+
+int android_log_write_string8(android_log_context ctx, const char *value) {
+ return android_log_write_string8_len(ctx, value, MAX_EVENT_PAYLOAD);
}
int android_log_write_float32(android_log_context ctx, float value) {
diff --git a/liblog/log_event_write.c b/liblog/log_event_write.c
index 0bc42d5..ad42edd 100644
--- a/liblog/log_event_write.c
+++ b/liblog/log_event_write.c
@@ -15,74 +15,33 @@
*/
#include <errno.h>
-#include <string.h>
#include <log/log.h>
-#include <log/logger.h>
-#define MAX_EVENT_PAYLOAD 512
#define MAX_SUBTAG_LEN 32
-static inline void copy4LE(uint8_t *buf, size_t pos, int val)
+int __android_log_error_write(int tag, const char *subTag, int32_t uid,
+ const char *data, uint32_t dataLen)
{
- buf[pos] = val & 0xFF;
- buf[pos+1] = (val >> 8) & 0xFF;
- buf[pos+2] = (val >> 16) & 0xFF;
- buf[pos+3] = (val >> 24) & 0xFF;
-}
+ int ret = -EINVAL;
-int __android_log_error_write(int tag, const char *subTag, int32_t uid, const char *data,
- uint32_t dataLen)
-{
- uint8_t buf[MAX_EVENT_PAYLOAD];
- size_t pos = 0;
- uint32_t subTagLen = 0;
- uint32_t roomLeftForData = 0;
+ if (subTag && (data || !dataLen)) {
+ android_log_context ctx = create_android_logger(tag);
- if ((subTag == NULL) || ((data == NULL) && (dataLen != 0))) return -EINVAL;
-
- subTagLen = strlen(subTag);
-
- // Truncate subtags that are too long.
- subTagLen = subTagLen > MAX_SUBTAG_LEN ? MAX_SUBTAG_LEN : subTagLen;
-
- // Truncate dataLen if it is too long.
- roomLeftForData = MAX_EVENT_PAYLOAD -
- (1 + // EVENT_TYPE_LIST
- 1 + // Number of elements in list
- 1 + // EVENT_TYPE_STRING
- sizeof(subTagLen) +
- subTagLen +
- 1 + // EVENT_TYPE_INT
- sizeof(uid) +
- 1 + // EVENT_TYPE_STRING
- sizeof(dataLen));
- dataLen = dataLen > roomLeftForData ? roomLeftForData : dataLen;
-
- buf[pos++] = EVENT_TYPE_LIST;
- buf[pos++] = 3; // Number of elements in the list (subTag, uid, data)
-
- // Write sub tag.
- buf[pos++] = EVENT_TYPE_STRING;
- copy4LE(buf, pos, subTagLen);
- pos += 4;
- memcpy(&buf[pos], subTag, subTagLen);
- pos += subTagLen;
-
- // Write UID.
- buf[pos++] = EVENT_TYPE_INT;
- copy4LE(buf, pos, uid);
- pos += 4;
-
- // Write data.
- buf[pos++] = EVENT_TYPE_STRING;
- copy4LE(buf, pos, dataLen);
- pos += 4;
- if (dataLen != 0)
- {
- memcpy(&buf[pos], data, dataLen);
- pos += dataLen;
+ ret = -ENOMEM;
+ if (ctx) {
+ ret = android_log_write_string8_len(ctx, subTag, MAX_SUBTAG_LEN);
+ if (ret >= 0) {
+ ret = android_log_write_int32(ctx, uid);
+ if (ret >= 0) {
+ ret = android_log_write_string8_len(ctx, data, dataLen);
+ if (ret >= 0) {
+ ret = android_log_write_list(ctx, LOG_ID_EVENTS);
+ }
+ }
+ }
+ android_log_destroy(&ctx);
+ }
}
-
- return __android_log_bwrite(tag, buf, pos);
+ return ret;
}
diff --git a/liblog/tests/libc_test.cpp b/liblog/tests/libc_test.cpp
index 9dd6f03..3d58147 100644
--- a/liblog/tests/libc_test.cpp
+++ b/liblog/tests/libc_test.cpp
@@ -14,126 +14,9 @@
* limitations under the License.
*/
-#include <fcntl.h>
-#include <sys/cdefs.h>
-
#include <gtest/gtest.h>
-// Should be in bionic test suite, *but* we are using liblog to confirm
-// end-to-end logging, so let the overly cute oedipus complex begin ...
-#include "../../../../bionic/libc/bionic/libc_logging.cpp" // not Standalone
-#define _ANDROID_LOG_H // Priorities redefined
-#define _LIBS_LOG_LOG_H // log ids redefined
-typedef unsigned char log_id_t; // log_id_t missing as a result
-#define _LIBS_LOG_LOG_READ_H // log_time redefined
-
-#include <log/log.h>
-#include <log/logger.h>
-#include <log/log_read.h>
-
-TEST(libc, __libc_android_log_event_int) {
- struct logger_list *logger_list;
-
- pid_t pid = getpid();
-
- ASSERT_TRUE(NULL != (logger_list = android_logger_list_open(
- LOG_ID_EVENTS, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK, 1000, pid)));
-
- struct timespec ts;
- clock_gettime(CLOCK_MONOTONIC, &ts);
- int value = ts.tv_nsec;
-
- __libc_android_log_event_int(0, value);
- usleep(1000000);
-
- int count = 0;
-
- for (;;) {
- log_msg log_msg;
- if (android_logger_list_read(logger_list, &log_msg) <= 0) {
- break;
- }
-
- ASSERT_EQ(log_msg.entry.pid, pid);
-
- if ((log_msg.entry.len != (4 + 1 + 4))
- || ((int)log_msg.id() != LOG_ID_EVENTS)) {
- continue;
- }
-
- char *eventData = log_msg.msg();
-
- int incoming = (eventData[0] & 0xFF) |
- ((eventData[1] & 0xFF) << 8) |
- ((eventData[2] & 0xFF) << 16) |
- ((eventData[3] & 0xFF) << 24);
-
- if (incoming != 0) {
- continue;
- }
-
- if (eventData[4] != EVENT_TYPE_INT) {
- continue;
- }
-
- incoming = (eventData[4 + 1 + 0] & 0xFF) |
- ((eventData[4 + 1 + 1] & 0xFF) << 8) |
- ((eventData[4 + 1 + 2] & 0xFF) << 16) |
- ((eventData[4 + 1 + 3] & 0xFF) << 24);
-
- if (incoming == value) {
- ++count;
- }
- }
-
- EXPECT_EQ(1, count);
-
- android_logger_list_close(logger_list);
-}
-
-TEST(libc, __libc_fatal_no_abort) {
- struct logger_list *logger_list;
-
- pid_t pid = getpid();
-
- ASSERT_TRUE(NULL != (logger_list = android_logger_list_open(
- (log_id_t)LOG_ID_CRASH, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK, 1000, pid)));
-
- char b[80];
- struct timespec ts;
- clock_gettime(CLOCK_MONOTONIC, &ts);
-
- __libc_fatal_no_abort("%u.%09u", (unsigned)ts.tv_sec, (unsigned)ts.tv_nsec);
- snprintf(b, sizeof(b),"%u.%09u", (unsigned)ts.tv_sec, (unsigned)ts.tv_nsec);
- usleep(1000000);
-
- int count = 0;
-
- for (;;) {
- log_msg log_msg;
- if (android_logger_list_read(logger_list, &log_msg) <= 0) {
- break;
- }
-
- ASSERT_EQ(log_msg.entry.pid, pid);
-
- if ((int)log_msg.id() != LOG_ID_CRASH) {
- continue;
- }
-
- char *data = log_msg.msg();
-
- if ((*data == ANDROID_LOG_FATAL)
- && !strcmp(data + 1, "libc")
- && !strcmp(data + 1 + strlen(data + 1) + 1, b)) {
- ++count;
- }
- }
-
- EXPECT_EQ(1, count);
-
- android_logger_list_close(logger_list);
-}
+#include <stdio.h>
TEST(libc, __pstore_append) {
FILE *fp;
diff --git a/liblog/tests/liblog_test.cpp b/liblog/tests/liblog_test.cpp
index 1317853..50ecd2d 100644
--- a/liblog/tests/liblog_test.cpp
+++ b/liblog/tests/liblog_test.cpp
@@ -1429,7 +1429,7 @@
const int TAG = 123456782;
const char SUBTAG[] = "test-subtag";
const int UID = -1;
- const int DATA_LEN = SIZEOF_MAX_PAYLOAD_BUF;
+ const int DATA_LEN = sizeof(max_payload_buf);
struct logger_list *logger_list;
pid_t pid = getpid();
@@ -1500,9 +1500,9 @@
}
eventData += dataLen;
- // 4 bytes for the tag, and 512 bytes for the log since the
- // max_payload_buf should be truncated.
- ASSERT_EQ(4 + 512, eventData - original);
+ // 4 bytes for the tag, and max_payload_buf should be truncated.
+ ASSERT_LE(4 + 512, eventData - original); // worst expectations
+ ASSERT_GT(4 + DATA_LEN, eventData - original); // must be truncated
++count;
}
@@ -2123,6 +2123,30 @@
return "[1,[2,[3,[4,[5,[6]]]]]]";
}
+static const char *event_test_android_log_error_write(uint32_t tag, size_t &expected_len) {
+ EXPECT_LE(0, __android_log_error_write(tag, "Hello World", 42, "dlroW olleH", 11));
+
+ expected_len = sizeof(uint32_t) +
+ sizeof(uint8_t) + sizeof(uint8_t) +
+ sizeof(uint8_t) + sizeof(uint32_t) + sizeof("Hello World") - 1 +
+ sizeof(uint8_t) + sizeof(uint32_t) +
+ sizeof(uint8_t) + sizeof(uint32_t) + sizeof("dlroW olleH") - 1;
+
+ return "[Hello World,42,dlroW olleH]";
+}
+
+static const char *event_test_android_log_error_write_null(uint32_t tag, size_t &expected_len) {
+ EXPECT_LE(0, __android_log_error_write(tag, "Hello World", 42, NULL, 0));
+
+ expected_len = sizeof(uint32_t) +
+ sizeof(uint8_t) + sizeof(uint8_t) +
+ sizeof(uint8_t) + sizeof(uint32_t) + sizeof("Hello World") - 1 +
+ sizeof(uint8_t) + sizeof(uint32_t) +
+ sizeof(uint8_t) + sizeof(uint32_t) + sizeof("") - 1;
+
+ return "[Hello World,42,]";
+}
+
// make sure all user buffers are flushed
static void print_barrier() {
std::cout.flush();
@@ -2241,6 +2265,14 @@
create_android_logger(event_test_7_level_suffix);
}
+TEST(liblog, create_android_logger_android_log_error_write) {
+ create_android_logger(event_test_android_log_error_write);
+}
+
+TEST(liblog, create_android_logger_android_log_error_write_null) {
+ create_android_logger(event_test_android_log_error_write_null);
+}
+
TEST(liblog, create_android_logger_overflow) {
android_log_context ctx;
diff --git a/libmincrypt/Android.mk b/libmincrypt/Android.mk
index 7906986..09fbbb1 100644
--- a/libmincrypt/Android.mk
+++ b/libmincrypt/Android.mk
@@ -14,5 +14,4 @@
LOCAL_CFLAGS := -Wall -Werror
include $(BUILD_HOST_STATIC_LIBRARY)
-include $(LOCAL_PATH)/tools/Android.mk \
- $(LOCAL_PATH)/test/Android.mk
+include $(LOCAL_PATH)/test/Android.mk
diff --git a/libmincrypt/tools/Android.mk b/libmincrypt/tools/Android.mk
deleted file mode 100644
index 3154914..0000000
--- a/libmincrypt/tools/Android.mk
+++ /dev/null
@@ -1,22 +0,0 @@
-# Copyright (C) 2008 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.
-
-LOCAL_PATH := $(call my-dir)
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := dumpkey
-LOCAL_SRC_FILES := DumpPublicKey.java
-LOCAL_JAR_MANIFEST := DumpPublicKey.mf
-LOCAL_STATIC_JAVA_LIBRARIES := bouncycastle-host
-include $(BUILD_HOST_JAVA_LIBRARY)
diff --git a/libmincrypt/tools/DumpPublicKey.java b/libmincrypt/tools/DumpPublicKey.java
deleted file mode 100644
index 3eb1398..0000000
--- a/libmincrypt/tools/DumpPublicKey.java
+++ /dev/null
@@ -1,270 +0,0 @@
-/*
- * Copyright (C) 2008 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.
- */
-
-package com.android.dumpkey;
-
-import org.bouncycastle.jce.provider.BouncyCastleProvider;
-
-import java.io.FileInputStream;
-import java.math.BigInteger;
-import java.security.cert.CertificateFactory;
-import java.security.cert.X509Certificate;
-import java.security.KeyStore;
-import java.security.Key;
-import java.security.PublicKey;
-import java.security.Security;
-import java.security.interfaces.ECPublicKey;
-import java.security.interfaces.RSAPublicKey;
-import java.security.spec.ECPoint;
-
-/**
- * Command line tool to extract RSA public keys from X.509 certificates
- * and output source code with data initializers for the keys.
- * @hide
- */
-class DumpPublicKey {
- /**
- * @param key to perform sanity checks on
- * @return version number of key. Supported versions are:
- * 1: 2048-bit RSA key with e=3 and SHA-1 hash
- * 2: 2048-bit RSA key with e=65537 and SHA-1 hash
- * 3: 2048-bit RSA key with e=3 and SHA-256 hash
- * 4: 2048-bit RSA key with e=65537 and SHA-256 hash
- * @throws Exception if the key has the wrong size or public exponent
- */
- static int checkRSA(RSAPublicKey key, boolean useSHA256) throws Exception {
- BigInteger pubexp = key.getPublicExponent();
- BigInteger modulus = key.getModulus();
- int version;
-
- if (pubexp.equals(BigInteger.valueOf(3))) {
- version = useSHA256 ? 3 : 1;
- } else if (pubexp.equals(BigInteger.valueOf(65537))) {
- version = useSHA256 ? 4 : 2;
- } else {
- throw new Exception("Public exponent should be 3 or 65537 but is " +
- pubexp.toString(10) + ".");
- }
-
- if (modulus.bitLength() != 2048) {
- throw new Exception("Modulus should be 2048 bits long but is " +
- modulus.bitLength() + " bits.");
- }
-
- return version;
- }
-
- /**
- * @param key to perform sanity checks on
- * @return version number of key. Supported versions are:
- * 5: 256-bit EC key with curve NIST P-256
- * @throws Exception if the key has the wrong size or public exponent
- */
- static int checkEC(ECPublicKey key) throws Exception {
- if (key.getParams().getCurve().getField().getFieldSize() != 256) {
- throw new Exception("Curve must be NIST P-256");
- }
-
- return 5;
- }
-
- /**
- * Perform sanity check on public key.
- */
- static int check(PublicKey key, boolean useSHA256) throws Exception {
- if (key instanceof RSAPublicKey) {
- return checkRSA((RSAPublicKey) key, useSHA256);
- } else if (key instanceof ECPublicKey) {
- if (!useSHA256) {
- throw new Exception("Must use SHA-256 with EC keys!");
- }
- return checkEC((ECPublicKey) key);
- } else {
- throw new Exception("Unsupported key class: " + key.getClass().getName());
- }
- }
-
- /**
- * @param key to output
- * @return a String representing this public key. If the key is a
- * version 1 key, the string will be a C initializer; this is
- * not true for newer key versions.
- */
- static String printRSA(RSAPublicKey key, boolean useSHA256) throws Exception {
- int version = check(key, useSHA256);
-
- BigInteger N = key.getModulus();
-
- StringBuilder result = new StringBuilder();
-
- int nwords = N.bitLength() / 32; // # of 32 bit integers in modulus
-
- if (version > 1) {
- result.append("v");
- result.append(Integer.toString(version));
- result.append(" ");
- }
-
- result.append("{");
- result.append(nwords);
-
- BigInteger B = BigInteger.valueOf(0x100000000L); // 2^32
- BigInteger N0inv = B.subtract(N.modInverse(B)); // -1 / N[0] mod 2^32
-
- result.append(",0x");
- result.append(N0inv.toString(16));
-
- BigInteger R = BigInteger.valueOf(2).pow(N.bitLength());
- BigInteger RR = R.multiply(R).mod(N); // 2^4096 mod N
-
- // Write out modulus as little endian array of integers.
- result.append(",{");
- for (int i = 0; i < nwords; ++i) {
- long n = N.mod(B).longValue();
- result.append(n);
-
- if (i != nwords - 1) {
- result.append(",");
- }
-
- N = N.divide(B);
- }
- result.append("}");
-
- // Write R^2 as little endian array of integers.
- result.append(",{");
- for (int i = 0; i < nwords; ++i) {
- long rr = RR.mod(B).longValue();
- result.append(rr);
-
- if (i != nwords - 1) {
- result.append(",");
- }
-
- RR = RR.divide(B);
- }
- result.append("}");
-
- result.append("}");
- return result.toString();
- }
-
- /**
- * @param key to output
- * @return a String representing this public key. If the key is a
- * version 1 key, the string will be a C initializer; this is
- * not true for newer key versions.
- */
- static String printEC(ECPublicKey key) throws Exception {
- int version = checkEC(key);
-
- StringBuilder result = new StringBuilder();
-
- result.append("v");
- result.append(Integer.toString(version));
- result.append(" ");
-
- BigInteger X = key.getW().getAffineX();
- BigInteger Y = key.getW().getAffineY();
- int nbytes = key.getParams().getCurve().getField().getFieldSize() / 8; // # of 32 bit integers in X coordinate
-
- result.append("{");
- result.append(nbytes);
-
- BigInteger B = BigInteger.valueOf(0x100L); // 2^8
-
- // Write out Y coordinate as array of characters.
- result.append(",{");
- for (int i = 0; i < nbytes; ++i) {
- long n = X.mod(B).longValue();
- result.append(n);
-
- if (i != nbytes - 1) {
- result.append(",");
- }
-
- X = X.divide(B);
- }
- result.append("}");
-
- // Write out Y coordinate as array of characters.
- result.append(",{");
- for (int i = 0; i < nbytes; ++i) {
- long n = Y.mod(B).longValue();
- result.append(n);
-
- if (i != nbytes - 1) {
- result.append(",");
- }
-
- Y = Y.divide(B);
- }
- result.append("}");
-
- result.append("}");
- return result.toString();
- }
-
- static String print(PublicKey key, boolean useSHA256) throws Exception {
- if (key instanceof RSAPublicKey) {
- return printRSA((RSAPublicKey) key, useSHA256);
- } else if (key instanceof ECPublicKey) {
- return printEC((ECPublicKey) key);
- } else {
- throw new Exception("Unsupported key class: " + key.getClass().getName());
- }
- }
-
- public static void main(String[] args) {
- if (args.length < 1) {
- System.err.println("Usage: DumpPublicKey certfile ... > source.c");
- System.exit(1);
- }
- Security.addProvider(new BouncyCastleProvider());
- try {
- for (int i = 0; i < args.length; i++) {
- FileInputStream input = new FileInputStream(args[i]);
- CertificateFactory cf = CertificateFactory.getInstance("X.509");
- X509Certificate cert = (X509Certificate) cf.generateCertificate(input);
-
- boolean useSHA256 = false;
- String sigAlg = cert.getSigAlgName();
- if ("SHA1withRSA".equals(sigAlg) || "MD5withRSA".equals(sigAlg)) {
- // SignApk has historically accepted "MD5withRSA"
- // certificates, but treated them as "SHA1withRSA"
- // anyway. Continue to do so for backwards
- // compatibility.
- useSHA256 = false;
- } else if ("SHA256withRSA".equals(sigAlg) || "SHA256withECDSA".equals(sigAlg)) {
- useSHA256 = true;
- } else {
- System.err.println(args[i] + ": unsupported signature algorithm \"" +
- sigAlg + "\"");
- System.exit(1);
- }
-
- PublicKey key = cert.getPublicKey();
- check(key, useSHA256);
- System.out.print(print(key, useSHA256));
- System.out.println(i < args.length - 1 ? "," : "");
- }
- } catch (Exception e) {
- e.printStackTrace();
- System.exit(1);
- }
- System.exit(0);
- }
-}
diff --git a/libmincrypt/tools/DumpPublicKey.mf b/libmincrypt/tools/DumpPublicKey.mf
deleted file mode 100644
index 7bb3bc8..0000000
--- a/libmincrypt/tools/DumpPublicKey.mf
+++ /dev/null
@@ -1 +0,0 @@
-Main-Class: com.android.dumpkey.DumpPublicKey
diff --git a/libnativeloader/include/nativeloader/native_loader.h b/libnativeloader/include/nativeloader/native_loader.h
index 2dec71f..5644aa6 100644
--- a/libnativeloader/include/nativeloader/native_loader.h
+++ b/libnativeloader/include/nativeloader/native_loader.h
@@ -26,6 +26,9 @@
namespace android {
__attribute__((visibility("default")))
+void PreloadPublicNativeLibraries();
+
+__attribute__((visibility("default")))
void* OpenNativeLibrary(JNIEnv* env, int32_t target_sdk_version, const char* path,
jobject class_loader, bool is_shared, jstring library_path,
jstring permitted_path);
diff --git a/libnativeloader/native_loader.cpp b/libnativeloader/native_loader.cpp
index a64b972..f8bb5fd 100644
--- a/libnativeloader/native_loader.cpp
+++ b/libnativeloader/native_loader.cpp
@@ -57,9 +57,7 @@
class LibraryNamespaces {
public:
- LibraryNamespaces() : initialized_(false) {
- PreloadPublicLibraries();
- }
+ LibraryNamespaces() : initialized_(false) { }
android_namespace_t* GetOrCreate(JNIEnv* env, jobject class_loader,
bool is_shared,
@@ -111,7 +109,6 @@
return it != namespaces_.end() ? it->second : nullptr;
}
- private:
void PreloadPublicLibraries() {
// android_init_namespaces() expects all the public libraries
// to be loaded so that they can be found by soname alone.
@@ -121,6 +118,7 @@
}
}
+ private:
bool InitPublicNamespace(const char* library_path) {
// Some apps call dlopen from generated code unknown to linker in which
// case linker uses anonymous namespace. See b/25844435 for details.
@@ -139,6 +137,12 @@
static LibraryNamespaces* g_namespaces = new LibraryNamespaces;
#endif
+void PreloadPublicNativeLibraries() {
+#if defined(__ANDROID__)
+ g_namespaces->PreloadPublicLibraries();
+#endif
+}
+
void* OpenNativeLibrary(JNIEnv* env, int32_t target_sdk_version, const char* path,
jobject class_loader, bool is_shared, jstring java_library_path,
diff --git a/libpixelflinger/codeflinger/GGLAssembler.h b/libpixelflinger/codeflinger/GGLAssembler.h
index 9db20df..ecc242a 100644
--- a/libpixelflinger/codeflinger/GGLAssembler.h
+++ b/libpixelflinger/codeflinger/GGLAssembler.h
@@ -288,6 +288,14 @@
private:
+ // GGLAssembler hides RegisterAllocator's and ARMAssemblerProxy's reset
+ // methods by providing a reset method with a different parameter set. The
+ // intent of GGLAssembler's reset method is to wrap the inherited reset
+ // methods, so make these methods private in order to prevent direct calls
+ // to these methods from clients.
+ using RegisterAllocator::reset;
+ using ARMAssemblerProxy::reset;
+
struct tex_coord_t {
reg_t s;
reg_t t;
diff --git a/libutils/Android.mk b/libutils/Android.mk
index 3663c52..6f88a6d 100644
--- a/libutils/Android.mk
+++ b/libutils/Android.mk
@@ -72,7 +72,7 @@
ifeq ($(TARGET_ARCH),mips)
LOCAL_CFLAGS += -DALIGN_DOUBLE
endif
-LOCAL_CFLAGS += -Werror
+LOCAL_CFLAGS += -Werror -fvisibility=protected
LOCAL_STATIC_LIBRARIES := \
libcutils \
diff --git a/logd/FlushCommand.cpp b/logd/FlushCommand.cpp
index fd45c4a0..6a26d00 100644
--- a/logd/FlushCommand.cpp
+++ b/logd/FlushCommand.cpp
@@ -16,7 +16,10 @@
#include <stdlib.h>
+#include <private/android_filesystem_config.h>
+
#include "FlushCommand.h"
+#include "LogBuffer.h"
#include "LogBufferElement.h"
#include "LogCommand.h"
#include "LogReader.h"
diff --git a/logd/LogAudit.cpp b/logd/LogAudit.cpp
index fffc9ba..230dd11 100644
--- a/logd/LogAudit.cpp
+++ b/logd/LogAudit.cpp
@@ -20,10 +20,13 @@
#include <limits.h>
#include <stdarg.h>
#include <stdlib.h>
+#include <string.h>
#include <sys/prctl.h>
#include <sys/uio.h>
#include <syslog.h>
+#include <string>
+
#include <cutils/properties.h>
#include <log/logger.h>
#include <private/android_filesystem_config.h>
@@ -31,7 +34,9 @@
#include "libaudit.h"
#include "LogAudit.h"
+#include "LogBuffer.h"
#include "LogKlog.h"
+#include "LogReader.h"
#ifndef AUDITD_ENFORCE_INTEGRITY
#define AUDITD_ENFORCE_INTEGRITY false
diff --git a/logd/LogAudit.h b/logd/LogAudit.h
index 455ed58..3a84541 100644
--- a/logd/LogAudit.h
+++ b/logd/LogAudit.h
@@ -18,7 +18,10 @@
#define _LOGD_LOG_AUDIT_H__
#include <sysutils/SocketListener.h>
-#include "LogReader.h"
+
+#include "LogBuffer.h"
+
+class LogReader;
class LogAudit : public SocketListener {
LogBuffer *logbuf;
diff --git a/logd/LogBufferElement.cpp b/logd/LogBufferElement.cpp
index fde9ad7..eb5194c 100644
--- a/logd/LogBufferElement.cpp
+++ b/logd/LogBufferElement.cpp
@@ -25,9 +25,11 @@
#include <log/logger.h>
#include <private/android_logger.h>
+#include "LogBuffer.h"
#include "LogBufferElement.h"
#include "LogCommand.h"
#include "LogReader.h"
+#include "LogUtils.h"
const uint64_t LogBufferElement::FLUSH_ERROR(0);
atomic_int_fast64_t LogBufferElement::sequence(1);
diff --git a/logd/LogKlog.cpp b/logd/LogKlog.cpp
index 9690489..ac2b128 100644
--- a/logd/LogKlog.cpp
+++ b/logd/LogKlog.cpp
@@ -20,13 +20,16 @@
#include <limits.h>
#include <stdarg.h>
#include <stdlib.h>
+#include <string.h>
#include <sys/prctl.h>
#include <sys/uio.h>
#include <syslog.h>
#include <log/logger.h>
+#include "LogBuffer.h"
#include "LogKlog.h"
+#include "LogReader.h"
#define KMSG_PRIORITY(PRI) \
'<', \
diff --git a/logd/LogKlog.h b/logd/LogKlog.h
index 3c8cc87..ee73b71 100644
--- a/logd/LogKlog.h
+++ b/logd/LogKlog.h
@@ -19,10 +19,12 @@
#include <sysutils/SocketListener.h>
#include <log/log_read.h>
-#include "LogReader.h"
char *log_strntok_r(char *s, size_t *len, char **saveptr, size_t *sublen);
+class LogBuffer;
+class LogReader;
+
class LogKlog : public SocketListener {
LogBuffer *logbuf;
LogReader *reader;
diff --git a/logd/LogListener.cpp b/logd/LogListener.cpp
index 846dd7c..39dd227 100644
--- a/logd/LogListener.cpp
+++ b/logd/LogListener.cpp
@@ -27,6 +27,7 @@
#include <private/android_filesystem_config.h>
#include <private/android_logger.h>
+#include "LogBuffer.h"
#include "LogListener.h"
#include "LogUtils.h"
diff --git a/logd/LogReader.cpp b/logd/LogReader.cpp
index 667a3f2..2c07984 100644
--- a/logd/LogReader.cpp
+++ b/logd/LogReader.cpp
@@ -18,11 +18,15 @@
#include <poll.h>
#include <sys/prctl.h>
#include <sys/socket.h>
+#include <sys/types.h>
#include <cutils/sockets.h>
-#include "LogReader.h"
#include "FlushCommand.h"
+#include "LogBuffer.h"
+#include "LogBufferElement.h"
+#include "LogReader.h"
+#include "LogUtils.h"
LogReader::LogReader(LogBuffer *logbuf) :
SocketListener(getLogSocket(), true),
@@ -176,6 +180,11 @@
}
FlushCommand command(*this, nonBlock, tail, logMask, pid, sequence, timeout);
+
+ // Set acceptable upper limit to wait for slow reader processing b/27242723
+ struct timeval t = { LOGD_SNDTIMEO, 0 };
+ setsockopt(cli->getSocket(), SOL_SOCKET, SO_SNDTIMEO, (const char *)&t, sizeof(t));
+
command.runSocketCommand(cli);
return true;
}
diff --git a/logd/LogReader.h b/logd/LogReader.h
index 91559a3..98674b8 100644
--- a/logd/LogReader.h
+++ b/logd/LogReader.h
@@ -18,8 +18,10 @@
#define _LOGD_LOG_WRITER_H__
#include <sysutils/SocketListener.h>
-#include "LogBuffer.h"
-#include "LogTimes.h"
+
+#define LOGD_SNDTIMEO 32
+
+class LogBuffer;
class LogReader : public SocketListener {
LogBuffer &mLogbuf;
diff --git a/logd/LogTimes.h b/logd/LogTimes.h
index 1117088..f5969df 100644
--- a/logd/LogTimes.h
+++ b/logd/LogTimes.h
@@ -27,6 +27,7 @@
#include <log/log.h>
class LogReader;
+class LogBufferElement;
class LogTimeEntry {
static pthread_mutex_t timesLock;
diff --git a/logd/tests/logd_test.cpp b/logd/tests/logd_test.cpp
index de19790..2014374 100644
--- a/logd/tests/logd_test.cpp
+++ b/logd/tests/logd_test.cpp
@@ -30,6 +30,8 @@
#include <log/log.h>
#include <log/logger.h>
+#include "../LogReader.h" // pickup LOGD_SNDTIMEO
+
/*
* returns statistics
*/
@@ -253,6 +255,9 @@
fprintf(stderr, "lid=crash ");
break;
case 5:
+ fprintf(stderr, "lid=security ");
+ break;
+ case 6:
fprintf(stderr, "lid=kernel ");
break;
default:
@@ -710,3 +715,56 @@
EXPECT_TRUE(content_timeout);
EXPECT_NE(0U, alarm_timeout);
}
+
+// b/27242723 confirmed fixed
+TEST(logd, SNDTIMEO) {
+ static const unsigned sndtimeo = LOGD_SNDTIMEO; // <sigh> it has to be done!
+ static const unsigned sleep_time = sndtimeo + 3;
+ static const unsigned alarm_time = sleep_time + 5;
+
+ int fd;
+
+ ASSERT_TRUE((fd = socket_local_client("logdr",
+ ANDROID_SOCKET_NAMESPACE_RESERVED,
+ SOCK_SEQPACKET)) > 0);
+
+ struct sigaction ignore, old_sigaction;
+ memset(&ignore, 0, sizeof(ignore));
+ ignore.sa_handler = caught_signal;
+ sigemptyset(&ignore.sa_mask);
+ sigaction(SIGALRM, &ignore, &old_sigaction);
+ unsigned int old_alarm = alarm(alarm_time);
+
+ static const char ask[] = "stream lids=0,1,2,3,4,5,6"; // all sources
+ bool reader_requested = write(fd, ask, sizeof(ask)) == sizeof(ask);
+ EXPECT_TRUE(reader_requested);
+
+ log_msg msg;
+ bool read_one = recv(fd, msg.buf, sizeof(msg), 0) > 0;
+
+ EXPECT_TRUE(read_one);
+ if (read_one) {
+ dump_log_msg("user", &msg, 3, -1);
+ }
+
+ fprintf (stderr, "Sleep for >%d seconds logd SO_SNDTIMEO ...\n", sndtimeo);
+ sleep(sleep_time);
+
+ // flush will block if we did not trigger. if it did, last entry returns 0
+ int recv_ret;
+ do {
+ recv_ret = recv(fd, msg.buf, sizeof(msg), 0);
+ } while (recv_ret > 0);
+ int save_errno = (recv_ret < 0) ? errno : 0;
+
+ EXPECT_NE(0U, alarm(old_alarm));
+ sigaction(SIGALRM, &old_sigaction, NULL);
+
+ EXPECT_EQ(0, recv_ret);
+ if (recv_ret > 0) {
+ dump_log_msg("user", &msg, 3, -1);
+ }
+ EXPECT_EQ(0, save_errno);
+
+ close(fd);
+}
diff --git a/rootdir/init.zygote32_64.rc b/rootdir/init.zygote32_64.rc
index 29bb1cf..4e702a1 100644
--- a/rootdir/init.zygote32_64.rc
+++ b/rootdir/init.zygote32_64.rc
@@ -11,4 +11,4 @@
class main
socket zygote_secondary stream 660 root system
onrestart restart zygote
- writepid /dev/cpuset/foreground/tasks
\ No newline at end of file
+ writepid /dev/cpuset/foreground/tasks
diff --git a/rootdir/init.zygote64_32.rc b/rootdir/init.zygote64_32.rc
index 8ed5e9e..692af99 100644
--- a/rootdir/init.zygote64_32.rc
+++ b/rootdir/init.zygote64_32.rc
@@ -11,4 +11,4 @@
class main
socket zygote_secondary stream 660 root system
onrestart restart zygote
- writepid /dev/cpuset/foreground/tasks
\ No newline at end of file
+ writepid /dev/cpuset/foreground/tasks