am 7d678d8d: Invoke perfprofd daemon (only for userdebug/eng builds).
* commit '7d678d8d78b40c9c7697565637ba5e4dc81ec02f':
Invoke perfprofd daemon (only for userdebug/eng builds).
diff --git a/base/Android.mk b/base/Android.mk
index ad85c6b..7bd317b 100644
--- a/base/Android.mk
+++ b/base/Android.mk
@@ -18,11 +18,13 @@
libbase_src_files := \
file.cpp \
+ logging.cpp \
stringprintf.cpp \
strings.cpp \
libbase_test_src_files := \
file_test.cpp \
+ logging_test.cpp \
stringprintf_test.cpp \
strings_test.cpp \
test_main.cpp \
@@ -38,7 +40,7 @@
include $(CLEAR_VARS)
LOCAL_MODULE := libbase
LOCAL_CLANG := true
-LOCAL_SRC_FILES := $(libbase_src_files) logging.cpp
+LOCAL_SRC_FILES := $(libbase_src_files)
LOCAL_C_INCLUDES := $(LOCAL_PATH)/include
LOCAL_CPPFLAGS := $(libbase_cppflags)
LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/include
@@ -61,9 +63,6 @@
include $(CLEAR_VARS)
LOCAL_MODULE := libbase
LOCAL_SRC_FILES := $(libbase_src_files)
-ifneq ($(HOST_OS),windows)
- LOCAL_SRC_FILES += logging.cpp
-endif
LOCAL_C_INCLUDES := $(LOCAL_PATH)/include
LOCAL_CPPFLAGS := $(libbase_cppflags)
LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/include
@@ -85,7 +84,7 @@
include $(CLEAR_VARS)
LOCAL_MODULE := libbase_test
LOCAL_CLANG := true
-LOCAL_SRC_FILES := $(libbase_test_src_files) logging_test.cpp
+LOCAL_SRC_FILES := $(libbase_test_src_files)
LOCAL_C_INCLUDES := $(LOCAL_PATH)
LOCAL_CPPFLAGS := $(libbase_cppflags)
LOCAL_SHARED_LIBRARIES := libbase
@@ -97,9 +96,6 @@
include $(CLEAR_VARS)
LOCAL_MODULE := libbase_test
LOCAL_SRC_FILES := $(libbase_test_src_files)
-ifneq ($(HOST_OS),windows)
- LOCAL_SRC_FILES += logging_test.cpp
-endif
LOCAL_C_INCLUDES := $(LOCAL_PATH)
LOCAL_CPPFLAGS := $(libbase_cppflags)
LOCAL_SHARED_LIBRARIES := libbase
diff --git a/base/file_test.cpp b/base/file_test.cpp
index e5cf696..b138094 100644
--- a/base/file_test.cpp
+++ b/base/file_test.cpp
@@ -36,7 +36,8 @@
TEST(file, ReadFileToString_success) {
std::string s("hello");
- ASSERT_TRUE(android::base::ReadFileToString("/proc/version", &s)) << errno;
+ ASSERT_TRUE(android::base::ReadFileToString("/proc/version", &s))
+ << strerror(errno);
EXPECT_GT(s.length(), 6U);
EXPECT_EQ('\n', s[s.length() - 1]);
s[5] = 0;
@@ -46,37 +47,44 @@
TEST(file, WriteStringToFile) {
TemporaryFile tf;
ASSERT_TRUE(tf.fd != -1);
- ASSERT_TRUE(android::base::WriteStringToFile("abc", tf.filename)) << errno;
+ ASSERT_TRUE(android::base::WriteStringToFile("abc", tf.filename))
+ << strerror(errno);
std::string s;
- ASSERT_TRUE(android::base::ReadFileToString(tf.filename, &s)) << errno;
+ ASSERT_TRUE(android::base::ReadFileToString(tf.filename, &s))
+ << strerror(errno);
EXPECT_EQ("abc", s);
}
+// WriteStringToFile2 is explicitly for setting Unix permissions, which make no
+// sense on Windows.
+#if !defined(_WIN32)
TEST(file, WriteStringToFile2) {
TemporaryFile tf;
ASSERT_TRUE(tf.fd != -1);
ASSERT_TRUE(android::base::WriteStringToFile("abc", tf.filename, 0660,
getuid(), getgid()))
- << errno;
+ << strerror(errno);
struct stat sb;
ASSERT_EQ(0, stat(tf.filename, &sb));
- ASSERT_EQ(0660U, (sb.st_mode & ~S_IFMT));
+ ASSERT_EQ(0660U, static_cast<unsigned int>(sb.st_mode & ~S_IFMT));
ASSERT_EQ(getuid(), sb.st_uid);
ASSERT_EQ(getgid(), sb.st_gid);
std::string s;
- ASSERT_TRUE(android::base::ReadFileToString(tf.filename, &s)) << errno;
+ ASSERT_TRUE(android::base::ReadFileToString(tf.filename, &s))
+ << strerror(errno);
EXPECT_EQ("abc", s);
}
+#endif
TEST(file, WriteStringToFd) {
TemporaryFile tf;
ASSERT_TRUE(tf.fd != -1);
ASSERT_TRUE(android::base::WriteStringToFd("abc", tf.fd));
- ASSERT_EQ(0, lseek(tf.fd, 0, SEEK_SET)) << errno;
+ ASSERT_EQ(0, lseek(tf.fd, 0, SEEK_SET)) << strerror(errno);
std::string s;
- ASSERT_TRUE(android::base::ReadFdToString(tf.fd, &s)) << errno;
+ ASSERT_TRUE(android::base::ReadFdToString(tf.fd, &s)) << strerror(errno);
EXPECT_EQ("abc", s);
}
@@ -101,6 +109,7 @@
ASSERT_TRUE(tf.fd != -1);
ASSERT_TRUE(android::base::WriteFully(tf.fd, "abc", 3));
std::string s;
- ASSERT_TRUE(android::base::ReadFileToString(tf.filename, &s)) << errno;
+ ASSERT_TRUE(android::base::ReadFileToString(tf.filename, &s))
+ << strerror(errno);
EXPECT_EQ("abc", s);
}
diff --git a/base/logging.cpp b/base/logging.cpp
index 0142b70..83957b3 100644
--- a/base/logging.cpp
+++ b/base/logging.cpp
@@ -27,12 +27,19 @@
#include <iostream>
#include <limits>
-#include <mutex>
#include <sstream>
#include <string>
#include <utility>
#include <vector>
+#ifndef _WIN32
+#include <mutex>
+#else
+#define NOGDI // Suppress the evil ERROR macro.
+#include <windows.h>
+#endif
+
+#include "base/macros.h"
#include "base/strings.h"
#include "cutils/threads.h"
@@ -45,10 +52,79 @@
#include <unistd.h>
#endif
+namespace {
+#ifndef _WIN32
+using std::mutex;
+using std::lock_guard;
+
+#if defined(__GLIBC__)
+const char* getprogname() {
+ return program_invocation_short_name;
+}
+#endif
+
+#else
+const char* getprogname() {
+ static bool first = true;
+ static char progname[MAX_PATH] = {};
+
+ if (first) {
+ // TODO(danalbert): This is a full path on Windows. Just get the basename.
+ DWORD nchars = GetModuleFileName(nullptr, progname, sizeof(progname));
+ DCHECK_GT(nchars, 0U);
+ first = false;
+ }
+
+ return progname;
+}
+
+class mutex {
+ public:
+ mutex() {
+ semaphore_ = CreateSemaphore(nullptr, 1, 1, nullptr);
+ CHECK(semaphore_ != nullptr) << "Failed to create Mutex";
+ }
+ ~mutex() {
+ CloseHandle(semaphore_);
+ }
+
+ void lock() {
+ DWORD result = WaitForSingleObject(semaphore_, INFINITE);
+ CHECK_EQ(result, WAIT_OBJECT_0) << GetLastError();
+ }
+
+ void unlock() {
+ bool result = ReleaseSemaphore(semaphore_, 1, nullptr);
+ CHECK(result);
+ }
+
+ private:
+ HANDLE semaphore_;
+};
+
+template <typename LockT>
+class lock_guard {
+ public:
+ explicit lock_guard(LockT& lock) : lock_(lock) {
+ lock_.lock();
+ }
+
+ ~lock_guard() {
+ lock_.unlock();
+ }
+
+ private:
+ LockT& lock_;
+
+ DISALLOW_COPY_AND_ASSIGN(lock_guard);
+};
+#endif
+} // namespace
+
namespace android {
namespace base {
-static std::mutex logging_lock;
+static mutex logging_lock;
#ifdef __ANDROID__
static LogFunction gLogger = LogdLogger();
@@ -60,12 +136,6 @@
static LogSeverity gMinimumLogSeverity = INFO;
static std::unique_ptr<std::string> gProgramInvocationName;
-#if defined(__GLIBC__)
-static const char* getprogname() {
- return program_invocation_short_name;
-}
-#endif
-
static const char* ProgramInvocationName() {
if (gProgramInvocationName == nullptr) {
gProgramInvocationName.reset(new std::string(getprogname()));
@@ -182,7 +252,7 @@
}
void SetLogger(LogFunction&& logger) {
- std::lock_guard<std::mutex> lock(logging_lock);
+ lock_guard<mutex> lock(logging_lock);
gLogger = std::move(logger);
}
@@ -287,7 +357,7 @@
void LogMessage::LogLine(const char* file, unsigned int line, LogId id,
LogSeverity severity, const char* message) {
const char* tag = ProgramInvocationName();
- std::lock_guard<std::mutex> lock(logging_lock);
+ lock_guard<mutex> lock(logging_lock);
gLogger(id, severity, tag, file, line, message);
}
diff --git a/base/logging_test.cpp b/base/logging_test.cpp
index d947c1d..c91857a 100644
--- a/base/logging_test.cpp
+++ b/base/logging_test.cpp
@@ -85,6 +85,9 @@
TEST(logging, LOG) {
ASSERT_DEATH(LOG(FATAL) << "foobar", "foobar");
+ // We can't usefully check the output of any of these on Windows because we
+ // don't have std::regex, but we can at least make sure we printed at least as
+ // many characters are in the log message.
{
CapturedStderr cap;
LOG(WARNING) << "foobar";
@@ -92,10 +95,13 @@
std::string output;
android::base::ReadFdToString(cap.fd(), &output);
+ ASSERT_GT(output.length(), strlen("foobar"));
+#if !defined(_WIN32)
std::regex message_regex(
make_log_pattern(android::base::WARNING, "foobar"));
ASSERT_TRUE(std::regex_search(output, message_regex));
+#endif
}
{
@@ -105,10 +111,13 @@
std::string output;
android::base::ReadFdToString(cap.fd(), &output);
+ ASSERT_GT(output.length(), strlen("foobar"));
+#if !defined(_WIN32)
std::regex message_regex(
make_log_pattern(android::base::INFO, "foobar"));
ASSERT_TRUE(std::regex_search(output, message_regex));
+#endif
}
{
@@ -129,10 +138,13 @@
std::string output;
android::base::ReadFdToString(cap.fd(), &output);
+ ASSERT_GT(output.length(), strlen("foobar"));
+#if !defined(_WIN32)
std::regex message_regex(
make_log_pattern(android::base::DEBUG, "foobar"));
ASSERT_TRUE(std::regex_search(output, message_regex));
+#endif
}
}
@@ -145,10 +157,13 @@
std::string output;
android::base::ReadFdToString(cap.fd(), &output);
+ ASSERT_GT(output.length(), strlen("foobar"));
+#if !defined(_WIN32)
std::regex message_regex(make_log_pattern(
android::base::INFO, "foobar: No such file or directory"));
ASSERT_TRUE(std::regex_search(output, message_regex));
+#endif
}
}
@@ -161,11 +176,14 @@
std::string output;
android::base::ReadFdToString(cap.fd(), &output);
+ ASSERT_GT(output.length(), strlen("unimplemented"));
+#if !defined(_WIN32)
std::string expected_message =
android::base::StringPrintf("%s unimplemented ", __PRETTY_FUNCTION__);
std::regex message_regex(
make_log_pattern(android::base::ERROR, expected_message.c_str()));
ASSERT_TRUE(std::regex_search(output, message_regex));
+#endif
}
}
diff --git a/base/stringprintf_test.cpp b/base/stringprintf_test.cpp
index 5cc2086..54b2b6c 100644
--- a/base/stringprintf_test.cpp
+++ b/base/stringprintf_test.cpp
@@ -20,11 +20,14 @@
#include <string>
+// The z size sepcifier isn't supported on Windows, so this test isn't useful.
+#if !defined(_WIN32)
TEST(StringPrintfTest, HexSizeT) {
size_t size = 0x00107e59;
EXPECT_EQ("00107e59", android::base::StringPrintf("%08zx", size));
EXPECT_EQ("0x00107e59", android::base::StringPrintf("0x%08zx", size));
}
+#endif
TEST(StringPrintfTest, StringAppendF) {
std::string s("a");
diff --git a/base/test_utils.cpp b/base/test_utils.cpp
index 1f6d3cf..0517bc7 100644
--- a/base/test_utils.cpp
+++ b/base/test_utils.cpp
@@ -16,15 +16,26 @@
#include "test_utils.h"
+#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
+#include <sys/stat.h>
#include <unistd.h>
+#if defined(_WIN32)
+#include <windows.h>
+#endif
+
TemporaryFile::TemporaryFile() {
+#if defined(__ANDROID__)
init("/data/local/tmp");
- if (fd == -1) {
- init("/tmp");
- }
+#elif defined(_WIN32)
+ char wd[MAX_PATH] = {};
+ _getcwd(wd, sizeof(wd));
+ init(wd);
+#else
+ init("/tmp");
+#endif
}
TemporaryFile::~TemporaryFile() {
@@ -34,5 +45,15 @@
void TemporaryFile::init(const char* tmp_dir) {
snprintf(filename, sizeof(filename), "%s/TemporaryFile-XXXXXX", tmp_dir);
+#if !defined(_WIN32)
fd = mkstemp(filename);
+#else
+ // Windows doesn't have mkstemp, and tmpfile creates the file in the root
+ // directory, requiring root (?!) permissions. We have to settle for mktemp.
+ if (mktemp(filename) == nullptr) {
+ abort();
+ }
+
+ fd = open(filename, O_RDWR | O_NOINHERIT | O_CREAT, _S_IREAD | _S_IWRITE);
+#endif
}
diff --git a/fastboot/Android.mk b/fastboot/Android.mk
index 7b2975b..dee471a 100644
--- a/fastboot/Android.mk
+++ b/fastboot/Android.mk
@@ -58,7 +58,8 @@
libsparse_host \
libutils \
liblog \
- libz
+ libz \
+ libbase
ifneq ($(HOST_OS),windows)
LOCAL_STATIC_LIBRARIES += libselinux
diff --git a/fs_mgr/fs_mgr.c b/fs_mgr/fs_mgr.c
index 5f639b7..2201031 100644
--- a/fs_mgr/fs_mgr.c
+++ b/fs_mgr/fs_mgr.c
@@ -31,7 +31,7 @@
#include <dirent.h>
#include <ext4.h>
#include <ext4_sb.h>
-#include <ext4_crypt.h>
+#include <ext4_crypt_init_extensions.h>
#include <linux/loop.h>
#include <private/android_filesystem_config.h>
@@ -486,16 +486,6 @@
return FS_MGR_MNTALL_FAIL;
}
- // Link it to the normal place so ext4_crypt functions work normally
- strlcat(tmp_mnt, "/unencrypted", sizeof(tmp_mnt));
- char link_path[PATH_MAX];
- strlcpy(link_path, rec->mount_point, sizeof(link_path));
- strlcat(link_path, "/unencrypted", sizeof(link_path));
- if (symlink(tmp_mnt, link_path)) {
- ERROR("Error creating symlink to unencrypted directory\n");
- return FS_MGR_MNTALL_FAIL;
- }
-
return FS_MGR_MNTALL_DEV_NON_DEFAULT_FILE_ENCRYPTED;
}
diff --git a/include/cutils/threads.h b/include/cutils/threads.h
index 3133cdb..5727494 100644
--- a/include/cutils/threads.h
+++ b/include/cutils/threads.h
@@ -17,6 +17,14 @@
#ifndef _LIBS_CUTILS_THREADS_H
#define _LIBS_CUTILS_THREADS_H
+#include <sys/types.h>
+
+#if !defined(_WIN32)
+#include <pthread.h>
+#else
+#include <windows.h>
+#endif
+
#ifdef __cplusplus
extern "C" {
#endif
@@ -29,10 +37,9 @@
/***********************************************************************/
/***********************************************************************/
-#if !defined(_WIN32)
+extern pid_t gettid();
-#include <pthread.h>
-#include <sys/types.h>
+#if !defined(_WIN32)
typedef struct {
pthread_mutex_t lock;
@@ -40,14 +47,10 @@
pthread_key_t tls;
} thread_store_t;
-extern pid_t gettid();
-
#define THREAD_STORE_INITIALIZER { PTHREAD_MUTEX_INITIALIZER, 0, 0 }
#else // !defined(_WIN32)
-#include <windows.h>
-
typedef struct {
int lock_init;
int has_tls;
diff --git a/init/Android.mk b/init/Android.mk
index 31d2fcd..485ff35 100644
--- a/init/Android.mk
+++ b/init/Android.mk
@@ -5,9 +5,9 @@
# --
ifneq (,$(filter userdebug eng,$(TARGET_BUILD_VARIANT)))
-init_options += -DALLOW_LOCAL_PROP_OVERRIDE=1 -DALLOW_DISABLE_SELINUX=1
+init_options += -DALLOW_LOCAL_PROP_OVERRIDE=1 -DALLOW_PERMISSIVE_SELINUX=1
else
-init_options += -DALLOW_LOCAL_PROP_OVERRIDE=0 -DALLOW_DISABLE_SELINUX=0
+init_options += -DALLOW_LOCAL_PROP_OVERRIDE=0 -DALLOW_PERMISSIVE_SELINUX=0
endif
init_options += -DLOG_UEVENTS=0
diff --git a/init/builtins.cpp b/init/builtins.cpp
index 4567b04..d772383 100644
--- a/init/builtins.cpp
+++ b/init/builtins.cpp
@@ -29,7 +29,7 @@
#include <sys/wait.h>
#include <unistd.h>
#include <linux/loop.h>
-#include <ext4_crypt.h>
+#include <ext4_crypt_init_extensions.h>
#include <selinux/selinux.h>
#include <selinux/label.h>
@@ -386,18 +386,6 @@
}
/*
- * Callback to make a directory from the ext4 code
- */
-static int do_mount_alls_make_dir(const char* dir)
-{
- if (make_dir(dir, 0700) && errno != EEXIST) {
- return -1;
- }
-
- return 0;
-}
-
-/*
* This function might request a reboot, in which case it will
* not return.
*/
@@ -452,6 +440,7 @@
property_set("vold.decrypt", "trigger_encryption");
} else if (ret == FS_MGR_MNTALL_DEV_MIGHT_BE_ENCRYPTED) {
property_set("ro.crypto.state", "encrypted");
+ property_set("ro.crypto.type", "block");
property_set("vold.decrypt", "trigger_default_encryption");
} else if (ret == FS_MGR_MNTALL_DEV_NOT_ENCRYPTED) {
property_set("ro.crypto.state", "unencrypted");
@@ -465,26 +454,11 @@
ret = wipe_data_via_recovery();
/* If reboot worked, there is no return. */
} else if (ret == FS_MGR_MNTALL_DEV_DEFAULT_FILE_ENCRYPTED) {
- // We have to create the key files here. Only init can call make_dir,
- // and we can't do it from fs_mgr as then fs_mgr would depend on
- // make_dir creating a circular dependency.
- fstab = fs_mgr_read_fstab(args[1]);
- for (int i = 0; i < fstab->num_entries; ++i) {
- if (fs_mgr_is_file_encrypted(&fstab->recs[i])) {
- if (e4crypt_create_device_key(fstab->recs[i].mount_point,
- do_mount_alls_make_dir)) {
- ERROR("Could not create device key on %s"
- " - continue unencrypted\n",
- fstab->recs[i].mount_point);
- }
- }
- }
- fs_mgr_free_fstab(fstab);
-
if (e4crypt_install_keyring()) {
return -1;
}
property_set("ro.crypto.state", "encrypted");
+ property_set("ro.crypto.type", "file");
// Although encrypted, we have device key, so we do not need to
// do anything different from the nonencrypted case.
@@ -494,6 +468,7 @@
return -1;
}
property_set("ro.crypto.state", "encrypted");
+ property_set("ro.crypto.type", "file");
property_set("vold.decrypt", "trigger_restart_min_framework");
} else if (ret > 0) {
ERROR("fs_mgr_mount_all returned unexpected error %d\n", ret);
@@ -840,11 +815,30 @@
return -1;
}
-int do_installkey(int nargs, char **args)
+/*
+ * Callback to make a directory from the ext4 code
+ */
+static int do_installkeys_ensure_dir_exists(const char* dir)
{
- if (nargs == 2) {
- return e4crypt_install_key(args[1]);
+ if (make_dir(dir, 0700) && errno != EEXIST) {
+ return -1;
}
- return -1;
+ return 0;
+}
+
+int do_installkey(int nargs, char **args)
+{
+ if (nargs != 2) {
+ return -1;
+ }
+
+ char prop_value[PROP_VALUE_MAX] = {0};
+ property_get("ro.crypto.type", prop_value);
+ if (strcmp(prop_value, "file")) {
+ return 0;
+ }
+
+ return e4crypt_create_device_key(args[1],
+ do_installkeys_ensure_dir_exists);
}
diff --git a/init/init.cpp b/init/init.cpp
index dd74538..68c8b7f 100644
--- a/init/init.cpp
+++ b/init/init.cpp
@@ -860,7 +860,7 @@
sehandle_prop = selinux_android_prop_context_handle();
}
-enum selinux_enforcing_status { SELINUX_DISABLED, SELINUX_PERMISSIVE, SELINUX_ENFORCING };
+enum selinux_enforcing_status { SELINUX_PERMISSIVE, SELINUX_ENFORCING };
static selinux_enforcing_status selinux_status_from_cmdline() {
selinux_enforcing_status status = SELINUX_ENFORCING;
@@ -870,9 +870,7 @@
if (value == nullptr) { return; }
*value++ = '\0';
if (strcmp(name, "androidboot.selinux") == 0) {
- if (strcmp(value, "disabled") == 0) {
- status = SELINUX_DISABLED;
- } else if (strcmp(value, "permissive") == 0) {
+ if (strcmp(value, "permissive") == 0) {
status = SELINUX_PERMISSIVE;
}
}
@@ -882,24 +880,9 @@
return status;
}
-
-static bool selinux_is_disabled(void)
-{
- if (ALLOW_DISABLE_SELINUX) {
- if (access("/sys/fs/selinux", F_OK) != 0) {
- // SELinux is not compiled into the kernel, or has been disabled
- // via the kernel command line "selinux=0".
- return true;
- }
- return selinux_status_from_cmdline() == SELINUX_DISABLED;
- }
-
- return false;
-}
-
static bool selinux_is_enforcing(void)
{
- if (ALLOW_DISABLE_SELINUX) {
+ if (ALLOW_PERMISSIVE_SELINUX) {
return selinux_status_from_cmdline() == SELINUX_ENFORCING;
}
return true;
@@ -907,10 +890,6 @@
int selinux_reload_policy(void)
{
- if (selinux_is_disabled()) {
- return -1;
- }
-
INFO("SELinux: Attempting to reload policy files\n");
if (selinux_android_reload_policy() == -1) {
@@ -947,10 +926,6 @@
cb.func_audit = audit_callback;
selinux_set_callback(SELINUX_CB_AUDIT, cb);
- if (selinux_is_disabled()) {
- return;
- }
-
if (in_kernel_domain) {
INFO("Loading SELinux policy...\n");
if (selinux_android_load_policy() < 0) {
@@ -958,8 +933,15 @@
security_failure();
}
+ bool kernel_enforcing = (security_getenforce() == 1);
bool is_enforcing = selinux_is_enforcing();
- security_setenforce(is_enforcing);
+ if (kernel_enforcing != is_enforcing) {
+ if (security_setenforce(is_enforcing)) {
+ ERROR("security_setenforce(%s) failed: %s\n",
+ is_enforcing ? "true" : "false", strerror(errno));
+ security_failure();
+ }
+ }
if (write_file("/sys/fs/selinux/checkreqprot", "0") == -1) {
security_failure();
diff --git a/libbacktrace/Android.mk b/libbacktrace/Android.mk
index 54cace9..a2b4cfe 100644
--- a/libbacktrace/Android.mk
+++ b/libbacktrace/Android.mk
@@ -51,18 +51,10 @@
UnwindMap.cpp \
UnwindPtrace.cpp \
-libbacktrace_shared_libraries_target := \
- libcutils \
-
libbacktrace_shared_libraries := \
libbase \
- libunwind \
-
-libbacktrace_shared_libraries_host := \
liblog \
-
-libbacktrace_static_libraries_host := \
- libcutils \
+ libunwind \
libbacktrace_ldlibs_host := \
-lpthread \
diff --git a/libbacktrace/Backtrace.cpp b/libbacktrace/Backtrace.cpp
index d75c210..4e4003e 100644
--- a/libbacktrace/Backtrace.cpp
+++ b/libbacktrace/Backtrace.cpp
@@ -27,6 +27,8 @@
#include <backtrace/Backtrace.h>
#include <backtrace/BacktraceMap.h>
+#include <cutils/threads.h>
+
#include "BacktraceLog.h"
#include "thread_utils.h"
#include "UnwindCurrent.h"
diff --git a/libbacktrace/BacktraceCurrent.cpp b/libbacktrace/BacktraceCurrent.cpp
index fd1f4da..14f04de 100644
--- a/libbacktrace/BacktraceCurrent.cpp
+++ b/libbacktrace/BacktraceCurrent.cpp
@@ -29,6 +29,8 @@
#include <backtrace/Backtrace.h>
#include <backtrace/BacktraceMap.h>
+#include <cutils/threads.h>
+
#include "BacktraceCurrent.h"
#include "BacktraceLog.h"
#include "ThreadEntry.h"
diff --git a/libbacktrace/BacktraceMap.cpp b/libbacktrace/BacktraceMap.cpp
index b0ada46..ca47f67 100644
--- a/libbacktrace/BacktraceMap.cpp
+++ b/libbacktrace/BacktraceMap.cpp
@@ -135,7 +135,7 @@
#if defined(__APPLE__)
// Corkscrew and libunwind don't compile on the mac, so create a generic
// map object.
-BacktraceMap* BacktraceMap::Create(pid_t pid, bool uncached) {
+BacktraceMap* BacktraceMap::Create(pid_t pid, bool /*uncached*/) {
BacktraceMap* map = new BacktraceMap(pid);
if (!map->Build()) {
delete map;
diff --git a/libbacktrace/backtrace_test.cpp b/libbacktrace/backtrace_test.cpp
index ebcb1f8..28d146a 100644
--- a/libbacktrace/backtrace_test.cpp
+++ b/libbacktrace/backtrace_test.cpp
@@ -30,20 +30,21 @@
#include <time.h>
#include <unistd.h>
-#include <backtrace/Backtrace.h>
-#include <backtrace/BacktraceMap.h>
-
-// For the THREAD_SIGNAL definition.
-#include "BacktraceCurrent.h"
-
-#include <cutils/atomic.h>
-#include <gtest/gtest.h>
-
#include <algorithm>
#include <memory>
#include <string>
#include <vector>
+#include <backtrace/Backtrace.h>
+#include <backtrace/BacktraceMap.h>
+
+#include <cutils/atomic.h>
+#include <cutils/threads.h>
+
+#include <gtest/gtest.h>
+
+// For the THREAD_SIGNAL definition.
+#include "BacktraceCurrent.h"
#include "thread_utils.h"
// Number of microseconds per milliseconds.
diff --git a/libbacktrace/thread_utils.c b/libbacktrace/thread_utils.c
index 6f4cd3c..e75f56e 100644
--- a/libbacktrace/thread_utils.c
+++ b/libbacktrace/thread_utils.c
@@ -16,25 +16,12 @@
#include "thread_utils.h"
-#if defined(__APPLE__)
+#if !defined(__BIONIC__)
-#include <sys/syscall.h>
-
-// Mac OS >= 10.6 has a system call equivalent to Linux's gettid().
-pid_t gettid() {
- return syscall(SYS_thread_selfid);
-}
-
-#elif !defined(__BIONIC__)
-
-// glibc doesn't implement or export either gettid or tgkill.
+// glibc doesn't implement or export tgkill.
#include <unistd.h>
#include <sys/syscall.h>
-pid_t gettid() {
- return syscall(__NR_gettid);
-}
-
int tgkill(int tgid, int tid, int sig) {
return syscall(__NR_tgkill, tgid, tid, sig);
}
diff --git a/libbacktrace/thread_utils.h b/libbacktrace/thread_utils.h
index ae4c929..df83581 100644
--- a/libbacktrace/thread_utils.h
+++ b/libbacktrace/thread_utils.h
@@ -23,8 +23,6 @@
int tgkill(int tgid, int tid, int sig);
-pid_t gettid();
-
__END_DECLS
#endif /* _LIBBACKTRACE_THREAD_UTILS_H */
diff --git a/libcutils/threads.c b/libcutils/threads.c
index 5f5577b..036f8c5 100644
--- a/libcutils/threads.c
+++ b/libcutils/threads.c
@@ -16,8 +16,6 @@
#include "cutils/threads.h"
-#if !defined(_WIN32)
-
// For gettid.
#if defined(__APPLE__)
#include "AvailabilityMacros.h" // For MAC_OS_X_VERSION_MAX_ALLOWED
@@ -30,9 +28,24 @@
#include <syscall.h>
#include <unistd.h>
#elif defined(_WIN32)
-#include <Windows.h>
+#include <windows.h>
#endif
+// No definition needed for Android because we'll just pick up bionic's copy.
+#ifndef __ANDROID__
+pid_t gettid() {
+#if defined(__APPLE__)
+ return syscall(SYS_thread_selfid);
+#elif defined(__linux__)
+ return syscall(__NR_gettid);
+#elif defined(_WIN32)
+ return GetCurrentThreadId();
+#endif
+}
+#endif // __ANDROID__
+
+#if !defined(_WIN32)
+
void* thread_store_get( thread_store_t* store )
{
if (!store->has_tls)
@@ -58,24 +71,6 @@
pthread_setspecific( store->tls, value );
}
-// No definition needed for Android because we'll just pick up bionic's copy.
-#ifndef __ANDROID__
-pid_t gettid() {
-#if defined(__APPLE__)
- uint64_t owner;
- int rc = pthread_threadid_np(NULL, &owner);
- if (rc != 0) {
- abort();
- }
- return owner;
-#elif defined(__linux__)
- return syscall(__NR_gettid);
-#elif defined(_WIN32)
- return (pid_t)GetCurrentThreadId();
-#endif
-}
-#endif // __ANDROID__
-
#else /* !defined(_WIN32) */
void* thread_store_get( thread_store_t* store )
{
diff --git a/libsparse/simg_dump.py b/libsparse/simg_dump.py
index 6ece31d..c70d45f 100755
--- a/libsparse/simg_dump.py
+++ b/libsparse/simg_dump.py
@@ -135,7 +135,7 @@
break;
else:
crc_bin = FH.read(4)
- crc = struct.unpack("<I", crc)
+ crc = struct.unpack("<I", crc_bin)
print("Unverified CRC32 0x%08X" % (crc))
else:
print("Unknown chunk type 0x%04X" % (chunk_type), end="")
diff --git a/libziparchive/zip_archive.cc b/libziparchive/zip_archive.cc
index 8582344..79c4c53 100644
--- a/libziparchive/zip_archive.cc
+++ b/libziparchive/zip_archive.cc
@@ -30,6 +30,7 @@
#include <memory>
#include <vector>
+#include "base/file.h"
#include "base/macros.h" // TEMP_FAILURE_RETRY may or may not be in unistd
#include "base/memory.h"
#include "log/log.h"
@@ -85,7 +86,8 @@
// Length of the central directory comment.
uint16_t comment_length;
private:
- DISALLOW_IMPLICIT_CONSTRUCTORS(EocdRecord);
+ EocdRecord() = default;
+ DISALLOW_COPY_AND_ASSIGN(EocdRecord);
} __attribute__((packed));
// A structure representing the fixed length fields for a single
@@ -138,7 +140,8 @@
// beginning of this archive.
uint32_t local_file_header_offset;
private:
- DISALLOW_IMPLICIT_CONSTRUCTORS(CentralDirectoryRecord);
+ CentralDirectoryRecord() = default;
+ DISALLOW_COPY_AND_ASSIGN(CentralDirectoryRecord);
} __attribute__((packed));
// The local file header for a given entry. This duplicates information
@@ -175,7 +178,8 @@
// will appear immediately after the entry file name.
uint16_t extra_field_length;
private:
- DISALLOW_IMPLICIT_CONSTRUCTORS(LocalFileHeader);
+ LocalFileHeader() = default;
+ DISALLOW_COPY_AND_ASSIGN(LocalFileHeader);
} __attribute__((packed));
struct DataDescriptor {
@@ -189,10 +193,10 @@
// Uncompressed size of the entry.
uint32_t uncompressed_size;
private:
- DISALLOW_IMPLICIT_CONSTRUCTORS(DataDescriptor);
+ DataDescriptor() = default;
+ DISALLOW_COPY_AND_ASSIGN(DataDescriptor);
} __attribute__((packed));
-#undef DISALLOW_IMPLICIT_CONSTRUCTORS
static const uint32_t kGPBDDFlagMask = 0x0008; // mask value that signifies that the entry has a DD
@@ -265,8 +269,6 @@
static const int32_t kErrorMessageLowerBound = -13;
-static const char kTempMappingFileName[] = "zip: ExtractFileToFile";
-
/*
* A Read-only Zip archive.
*
@@ -324,35 +326,6 @@
}
};
-static int32_t CopyFileToFile(int fd, uint8_t* begin, const uint32_t length, uint64_t *crc_out) {
- static const uint32_t kBufSize = 32768;
- uint8_t buf[kBufSize];
-
- uint32_t count = 0;
- uint64_t crc = 0;
- while (count < length) {
- uint32_t remaining = length - count;
-
- // Safe conversion because kBufSize is narrow enough for a 32 bit signed
- // value.
- ssize_t get_size = (remaining > kBufSize) ? kBufSize : remaining;
- ssize_t actual = TEMP_FAILURE_RETRY(read(fd, buf, get_size));
-
- if (actual != get_size) {
- ALOGW("CopyFileToFile: copy read failed (" ZD " vs " ZD ")", actual, get_size);
- return kIoError;
- }
-
- memcpy(begin + count, buf, get_size);
- crc = crc32(crc, buf, get_size);
- count += get_size;
- }
-
- *crc_out = crc;
-
- return 0;
-}
-
/*
* Round up to the next highest power of 2.
*
@@ -972,6 +945,117 @@
return kIterationEnd;
}
+class Writer {
+ public:
+ virtual bool Append(uint8_t* buf, size_t buf_size) = 0;
+ virtual ~Writer() {}
+ protected:
+ Writer() = default;
+ private:
+ DISALLOW_COPY_AND_ASSIGN(Writer);
+};
+
+// A Writer that writes data to a fixed size memory region.
+// The size of the memory region must be equal to the total size of
+// the data appended to it.
+class MemoryWriter : public Writer {
+ public:
+ MemoryWriter(uint8_t* buf, size_t size) : Writer(),
+ buf_(buf), size_(size), bytes_written_(0) {
+ }
+
+ virtual bool Append(uint8_t* buf, size_t buf_size) override {
+ if (bytes_written_ + buf_size > size_) {
+ ALOGW("Zip: Unexpected size " ZD " (declared) vs " ZD " (actual)",
+ size_, bytes_written_ + buf_size);
+ return false;
+ }
+
+ memcpy(buf_ + bytes_written_, buf, buf_size);
+ bytes_written_ += buf_size;
+ return true;
+ }
+
+ private:
+ uint8_t* const buf_;
+ const size_t size_;
+ size_t bytes_written_;
+};
+
+// A Writer that appends data to a file |fd| at its current position.
+// The file will be truncated to the end of the written data.
+class FileWriter : public Writer {
+ public:
+
+ // Creates a FileWriter for |fd| and prepare to write |entry| to it,
+ // guaranteeing that the file descriptor is valid and that there's enough
+ // space on the volume to write out the entry completely and that the file
+ // is truncated to the correct length.
+ //
+ // Returns a valid FileWriter on success, |nullptr| if an error occurred.
+ static std::unique_ptr<FileWriter> Create(int fd, const ZipEntry* entry) {
+ const uint32_t declared_length = entry->uncompressed_length;
+ const off64_t current_offset = lseek64(fd, 0, SEEK_CUR);
+ if (current_offset == -1) {
+ ALOGW("Zip: unable to seek to current location on fd %d: %s", fd, strerror(errno));
+ return nullptr;
+ }
+
+ int result = 0;
+#if defined(__linux__)
+ if (declared_length > 0) {
+ // Make sure we have enough space on the volume to extract the compressed
+ // entry. Note that the call to ftruncate below will change the file size but
+ // will not allocate space on disk and this call to fallocate will not
+ // change the file size.
+ result = TEMP_FAILURE_RETRY(fallocate(fd, 0, current_offset, declared_length));
+ if (result == -1) {
+ ALOGW("Zip: unable to allocate space for file to %" PRId64 ": %s",
+ static_cast<int64_t>(declared_length + current_offset), strerror(errno));
+ return std::unique_ptr<FileWriter>(nullptr);
+ }
+ }
+#endif // __linux__
+
+ result = TEMP_FAILURE_RETRY(ftruncate(fd, declared_length + current_offset));
+ if (result == -1) {
+ ALOGW("Zip: unable to truncate file to %" PRId64 ": %s",
+ static_cast<int64_t>(declared_length + current_offset), strerror(errno));
+ return std::unique_ptr<FileWriter>(nullptr);
+ }
+
+ return std::unique_ptr<FileWriter>(new FileWriter(fd, declared_length));
+ }
+
+ virtual bool Append(uint8_t* buf, size_t buf_size) override {
+ if (total_bytes_written_ + buf_size > declared_length_) {
+ ALOGW("Zip: Unexpected size " ZD " (declared) vs " ZD " (actual)",
+ declared_length_, total_bytes_written_ + buf_size);
+ return false;
+ }
+
+ const bool result = android::base::WriteFully(fd_, buf, buf_size);
+ if (result) {
+ total_bytes_written_ += buf_size;
+ } else {
+ ALOGW("Zip: unable to write " ZD " bytes to file; %s", buf_size, strerror(errno));
+ }
+
+ return result;
+ }
+ private:
+ FileWriter(const int fd, const size_t declared_length) :
+ Writer(),
+ fd_(fd),
+ declared_length_(declared_length),
+ total_bytes_written_(0) {
+ }
+
+ const int fd_;
+ const size_t declared_length_;
+ size_t total_bytes_written_;
+};
+
// This method is using libz macros with old-style-casts
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wold-style-cast"
@@ -980,9 +1064,8 @@
}
#pragma GCC diagnostic pop
-static int32_t InflateToFile(int fd, const ZipEntry* entry,
- uint8_t* begin, uint32_t length,
- uint64_t* crc_out) {
+static int32_t InflateEntryToWriter(int fd, const ZipEntry* entry,
+ Writer* writer, uint64_t* crc_out) {
const size_t kBufSize = 32768;
std::vector<uint8_t> read_buf(kBufSize);
std::vector<uint8_t> write_buf(kBufSize);
@@ -1027,7 +1110,6 @@
const uint32_t uncompressed_length = entry->uncompressed_length;
uint32_t compressed_length = entry->compressed_length;
- uint32_t write_count = 0;
do {
/* read as much as we can */
if (zstream.avail_in == 0) {
@@ -1057,12 +1139,10 @@
if (zstream.avail_out == 0 ||
(zerr == Z_STREAM_END && zstream.avail_out != kBufSize)) {
const size_t write_size = zstream.next_out - &write_buf[0];
- // The file might have declared a bogus length.
- if (write_size + write_count > length) {
- return -1;
+ if (!writer->Append(&write_buf[0], write_size)) {
+ // The file might have declared a bogus length.
+ return kInconsistentInformation;
}
- memcpy(begin + write_count, &write_buf[0], write_size);
- write_count += write_size;
zstream.next_out = &write_buf[0];
zstream.avail_out = kBufSize;
@@ -1083,8 +1163,41 @@
return 0;
}
-int32_t ExtractToMemory(ZipArchiveHandle handle,
- ZipEntry* entry, uint8_t* begin, uint32_t size) {
+static int32_t CopyEntryToWriter(int fd, const ZipEntry* entry, Writer* writer,
+ uint64_t *crc_out) {
+ static const uint32_t kBufSize = 32768;
+ std::vector<uint8_t> buf(kBufSize);
+
+ const uint32_t length = entry->uncompressed_length;
+ uint32_t count = 0;
+ uint64_t crc = 0;
+ while (count < length) {
+ uint32_t remaining = length - count;
+
+ // Safe conversion because kBufSize is narrow enough for a 32 bit signed
+ // value.
+ const ssize_t block_size = (remaining > kBufSize) ? kBufSize : remaining;
+ const ssize_t actual = TEMP_FAILURE_RETRY(read(fd, &buf[0], block_size));
+
+ if (actual != block_size) {
+ ALOGW("CopyFileToFile: copy read failed (" ZD " vs " ZD ")", actual, block_size);
+ return kIoError;
+ }
+
+ if (!writer->Append(&buf[0], block_size)) {
+ return kIoError;
+ }
+ crc = crc32(crc, &buf[0], block_size);
+ count += block_size;
+ }
+
+ *crc_out = crc;
+
+ return 0;
+}
+
+int32_t ExtractToWriter(ZipArchiveHandle handle,
+ ZipEntry* entry, Writer* writer) {
ZipArchive* archive = reinterpret_cast<ZipArchive*>(handle);
const uint16_t method = entry->method;
off64_t data_offset = entry->offset;
@@ -1098,9 +1211,9 @@
int32_t return_value = -1;
uint64_t crc = 0;
if (method == kCompressStored) {
- return_value = CopyFileToFile(archive->fd, begin, size, &crc);
+ return_value = CopyEntryToWriter(archive->fd, entry, writer, &crc);
} else if (method == kCompressDeflated) {
- return_value = InflateToFile(archive->fd, entry, begin, size, &crc);
+ return_value = InflateEntryToWriter(archive->fd, entry, writer, &crc);
}
if (!return_value && entry->has_data_descriptor) {
@@ -1120,55 +1233,20 @@
return return_value;
}
+int32_t ExtractToMemory(ZipArchiveHandle handle, ZipEntry* entry,
+ uint8_t* begin, uint32_t size) {
+ std::unique_ptr<Writer> writer(new MemoryWriter(begin, size));
+ return ExtractToWriter(handle, entry, writer.get());
+}
+
int32_t ExtractEntryToFile(ZipArchiveHandle handle,
ZipEntry* entry, int fd) {
- const uint32_t declared_length = entry->uncompressed_length;
-
- const off64_t current_offset = lseek64(fd, 0, SEEK_CUR);
- if (current_offset == -1) {
- ALOGW("Zip: unable to seek to current location on fd %d: %s", fd,
- strerror(errno));
+ std::unique_ptr<Writer> writer(FileWriter::Create(fd, entry));
+ if (writer.get() == nullptr) {
return kIoError;
}
- int result = 0;
-#if defined(__linux__)
- // Make sure we have enough space on the volume to extract the compressed
- // entry. Note that the call to ftruncate below will change the file size but
- // will not allocate space on disk.
- if (declared_length > 0) {
- result = TEMP_FAILURE_RETRY(fallocate(fd, 0, current_offset, declared_length));
- if (result == -1) {
- ALOGW("Zip: unable to allocate space for file to %" PRId64 ": %s",
- static_cast<int64_t>(declared_length + current_offset), strerror(errno));
- return kIoError;
- }
- }
-#endif // defined(__linux__)
-
- result = TEMP_FAILURE_RETRY(ftruncate(fd, declared_length + current_offset));
- if (result == -1) {
- ALOGW("Zip: unable to truncate file to %" PRId64 ": %s",
- static_cast<int64_t>(declared_length + current_offset), strerror(errno));
- return kIoError;
- }
-
- // Don't attempt to map a region of length 0. We still need the
- // ftruncate() though, since the API guarantees that we will truncate
- // the file to the end of the uncompressed output.
- if (declared_length == 0) {
- return 0;
- }
-
- android::FileMap map;
- if (!map.create(kTempMappingFileName, fd, current_offset, declared_length, false)) {
- return kMmapFailed;
- }
-
- const int32_t error = ExtractToMemory(handle, entry,
- reinterpret_cast<uint8_t*>(map.getDataPtr()),
- map.getDataLength());
- return error;
+ return ExtractToWriter(handle, entry, writer.get());
}
const char* ErrorCodeString(int32_t error_code) {
diff --git a/libziparchive/zip_archive_test.cc b/libziparchive/zip_archive_test.cc
index 64faa6d..f8952ce 100644
--- a/libziparchive/zip_archive_test.cc
+++ b/libziparchive/zip_archive_test.cc
@@ -23,6 +23,7 @@
#include <unistd.h>
#include <vector>
+#include <base/file.h>
#include <gtest/gtest.h>
static std::string test_data_dir;
@@ -228,6 +229,44 @@
0x54557478, 0x13030005, 0x7552e25c, 0x01000b78, 0x00428904, 0x13880400,
0x4b500000, 0x00000605, 0x00010000, 0x004f0001, 0x00430000, 0x00000000 };
+// This is a zip file containing a single entry (ab.txt) that contains
+// 90072 repetitions of the string "ab\n" and has an uncompressed length
+// of 270216 bytes.
+static const uint16_t kAbZip[] = {
+ 0x4b50, 0x0403, 0x0014, 0x0000, 0x0008, 0x51d2, 0x4698, 0xc4b0,
+ 0x2cda, 0x011b, 0x0000, 0x1f88, 0x0004, 0x0006, 0x001c, 0x6261,
+ 0x742e, 0x7478, 0x5455, 0x0009, 0x7c03, 0x3a09, 0x7c55, 0x3a09,
+ 0x7555, 0x0b78, 0x0100, 0x8904, 0x0042, 0x0400, 0x1388, 0x0000,
+ 0xc2ed, 0x0d31, 0x0000, 0x030c, 0x7fa0, 0x3b2e, 0x22ff, 0xa2aa,
+ 0x841f, 0x45fc, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555,
+ 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555,
+ 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555,
+ 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555,
+ 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555,
+ 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555,
+ 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555,
+ 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555,
+ 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555,
+ 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555,
+ 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555,
+ 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555,
+ 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555,
+ 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555,
+ 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555,
+ 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555,
+ 0x5555, 0x5555, 0x5555, 0x5555, 0xdd55, 0x502c, 0x014b, 0x1e02,
+ 0x1403, 0x0000, 0x0800, 0xd200, 0x9851, 0xb046, 0xdac4, 0x1b2c,
+ 0x0001, 0x8800, 0x041f, 0x0600, 0x1800, 0x0000, 0x0000, 0x0100,
+ 0x0000, 0xa000, 0x0081, 0x0000, 0x6100, 0x2e62, 0x7874, 0x5574,
+ 0x0554, 0x0300, 0x097c, 0x553a, 0x7875, 0x000b, 0x0401, 0x4289,
+ 0x0000, 0x8804, 0x0013, 0x5000, 0x054b, 0x0006, 0x0000, 0x0100,
+ 0x0100, 0x4c00, 0x0000, 0x5b00, 0x0001, 0x0000, 0x0000
+};
+
+static const uint8_t kAbTxtName[] = { 'a', 'b', '.', 't', 'x', 't' };
+static const uint16_t kAbTxtNameLength = sizeof(kAbTxtName);
+static const size_t kAbUncompressedSize = 270216;
+
static int make_temporary_file(const char* file_name_pattern) {
char full_path[1024];
// Account for differences between the host and the target.
@@ -275,6 +314,55 @@
close(output_fd);
}
+TEST(ziparchive, EntryLargerThan32K) {
+ char temp_file_pattern[] = "entry_larger_than_32k_test_XXXXXX";
+ int fd = make_temporary_file(temp_file_pattern);
+ ASSERT_NE(-1, fd);
+ ASSERT_TRUE(android::base::WriteFully(fd, reinterpret_cast<const uint8_t*>(kAbZip),
+ sizeof(kAbZip) - 1));
+ ZipArchiveHandle handle;
+ ASSERT_EQ(0, OpenArchiveFd(fd, "EntryLargerThan32KTest", &handle));
+
+ ZipEntry entry;
+ ZipEntryName ab_name;
+ ab_name.name = kAbTxtName;
+ ab_name.name_length = kAbTxtNameLength;
+ ASSERT_EQ(0, FindEntry(handle, ab_name, &entry));
+ ASSERT_EQ(kAbUncompressedSize, entry.uncompressed_length);
+
+ // Extract the entry to memory.
+ std::vector<uint8_t> buffer(kAbUncompressedSize);
+ ASSERT_EQ(0, ExtractToMemory(handle, &entry, &buffer[0], buffer.size()));
+
+ // Extract the entry to a file.
+ char output_file_pattern[] = "entry_larger_than_32k_test_output_XXXXXX";
+ int output_fd = make_temporary_file(output_file_pattern);
+ ASSERT_NE(-1, output_fd);
+ ASSERT_EQ(0, ExtractEntryToFile(handle, &entry, output_fd));
+
+ // Make sure the extracted file size is as expected.
+ struct stat stat_buf;
+ ASSERT_EQ(0, fstat(output_fd, &stat_buf));
+ ASSERT_EQ(kAbUncompressedSize, static_cast<size_t>(stat_buf.st_size));
+
+ // Read the file back to a buffer and make sure the contents are
+ // the same as the memory buffer we extracted directly to.
+ std::vector<uint8_t> file_contents(kAbUncompressedSize);
+ ASSERT_EQ(0, lseek64(output_fd, 0, SEEK_SET));
+ ASSERT_TRUE(android::base::ReadFully(output_fd, &file_contents[0], file_contents.size()));
+ ASSERT_EQ(file_contents, buffer);
+
+ for (int i = 0; i < 90072; ++i) {
+ const uint8_t* line = &file_contents[0] + (3 * i);
+ ASSERT_EQ('a', line[0]);
+ ASSERT_EQ('b', line[1]);
+ ASSERT_EQ('\n', line[2]);
+ }
+
+ close(fd);
+ close(output_fd);
+}
+
TEST(ziparchive, TrailerAfterEOCD) {
char temp_file_pattern[] = "trailer_after_eocd_test_XXXXXX";
int fd = make_temporary_file(temp_file_pattern);
diff --git a/rootdir/init.rc b/rootdir/init.rc
index 02b3656..9fdb8e3 100644
--- a/rootdir/init.rc
+++ b/rootdir/init.rc
@@ -223,17 +223,19 @@
mkdir /cache/lost+found 0770 root root
on post-fs-data
- installkey /data
-
# We chown/chmod /data again so because mount is run as root + defaults
chown system system /data
chmod 0771 /data
# We restorecon /data in case the userdata partition has been reset.
restorecon /data
+ # Make sure we have the device encryption key
+ start logd
+ start vold
+ installkey /data
+
# Emulated internal storage area
mkdir /data/media 0770 media_rw media_rw
-
# Start bootcharting as soon as possible after the data partition is
# mounted to collect more data.
mkdir /data/bootchart 0755 shell shell
@@ -456,7 +458,6 @@
class_start main
on property:vold.decrypt=trigger_restart_framework
- installkey /data
class_start main
class_start late_start