Merge "adb: win32: fix adb emu command"
diff --git a/fs_mgr/fs_mgr_verity.c b/fs_mgr/fs_mgr_verity.c
index 6ef46ba..63b23b9 100644
--- a/fs_mgr/fs_mgr_verity.c
+++ b/fs_mgr/fs_mgr_verity.c
@@ -934,10 +934,6 @@
struct dm_ioctl *io = (struct dm_ioctl *) buffer;
char *mount_point = basename(fstab->mount_point);
- // set the dm_ioctl flags
- io->flags |= 1;
- io->target_count = 1;
-
// get verity filesystem size
if (get_fs_size(fstab->fs_type, fstab->blk_device, &device_size) < 0) {
return retval;
diff --git a/init/init.cpp b/init/init.cpp
index 68c8b7f..4f46560 100644
--- a/init/init.cpp
+++ b/init/init.cpp
@@ -43,6 +43,7 @@
#include <base/file.h>
#include <base/stringprintf.h>
+#include <base/strings.h>
#include <cutils/android_reboot.h>
#include <cutils/fs.h>
#include <cutils/iosched_policy.h>
@@ -205,16 +206,15 @@
return;
}
- struct stat s;
- if (stat(svc->args[0], &s) != 0) {
- ERROR("cannot find '%s', disabling '%s'\n", svc->args[0], svc->name);
+ struct stat sb;
+ if (stat(svc->args[0], &sb) == -1) {
+ ERROR("cannot find '%s' (%s), disabling '%s'\n", svc->args[0], strerror(errno), svc->name);
svc->flags |= SVC_DISABLED;
return;
}
if ((!(svc->flags & SVC_ONESHOT)) && dynamic_args) {
- ERROR("service '%s' must be one-shot to use dynamic args, disabling\n",
- svc->args[0]);
+ ERROR("service '%s' must be one-shot to use dynamic args, disabling\n", svc->args[0]);
svc->flags |= SVC_DISABLED;
return;
}
@@ -746,36 +746,20 @@
return 0;
}
-static void import_kernel_nv(char *name, bool for_emulator)
-{
- char *value = strchr(name, '=');
- int name_len = strlen(name);
-
- if (value == 0) return;
- *value++ = 0;
- if (name_len == 0) return;
+static void import_kernel_nv(const std::string& key, const std::string& value, bool for_emulator) {
+ if (key.empty()) return;
if (for_emulator) {
- /* in the emulator, export any kernel option with the
- * ro.kernel. prefix */
- char buff[PROP_NAME_MAX];
- int len = snprintf( buff, sizeof(buff), "ro.kernel.%s", name );
-
- if (len < (int)sizeof(buff))
- property_set( buff, value );
+ // In the emulator, export any kernel option with the "ro.kernel." prefix.
+ property_set(android::base::StringPrintf("ro.kernel.%s", key.c_str()).c_str(), value.c_str());
return;
}
- if (!strcmp(name,"qemu")) {
- strlcpy(qemu, value, sizeof(qemu));
- } else if (!strncmp(name, "androidboot.", 12) && name_len > 12) {
- const char *boot_prop_name = name + 12;
- char prop[PROP_NAME_MAX];
- int cnt;
-
- cnt = snprintf(prop, sizeof(prop), "ro.boot.%s", boot_prop_name);
- if (cnt < PROP_NAME_MAX)
- property_set(prop, value);
+ if (key == "qemu") {
+ strlcpy(qemu, value.c_str(), sizeof(qemu));
+ } else if (android::base::StartsWith(key, "androidboot.")) {
+ property_set(android::base::StringPrintf("ro.boot.%s", key.c_str() + 12).c_str(),
+ value.c_str());
}
}
@@ -799,8 +783,7 @@
}
}
-static void process_kernel_dt(void)
-{
+static void process_kernel_dt() {
static const char android_dir[] = "/proc/device-tree/firmware/android";
std::string file_name = android::base::StringPrintf("%s/compatible", android_dir);
@@ -813,13 +796,13 @@
}
std::unique_ptr<DIR, int(*)(DIR*)>dir(opendir(android_dir), closedir);
- if (!dir)
- return;
+ if (!dir) return;
struct dirent *dp;
while ((dp = readdir(dir.get())) != NULL) {
- if (dp->d_type != DT_REG || !strcmp(dp->d_name, "compatible"))
+ if (dp->d_type != DT_REG || !strcmp(dp->d_name, "compatible")) {
continue;
+ }
file_name = android::base::StringPrintf("%s/%s", android_dir, dp->d_name);
@@ -831,18 +814,15 @@
}
}
-static void process_kernel_cmdline(void)
-{
- /* don't expose the raw commandline to nonpriv processes */
+static void process_kernel_cmdline() {
+ // Don't expose the raw commandline to unprivileged processes.
chmod("/proc/cmdline", 0440);
- /* first pass does the common stuff, and finds if we are in qemu.
- * second pass is only necessary for qemu to export all kernel params
- * as props.
- */
+ // The first pass does the common stuff, and finds if we are in qemu.
+ // The second pass is only necessary for qemu to export all kernel params
+ // as properties.
import_kernel_cmdline(false, import_kernel_nv);
- if (qemu[0])
- import_kernel_cmdline(true, import_kernel_nv);
+ if (qemu[0]) import_kernel_cmdline(true, import_kernel_nv);
}
static int queue_property_triggers_action(int nargs, char **args)
@@ -865,17 +845,11 @@
static selinux_enforcing_status selinux_status_from_cmdline() {
selinux_enforcing_status status = SELINUX_ENFORCING;
- std::function<void(char*,bool)> fn = [&](char* name, bool in_qemu) {
- char *value = strchr(name, '=');
- if (value == nullptr) { return; }
- *value++ = '\0';
- if (strcmp(name, "androidboot.selinux") == 0) {
- if (strcmp(value, "permissive") == 0) {
- status = SELINUX_PERMISSIVE;
- }
+ import_kernel_cmdline(false, [&](const std::string& key, const std::string& value, bool in_qemu) {
+ if (key == "androidboot.selinux" && value == "permissive") {
+ status = SELINUX_PERMISSIVE;
}
- };
- import_kernel_cmdline(false, fn);
+ });
return status;
}
@@ -989,7 +963,7 @@
klog_init();
klog_set_level(KLOG_NOTICE_LEVEL);
- NOTICE("init%s started!\n", is_first_stage ? "" : " second stage");
+ NOTICE("init %s started!\n", is_first_stage ? "first stage" : "second stage");
if (!is_first_stage) {
// Indicate that booting is in progress to background fw loaders, etc.
@@ -1002,7 +976,7 @@
process_kernel_dt();
process_kernel_cmdline();
- // Propogate the kernel variables to internal variables
+ // Propagate the kernel variables to internal variables
// used by init as well as the current required properties.
export_kernel_boot_props();
}
@@ -1028,7 +1002,7 @@
// These directories were necessarily created before initial policy load
// and therefore need their security context restored to the proper value.
// This must happen before /dev is populated by ueventd.
- INFO("Running restorecon...\n");
+ NOTICE("Running restorecon...\n");
restorecon("/dev");
restorecon("/dev/socket");
restorecon("/dev/__properties__");
diff --git a/init/init_parser.cpp b/init/init_parser.cpp
index b76b04e..e5b3b58 100644
--- a/init/init_parser.cpp
+++ b/init/init_parser.cpp
@@ -426,29 +426,27 @@
parser_done:
list_for_each(node, &import_list) {
- struct import *import = node_to_item(node, struct import, list);
- int ret;
-
- ret = init_parse_config_file(import->filename);
- if (ret)
- ERROR("could not import file '%s' from '%s'\n",
- import->filename, fn);
+ struct import* import = node_to_item(node, struct import, list);
+ if (!init_parse_config_file(import->filename)) {
+ ERROR("could not import file '%s' from '%s': %s\n",
+ import->filename, fn, strerror(errno));
+ }
}
}
-int init_parse_config_file(const char* path) {
+bool init_parse_config_file(const char* path) {
INFO("Parsing %s...\n", path);
Timer t;
std::string data;
if (!read_file(path, &data)) {
- return -1;
+ return false;
}
parse_config(path, data);
dump_parser_state();
NOTICE("(Parsing %s took %.2fs.)\n", path, t.duration());
- return 0;
+ return true;
}
static int valid_name(const char *name)
diff --git a/init/init_parser.h b/init/init_parser.h
index 6348607..90f880f 100644
--- a/init/init_parser.h
+++ b/init/init_parser.h
@@ -31,7 +31,7 @@
void queue_all_property_triggers();
void queue_builtin_action(int (*func)(int nargs, char **args), const char *name);
-int init_parse_config_file(const char *fn);
+bool init_parse_config_file(const char* path);
int expand_props(char *dst, const char *src, int len);
service* make_exec_oneshot_service(int argc, char** argv);
diff --git a/init/log.cpp b/init/log.cpp
index d32f2da..eb5ec42 100644
--- a/init/log.cpp
+++ b/init/log.cpp
@@ -14,30 +14,35 @@
* limitations under the License.
*/
+#include "log.h"
+
#include <stdlib.h>
#include <string.h>
#include <sys/uio.h>
#include <selinux/selinux.h>
-#include "log.h"
+#include <base/stringprintf.h>
static void init_klog_vwrite(int level, const char* fmt, va_list ap) {
static const char* tag = basename(getprogname());
- char prefix[64];
- snprintf(prefix, sizeof(prefix), "<%d>%s: ", level, tag);
+ // The kernel's printk buffer is only 1024 bytes.
+ // TODO: should we automatically break up long lines into multiple lines?
+ // Or we could log but with something like "..." at the end?
+ char buf[1024];
+ size_t prefix_size = snprintf(buf, sizeof(buf), "<%d>%s: ", level, tag);
+ size_t msg_size = vsnprintf(buf + prefix_size, sizeof(buf) - prefix_size, fmt, ap);
+ if (msg_size >= sizeof(buf) - prefix_size) {
+ msg_size = snprintf(buf + prefix_size, sizeof(buf) - prefix_size,
+ "(%zu-byte message too long for printk)\n", msg_size);
+ }
- char msg[512];
- vsnprintf(msg, sizeof(msg), fmt, ap);
+ iovec iov[1];
+ iov[0].iov_base = buf;
+ iov[0].iov_len = prefix_size + msg_size;
- iovec iov[2];
- iov[0].iov_base = prefix;
- iov[0].iov_len = strlen(prefix);
- iov[1].iov_base = msg;
- iov[1].iov_len = strlen(msg);
-
- klog_writev(level, iov, 2);
+ klog_writev(level, iov, 1);
}
void init_klog_write(int level, const char* fmt, ...) {
diff --git a/init/util.cpp b/init/util.cpp
index 9343145..7754e53 100644
--- a/init/util.cpp
+++ b/init/util.cpp
@@ -33,6 +33,7 @@
#include <sys/un.h>
#include <base/file.h>
+#include <base/strings.h>
/* for ANDROID_SOCKET_* */
#include <cutils/sockets.h>
@@ -403,32 +404,16 @@
}
}
-void import_kernel_cmdline(bool in_qemu, std::function<void(char*,bool)> import_kernel_nv)
-{
- char cmdline[2048];
- char *ptr;
- int fd;
+void import_kernel_cmdline(bool in_qemu,
+ std::function<void(const std::string&, const std::string&, bool)> fn) {
+ std::string cmdline;
+ android::base::ReadFileToString("/proc/cmdline", &cmdline);
- fd = open("/proc/cmdline", O_RDONLY | O_CLOEXEC);
- if (fd >= 0) {
- int n = read(fd, cmdline, sizeof(cmdline) - 1);
- if (n < 0) n = 0;
-
- /* get rid of trailing newline, it happens */
- if (n > 0 && cmdline[n-1] == '\n') n--;
-
- cmdline[n] = 0;
- close(fd);
- } else {
- cmdline[0] = 0;
- }
-
- ptr = cmdline;
- while (ptr && *ptr) {
- char *x = strchr(ptr, ' ');
- if (x != 0) *x++ = 0;
- import_kernel_nv(ptr, in_qemu);
- ptr = x;
+ for (const auto& entry : android::base::Split(android::base::Trim(cmdline), " ")) {
+ std::vector<std::string> pieces = android::base::Split(entry, "=");
+ if (pieces.size() == 2) {
+ fn(pieces[0], pieces[1], in_qemu);
+ }
}
}
diff --git a/init/util.h b/init/util.h
index 6864acf..4ac941e 100644
--- a/init/util.h
+++ b/init/util.h
@@ -58,7 +58,8 @@
void remove_link(const char *oldpath, const char *newpath);
int wait_for_file(const char *filename, int timeout);
void open_devnull_stdio(void);
-void import_kernel_cmdline(bool in_qemu, std::function<void(char*,bool)>);
+void import_kernel_cmdline(bool in_qemu,
+ std::function<void(const std::string&, const std::string&, bool)>);
int make_dir(const char *path, mode_t mode);
int restorecon(const char *pathname);
int restorecon_recursive(const char *pathname);
diff --git a/libbacktrace/BacktracePtrace.cpp b/libbacktrace/BacktracePtrace.cpp
index 6134438..e10cce1 100644
--- a/libbacktrace/BacktracePtrace.cpp
+++ b/libbacktrace/BacktracePtrace.cpp
@@ -83,13 +83,12 @@
if (!PtraceRead(Tid(), addr & ~(sizeof(word_t) - 1), &data_word)) {
return 0;
}
- align_bytes = sizeof(word_t) - align_bytes;
- memcpy(buffer, reinterpret_cast<uint8_t*>(&data_word) + sizeof(word_t) - align_bytes,
- align_bytes);
- addr += align_bytes;
- buffer += align_bytes;
- bytes -= align_bytes;
- bytes_read += align_bytes;
+ size_t copy_bytes = MIN(sizeof(word_t) - align_bytes, bytes);
+ memcpy(buffer, reinterpret_cast<uint8_t*>(&data_word) + align_bytes, copy_bytes);
+ addr += copy_bytes;
+ buffer += copy_bytes;
+ bytes -= copy_bytes;
+ bytes_read += copy_bytes;
}
size_t num_words = bytes / sizeof(word_t);
diff --git a/libbacktrace/backtrace_test.cpp b/libbacktrace/backtrace_test.cpp
index 28d146a..a086547 100644
--- a/libbacktrace/backtrace_test.cpp
+++ b/libbacktrace/backtrace_test.cpp
@@ -883,6 +883,17 @@
ASSERT_EQ(waitpid(pid, nullptr, 0), pid);
}
+void InitMemory(uint8_t* memory, size_t bytes) {
+ for (size_t i = 0; i < bytes; i++) {
+ memory[i] = i;
+ if (memory[i] == '\0') {
+ // Don't use '\0' in our data so we can verify that an overread doesn't
+ // occur by using a '\0' as the character after the read data.
+ memory[i] = 23;
+ }
+ }
+}
+
void* ThreadReadTest(void* data) {
thread_t* thread_data = reinterpret_cast<thread_t*>(data);
@@ -901,9 +912,7 @@
}
// Set up a simple pattern in memory.
- for (size_t i = 0; i < pagesize; i++) {
- memory[i] = i;
- }
+ InitMemory(memory, pagesize);
thread_data->data = memory;
@@ -931,9 +940,8 @@
// Create a page of data to use to do quick compares.
uint8_t* expected = new uint8_t[pagesize];
- for (size_t i = 0; i < pagesize; i++) {
- expected[i] = i;
- }
+ InitMemory(expected, pagesize);
+
uint8_t* data = new uint8_t[2*pagesize];
// Verify that we can only read one page worth of data.
size_t bytes_read = backtrace->Read(read_addr, data, 2 * pagesize);
@@ -947,6 +955,20 @@
ASSERT_TRUE(memcmp(data, &expected[i], 2 * sizeof(word_t)) == 0)
<< "Offset at " << i << " failed";
}
+
+ // Verify small unaligned reads.
+ for (size_t i = 1; i < sizeof(word_t); i++) {
+ for (size_t j = 1; j < sizeof(word_t); j++) {
+ // Set one byte past what we expect to read, to guarantee we don't overread.
+ data[j] = '\0';
+ bytes_read = backtrace->Read(read_addr + i, data, j);
+ ASSERT_EQ(j, bytes_read);
+ ASSERT_TRUE(memcmp(data, &expected[i], j) == 0)
+ << "Offset at " << i << " length " << j << " miscompared";
+ ASSERT_EQ('\0', data[j])
+ << "Offset at " << i << " length " << j << " wrote too much data";
+ }
+ }
delete data;
delete expected;
}
@@ -990,9 +1012,7 @@
}
// Set up a simple pattern in memory.
- for (size_t i = 0; i < pagesize; i++) {
- memory[i] = i;
- }
+ InitMemory(memory, pagesize);
g_addr = reinterpret_cast<uintptr_t>(memory);
g_ready = 1;
diff --git a/mkbootimg/bootimg.h b/mkbootimg/bootimg.h
index 9171d85..5ab6195 100644
--- a/mkbootimg/bootimg.h
+++ b/mkbootimg/bootimg.h
@@ -15,6 +15,8 @@
** limitations under the License.
*/
+#include <stdint.h>
+
#ifndef _BOOT_IMAGE_H_
#define _BOOT_IMAGE_H_
@@ -28,31 +30,31 @@
struct boot_img_hdr
{
- unsigned char magic[BOOT_MAGIC_SIZE];
+ uint8_t magic[BOOT_MAGIC_SIZE];
- unsigned kernel_size; /* size in bytes */
- unsigned kernel_addr; /* physical load addr */
+ uint32_t kernel_size; /* size in bytes */
+ uint32_t kernel_addr; /* physical load addr */
- unsigned ramdisk_size; /* size in bytes */
- unsigned ramdisk_addr; /* physical load addr */
+ uint32_t ramdisk_size; /* size in bytes */
+ uint32_t ramdisk_addr; /* physical load addr */
- unsigned second_size; /* size in bytes */
- unsigned second_addr; /* physical load addr */
+ uint32_t second_size; /* size in bytes */
+ uint32_t second_addr; /* physical load addr */
- unsigned tags_addr; /* physical addr for kernel tags */
- unsigned page_size; /* flash page size we assume */
- unsigned unused[2]; /* future expansion: should be 0 */
+ uint32_t tags_addr; /* physical addr for kernel tags */
+ uint32_t page_size; /* flash page size we assume */
+ uint32_t unused[2]; /* future expansion: should be 0 */
- unsigned char name[BOOT_NAME_SIZE]; /* asciiz product name */
+ uint8_t name[BOOT_NAME_SIZE]; /* asciiz product name */
- unsigned char cmdline[BOOT_ARGS_SIZE];
+ uint8_t cmdline[BOOT_ARGS_SIZE];
- unsigned id[8]; /* timestamp / checksum / sha1 / etc */
+ uint32_t id[8]; /* timestamp / checksum / sha1 / etc */
/* Supplemental command line data; kept here to maintain
* binary compatibility with older versions of mkbootimg */
- unsigned char extra_cmdline[BOOT_EXTRA_ARGS_SIZE];
-};
+ uint8_t extra_cmdline[BOOT_EXTRA_ARGS_SIZE];
+} __attribute__((packed));
/*
** +-----------------+
diff --git a/mkbootimg/mkbootimg.c b/mkbootimg/mkbootimg.c
index fc92b4d..31f76e4 100644
--- a/mkbootimg/mkbootimg.c
+++ b/mkbootimg/mkbootimg.c
@@ -96,24 +96,24 @@
{
boot_img_hdr hdr;
- char *kernel_fn = 0;
- void *kernel_data = 0;
- char *ramdisk_fn = 0;
- void *ramdisk_data = 0;
- char *second_fn = 0;
- void *second_data = 0;
+ char *kernel_fn = NULL;
+ void *kernel_data = NULL;
+ char *ramdisk_fn = NULL;
+ void *ramdisk_data = NULL;
+ char *second_fn = NULL;
+ void *second_data = NULL;
char *cmdline = "";
- char *bootimg = 0;
+ char *bootimg = NULL;
char *board = "";
- unsigned pagesize = 2048;
+ uint32_t pagesize = 2048;
int fd;
SHA_CTX ctx;
const uint8_t* sha;
- unsigned base = 0x10000000;
- unsigned kernel_offset = 0x00008000;
- unsigned ramdisk_offset = 0x01000000;
- unsigned second_offset = 0x00f00000;
- unsigned tags_offset = 0x00000100;
+ uint32_t base = 0x10000000U;
+ uint32_t kernel_offset = 0x00008000U;
+ uint32_t ramdisk_offset = 0x01000000U;
+ uint32_t second_offset = 0x00f00000U;
+ uint32_t tags_offset = 0x00000100U;
size_t cmdlen;
argc--;