Fix out of bound access in libziparchive am: 1ee4892e66 am: c24dd97654 am: 8788591224 am: 167562aa76 am: 398adf9b55 am: 680c3f1dc4 am: f0ce69815f am: 6fb68bb196
am: 2af1a88fcb
Change-Id: I7a5fdc8df2449a332c7696c472e25880bfccc67f
diff --git a/adb/bugreport.cpp b/adb/bugreport.cpp
index 9ed44a7..c348dd5 100644
--- a/adb/bugreport.cpp
+++ b/adb/bugreport.cpp
@@ -47,7 +47,7 @@
show_progress_(show_progress),
status_(0),
line_() {
- SetLineMessage();
+ SetLineMessage("generating");
}
void OnStdout(const char* buffer, int length) {
@@ -97,6 +97,7 @@
OS_PATH_SEPARATOR, dest_file_.c_str());
}
std::vector<const char*> srcs{src_file_.c_str()};
+ SetLineMessage("pulling");
status_ =
br_->DoSyncPull(srcs, destination.c_str(), true, line_message_.c_str()) ? 0 : 1;
if (status_ != 0) {
@@ -111,9 +112,8 @@
}
private:
- void SetLineMessage() {
- line_message_ =
- android::base::StringPrintf("generating %s", adb_basename(dest_file_).c_str());
+ void SetLineMessage(const std::string& action) {
+ line_message_ = action + " " + adb_basename(dest_file_);
}
void SetSrcFile(const std::string path) {
@@ -121,7 +121,7 @@
if (!dest_dir_.empty()) {
// Only uses device-provided name when user passed a directory.
dest_file_ = adb_basename(path);
- SetLineMessage();
+ SetLineMessage("generating");
}
}
diff --git a/adb/bugreport_test.cpp b/adb/bugreport_test.cpp
index 3cd2b6d..1129285 100644
--- a/adb/bugreport_test.cpp
+++ b/adb/bugreport_test.cpp
@@ -189,7 +189,7 @@
.WillOnce(DoAll(WithArg<4>(WriteOnStdout("OK:/device/da_bugreport.zip")),
WithArg<4>(ReturnCallbackDone())));
EXPECT_CALL(br_, DoSyncPull(ElementsAre(StrEq("/device/da_bugreport.zip")), StrEq(dest_file),
- true, StrEq("generating da_bugreport.zip")))
+ true, StrEq("pulling da_bugreport.zip")))
.WillOnce(Return(true));
const char* args[] = {"bugreport"};
@@ -209,7 +209,7 @@
WithArg<4>(WriteOnStdout("OK:/device/da_bugreport.zip\n")),
WithArg<4>(ReturnCallbackDone())));
EXPECT_CALL(br_, DoSyncPull(ElementsAre(StrEq("/device/da_bugreport.zip")), StrEq(dest_file),
- true, StrEq("generating da_bugreport.zip")))
+ true, StrEq("pulling da_bugreport.zip")))
.WillOnce(Return(true));
const char* args[] = {"bugreport"};
@@ -223,7 +223,7 @@
.WillOnce(DoAll(WithArg<4>(WriteOnStdout("OK:/device/bugreport.zip")),
WithArg<4>(ReturnCallbackDone())));
EXPECT_CALL(br_, DoSyncPull(ElementsAre(StrEq("/device/bugreport.zip")), StrEq("file.zip"),
- true, StrEq("generating file.zip")))
+ true, StrEq("pulling file.zip")))
.WillOnce(Return(true));
const char* args[] = {"bugreport", "file.zip"};
@@ -239,7 +239,7 @@
WithArg<4>(WriteOnStdout("/bugreport.zip")),
WithArg<4>(ReturnCallbackDone())));
EXPECT_CALL(br_, DoSyncPull(ElementsAre(StrEq("/device/bugreport.zip")), StrEq("file.zip"),
- true, StrEq("generating file.zip")))
+ true, StrEq("pulling file.zip")))
.WillOnce(Return(true));
const char* args[] = {"bugreport", "file.zip"};
@@ -275,7 +275,7 @@
WithArg<4>(ReturnCallbackDone())));
// clang-format on
EXPECT_CALL(br_, DoSyncPull(ElementsAre(StrEq("/device/bugreport.zip")), StrEq("file.zip"),
- true, StrEq("generating file.zip")))
+ true, StrEq("pulling file.zip")))
.WillOnce(Return(true));
const char* args[] = {"bugreport", "file.zip"};
@@ -294,7 +294,7 @@
WithArg<4>(WriteOnStdout("OK:/device/da_bugreport.zip")),
WithArg<4>(ReturnCallbackDone())));
EXPECT_CALL(br_, DoSyncPull(ElementsAre(StrEq("/device/da_bugreport.zip")), StrEq(dest_file),
- true, StrEq("generating da_bugreport.zip")))
+ true, StrEq("pulling da_bugreport.zip")))
.WillOnce(Return(true));
const char* args[] = {"bugreport", td.path};
@@ -308,7 +308,7 @@
.WillOnce(DoAll(WithArg<4>(WriteOnStdout("OK:/device/bugreport.zip\n")),
WithArg<4>(ReturnCallbackDone())));
EXPECT_CALL(br_, DoSyncPull(ElementsAre(StrEq("/device/bugreport.zip")), StrEq("file.zip"),
- true, StrEq("generating file.zip")))
+ true, StrEq("pulling file.zip")))
.WillOnce(Return(true));
const char* args[] = {"bugreport", "file"};
@@ -327,7 +327,7 @@
WithArg<4>(WriteOnStdout("OK:/device/da_bugreport.zip")),
WithArg<4>(ReturnCallbackDone())));
EXPECT_CALL(br_, DoSyncPull(ElementsAre(StrEq("/device/da_bugreport.zip")), StrEq(dest_file),
- true, StrEq("generating da_bugreport.zip")))
+ true, StrEq("pulling da_bugreport.zip")))
.WillOnce(Return(true));
const char* args[] = {"bugreport", td.path};
diff --git a/adb/commandline.cpp b/adb/commandline.cpp
index 23827de..51d828a 100644
--- a/adb/commandline.cpp
+++ b/adb/commandline.cpp
@@ -1430,6 +1430,16 @@
#endif
}
+static bool _use_legacy_install() {
+ FeatureSet features;
+ std::string error;
+ if (!adb_get_feature_set(&features, &error)) {
+ fprintf(stderr, "error: %s\n", error.c_str());
+ return true;
+ }
+ return !CanUseFeature(features, kFeatureCmd);
+}
+
int adb_commandline(int argc, const char **argv) {
int no_daemon = 0;
int is_daemon = 0;
@@ -1797,17 +1807,10 @@
}
else if (!strcmp(argv[0], "install")) {
if (argc < 2) return usage();
- FeatureSet features;
- std::string error;
- if (!adb_get_feature_set(&features, &error)) {
- fprintf(stderr, "error: %s\n", error.c_str());
- return 1;
+ if (_use_legacy_install()) {
+ return install_app_legacy(transport_type, serial, argc, argv);
}
-
- if (CanUseFeature(features, kFeatureCmd)) {
- return install_app(transport_type, serial, argc, argv);
- }
- return install_app_legacy(transport_type, serial, argc, argv);
+ return install_app(transport_type, serial, argc, argv);
}
else if (!strcmp(argv[0], "install-multiple")) {
if (argc < 2) return usage();
@@ -1815,17 +1818,10 @@
}
else if (!strcmp(argv[0], "uninstall")) {
if (argc < 2) return usage();
- FeatureSet features;
- std::string error;
- if (!adb_get_feature_set(&features, &error)) {
- fprintf(stderr, "error: %s\n", error.c_str());
- return 1;
+ if (_use_legacy_install()) {
+ return uninstall_app_legacy(transport_type, serial, argc, argv);
}
-
- if (CanUseFeature(features, kFeatureCmd)) {
- return uninstall_app(transport_type, serial, argc, argv);
- }
- return uninstall_app_legacy(transport_type, serial, argc, argv);
+ return uninstall_app(transport_type, serial, argc, argv);
}
else if (!strcmp(argv[0], "sync")) {
std::string src;
@@ -2031,7 +2027,6 @@
int i;
struct stat sb;
uint64_t total_size = 0;
-
// Find all APK arguments starting at end.
// All other arguments passed through verbatim.
int first_apk = -1;
@@ -2056,7 +2051,14 @@
return 1;
}
- std::string cmd = android::base::StringPrintf("exec:pm install-create -S %" PRIu64, total_size);
+ std::string install_cmd;
+ if (_use_legacy_install()) {
+ install_cmd = "exec:pm";
+ } else {
+ install_cmd = "exec:cmd package";
+ }
+
+ std::string cmd = android::base::StringPrintf("%s install-create -S %" PRIu64, install_cmd.c_str(), total_size);
for (i = 1; i < first_apk; i++) {
cmd += " " + escape_arg(argv[i]);
}
@@ -2098,8 +2100,8 @@
}
std::string cmd = android::base::StringPrintf(
- "exec:pm install-write -S %" PRIu64 " %d %d_%s -",
- static_cast<uint64_t>(sb.st_size), session_id, i, adb_basename(file).c_str());
+ "%s install-write -S %" PRIu64 " %d %d_%s -",
+ install_cmd.c_str(), static_cast<uint64_t>(sb.st_size), session_id, i, adb_basename(file).c_str());
int localFd = adb_open(file, O_RDONLY);
if (localFd < 0) {
@@ -2134,8 +2136,8 @@
finalize_session:
// Commit session if we streamed everything okay; otherwise abandon
std::string service =
- android::base::StringPrintf("exec:pm install-%s %d",
- success ? "commit" : "abandon", session_id);
+ android::base::StringPrintf("%s install-%s %d",
+ install_cmd.c_str(), success ? "commit" : "abandon", session_id);
fd = adb_connect(service, &error);
if (fd < 0) {
fprintf(stderr, "Connect error for finalize: %s\n", error.c_str());
diff --git a/debuggerd/tombstone.cpp b/debuggerd/tombstone.cpp
index fa983fa..dfdf29c 100644
--- a/debuggerd/tombstone.cpp
+++ b/debuggerd/tombstone.cpp
@@ -368,6 +368,7 @@
ALOGE("Cannot get siginfo for %d: %s\n", tid, strerror(errno));
}
+ ScopedBacktraceMapIteratorLock lock(map);
_LOG(log, logtype::MAPS, "\n");
if (!print_fault_address_marker) {
_LOG(log, logtype::MAPS, "memory map:\n");
diff --git a/fastboot/fastboot.cpp b/fastboot/fastboot.cpp
index c1c3174..2b6cad1 100644
--- a/fastboot/fastboot.cpp
+++ b/fastboot/fastboot.cpp
@@ -116,16 +116,18 @@
};
static std::string find_item_given_name(const char* img_name, const char* product) {
- char *dir;
- char path[PATH_MAX + 128];
+ char path_c_str[PATH_MAX + 128];
if(product) {
- get_my_path(path);
- return android::base::StringPrintf("../../../target/product/%s/%s", product, img_name);
+ get_my_path(path_c_str);
+ std::string path = path_c_str;
+ path.erase(path.find_last_of('/'));
+ return android::base::StringPrintf("%s/../../../target/product/%s/%s",
+ path.c_str(), product, img_name);
}
- dir = getenv("ANDROID_PRODUCT_OUT");
- if((dir == 0) || (dir[0] == 0)) {
+ char *dir = getenv("ANDROID_PRODUCT_OUT");
+ if (dir == nullptr || dir[0] == '\0') {
die("neither -p product specified nor ANDROID_PRODUCT_OUT set");
}
diff --git a/fs_mgr/fs_mgr.c b/fs_mgr/fs_mgr.c
index 6de8817..387f708 100644
--- a/fs_mgr/fs_mgr.c
+++ b/fs_mgr/fs_mgr.c
@@ -489,7 +489,7 @@
* first successful mount.
* Returns -1 on error, and FS_MGR_MNTALL_* otherwise.
*/
-int fs_mgr_mount_all(struct fstab *fstab)
+int fs_mgr_mount_all(struct fstab *fstab, int mount_mode)
{
int i = 0;
int encryptable = FS_MGR_MNTALL_DEV_NOT_ENCRYPTABLE;
@@ -503,8 +503,10 @@
}
for (i = 0; i < fstab->num_entries; i++) {
- /* Don't mount entries that are managed by vold */
- if (fstab->recs[i].fs_mgr_flags & (MF_VOLDMANAGED | MF_RECOVERYONLY)) {
+ /* Don't mount entries that are managed by vold or not for the mount mode*/
+ if ((fstab->recs[i].fs_mgr_flags & (MF_VOLDMANAGED | MF_RECOVERYONLY)) ||
+ ((mount_mode == MOUNT_MODE_LATE) && !fs_mgr_is_latemount(&fstab->recs[i])) ||
+ ((mount_mode == MOUNT_MODE_EARLY) && fs_mgr_is_latemount(&fstab->recs[i]))) {
continue;
}
diff --git a/fs_mgr/fs_mgr_fstab.c b/fs_mgr/fs_mgr_fstab.c
index 45adb34..21b4c74 100644
--- a/fs_mgr/fs_mgr_fstab.c
+++ b/fs_mgr/fs_mgr_fstab.c
@@ -78,6 +78,7 @@
{ "formattable", MF_FORMATTABLE },
{ "slotselect", MF_SLOTSELECT },
{ "nofail", MF_NOFAIL },
+ { "latemount", MF_LATEMOUNT },
{ "defaults", 0 },
{ 0, 0 },
};
@@ -545,3 +546,8 @@
{
return fstab->fs_mgr_flags & MF_NOFAIL;
}
+
+int fs_mgr_is_latemount(struct fstab_rec *fstab)
+{
+ return fstab->fs_mgr_flags & MF_LATEMOUNT;
+}
diff --git a/fs_mgr/fs_mgr_main.c b/fs_mgr/fs_mgr_main.c
index e5a00d5..776c13e 100644
--- a/fs_mgr/fs_mgr_main.c
+++ b/fs_mgr/fs_mgr_main.c
@@ -96,7 +96,7 @@
fstab = fs_mgr_read_fstab(fstab_file);
if (a_flag) {
- return fs_mgr_mount_all(fstab);
+ return fs_mgr_mount_all(fstab, MOUNT_MODE_DEFAULT);
} else if (n_flag) {
return fs_mgr_do_mount(fstab, n_name, n_blk_dev, 0);
} else if (u_flag) {
diff --git a/fs_mgr/fs_mgr_priv.h b/fs_mgr/fs_mgr_priv.h
index 46975f1..6d9492b 100644
--- a/fs_mgr/fs_mgr_priv.h
+++ b/fs_mgr/fs_mgr_priv.h
@@ -48,7 +48,7 @@
*
* <fs_mgr_options> is a comma separated list of flags that control the operation of
* the fs_mgr program. The list includes "wait", which will wait till
- * the <source> file exists, and "check", which requests that the fs_mgr
+ * the <source> file exists, and "check", which requests that the fs_mgr
* run an fscheck program on the <source> before mounting the filesystem.
* If check is specifed on a read-only filesystem, it is ignored.
* Also, "encryptable" means that filesystem can be encrypted.
@@ -83,6 +83,7 @@
#define MF_FORMATTABLE 0x4000
#define MF_SLOTSELECT 0x8000
#define MF_FORCEFDEORFBE 0x10000
+#define MF_LATEMOUNT 0x20000
#define MF_NOFAIL 0x40000
#define DM_BUF_SIZE 4096
diff --git a/fs_mgr/include/fs_mgr.h b/fs_mgr/include/fs_mgr.h
index 46d8f97..7565965 100644
--- a/fs_mgr/include/fs_mgr.h
+++ b/fs_mgr/include/fs_mgr.h
@@ -40,6 +40,13 @@
VERITY_MODE_DEFAULT = VERITY_MODE_RESTART
};
+// Mount modes
+enum mount_mode {
+ MOUNT_MODE_DEFAULT = 0,
+ MOUNT_MODE_EARLY = 1,
+ MOUNT_MODE_LATE = 2
+};
+
/*
* The entries must be kept in the same order as they were seen in the fstab.
* Unless explicitly requested, a lookup on mount point should always
@@ -82,7 +89,7 @@
#define FS_MGR_MNTALL_DEV_NOT_ENCRYPTED 1
#define FS_MGR_MNTALL_DEV_NOT_ENCRYPTABLE 0
#define FS_MGR_MNTALL_FAIL -1
-int fs_mgr_mount_all(struct fstab *fstab);
+int fs_mgr_mount_all(struct fstab *fstab, int mount_mode);
#define FS_MGR_DOMNT_FAILED -1
#define FS_MGR_DOMNT_BUSY -2
@@ -110,6 +117,7 @@
int fs_mgr_is_notrim(struct fstab_rec *fstab);
int fs_mgr_is_formattable(struct fstab_rec *fstab);
int fs_mgr_is_nofail(struct fstab_rec *fstab);
+int fs_mgr_is_latemount(struct fstab_rec *fstab);
int fs_mgr_swapon_all(struct fstab *fstab);
int fs_mgr_do_format(struct fstab_rec *fstab);
diff --git a/include/backtrace/BacktraceMap.h b/include/backtrace/BacktraceMap.h
index 2373c45..b80045f 100644
--- a/include/backtrace/BacktraceMap.h
+++ b/include/backtrace/BacktraceMap.h
@@ -71,6 +71,12 @@
bool IsWritable(uintptr_t pc) { return GetFlags(pc) & PROT_WRITE; }
bool IsExecutable(uintptr_t pc) { return GetFlags(pc) & PROT_EXEC; }
+ // In order to use the iterators on this object, a caller must
+ // call the LockIterator and UnlockIterator function to guarantee
+ // that the data does not change while it's being used.
+ virtual void LockIterator() {}
+ virtual void UnlockIterator() {}
+
typedef std::deque<backtrace_map_t>::iterator iterator;
iterator begin() { return maps_.begin(); }
iterator end() { return maps_.end(); }
@@ -102,4 +108,18 @@
pid_t pid_;
};
+class ScopedBacktraceMapIteratorLock {
+public:
+ explicit ScopedBacktraceMapIteratorLock(BacktraceMap* map) : map_(map) {
+ map->LockIterator();
+ }
+
+ ~ScopedBacktraceMapIteratorLock() {
+ map_->UnlockIterator();
+ }
+
+private:
+ BacktraceMap* map_;
+};
+
#endif // _BACKTRACE_BACKTRACE_MAP_H
diff --git a/include/cutils/trace.h b/include/cutils/trace.h
index c9790ad..19313af 100644
--- a/include/cutils/trace.h
+++ b/include/cutils/trace.h
@@ -70,7 +70,8 @@
#define ATRACE_TAG_PACKAGE_MANAGER (1<<18)
#define ATRACE_TAG_SYSTEM_SERVER (1<<19)
#define ATRACE_TAG_DATABASE (1<<20)
-#define ATRACE_TAG_LAST ATRACE_TAG_DATABASE
+#define ATRACE_TAG_NETWORK (1<<21)
+#define ATRACE_TAG_LAST ATRACE_TAG_NETWORK
// Reserved for initialization.
#define ATRACE_TAG_NOT_READY (1ULL<<63)
diff --git a/init/builtins.cpp b/init/builtins.cpp
index 70f9194..44217f0 100644
--- a/init/builtins.cpp
+++ b/init/builtins.cpp
@@ -479,9 +479,9 @@
*
* start_index: index of the first path in the args list
*/
-static void import_late(const std::vector<std::string>& args, size_t start_index) {
+static void import_late(const std::vector<std::string>& args, size_t start_index, size_t end_index) {
Parser& parser = Parser::GetInstance();
- if (args.size() <= start_index) {
+ if (end_index <= start_index) {
// Use the default set if no path is given
static const std::vector<std::string> init_directories = {
"/system/etc/init",
@@ -493,25 +493,23 @@
parser.ParseConfig(dir);
}
} else {
- for (size_t i = start_index; i < args.size(); ++i) {
+ for (size_t i = start_index; i < end_index; ++i) {
parser.ParseConfig(args[i]);
}
}
}
-/* mount_all <fstab> [ <path> ]*
+/* mount_fstab
*
- * This function might request a reboot, in which case it will
- * not return.
+ * Call fs_mgr_mount_all() to mount the given fstab
*/
-static int do_mount_all(const std::vector<std::string>& args) {
+static int mount_fstab(const char* fstabfile, int mount_mode) {
pid_t pid;
int ret = -1;
int child_ret = -1;
int status;
struct fstab *fstab;
- const char* fstabfile = args[1].c_str();
/*
* Call fs_mgr_mount_all() to mount all filesystems. We fork(2) and
* do the call in the child to provide protection to the main init
@@ -536,7 +534,7 @@
/* child, call fs_mgr_mount_all() */
klog_set_level(6); /* So we can see what fs_mgr_mount_all() does */
fstab = fs_mgr_read_fstab(fstabfile);
- child_ret = fs_mgr_mount_all(fstab);
+ child_ret = fs_mgr_mount_all(fstab, mount_mode);
fs_mgr_free_fstab(fstab);
if (child_ret == -1) {
ERROR("fs_mgr_mount_all returned an error\n");
@@ -546,28 +544,38 @@
/* fork failed, return an error */
return -1;
}
+ return ret;
+}
- /* Paths of .rc files are specified at the 2nd argument and beyond */
- import_late(args, 2);
-
- if (ret == FS_MGR_MNTALL_DEV_NEEDS_ENCRYPTION) {
+/* Queue event based on fs_mgr return code.
+ *
+ * code: return code of fs_mgr_mount_all
+ *
+ * This function might request a reboot, in which case it will
+ * not return.
+ *
+ * return code is processed based on input code
+ */
+static int queue_fs_event(int code) {
+ int ret = code;
+ if (code == FS_MGR_MNTALL_DEV_NEEDS_ENCRYPTION) {
ActionManager::GetInstance().QueueEventTrigger("encrypt");
- } else if (ret == FS_MGR_MNTALL_DEV_MIGHT_BE_ENCRYPTED) {
+ } else if (code == FS_MGR_MNTALL_DEV_MIGHT_BE_ENCRYPTED) {
property_set("ro.crypto.state", "encrypted");
property_set("ro.crypto.type", "block");
ActionManager::GetInstance().QueueEventTrigger("defaultcrypto");
- } else if (ret == FS_MGR_MNTALL_DEV_NOT_ENCRYPTED) {
+ } else if (code == FS_MGR_MNTALL_DEV_NOT_ENCRYPTED) {
property_set("ro.crypto.state", "unencrypted");
ActionManager::GetInstance().QueueEventTrigger("nonencrypted");
- } else if (ret == FS_MGR_MNTALL_DEV_NOT_ENCRYPTABLE) {
+ } else if (code == FS_MGR_MNTALL_DEV_NOT_ENCRYPTABLE) {
property_set("ro.crypto.state", "unsupported");
ActionManager::GetInstance().QueueEventTrigger("nonencrypted");
- } else if (ret == FS_MGR_MNTALL_DEV_NEEDS_RECOVERY) {
+ } else if (code == FS_MGR_MNTALL_DEV_NEEDS_RECOVERY) {
/* Setup a wipe via recovery, and reboot into recovery */
ERROR("fs_mgr_mount_all suggested recovery, so wiping data via recovery.\n");
ret = wipe_data_via_recovery("wipe_data_via_recovery");
/* If reboot worked, there is no return. */
- } else if (ret == FS_MGR_MNTALL_DEV_FILE_ENCRYPTED) {
+ } else if (code == FS_MGR_MNTALL_DEV_FILE_ENCRYPTED) {
if (e4crypt_install_keyring()) {
return -1;
}
@@ -577,14 +585,55 @@
// Although encrypted, we have device key, so we do not need to
// do anything different from the nonencrypted case.
ActionManager::GetInstance().QueueEventTrigger("nonencrypted");
- } else if (ret > 0) {
- ERROR("fs_mgr_mount_all returned unexpected error %d\n", ret);
+ } else if (code > 0) {
+ ERROR("fs_mgr_mount_all returned unexpected error %d\n", code);
}
/* else ... < 0: error */
return ret;
}
+/* mount_all <fstab> [ <path> ]* [--<options>]*
+ *
+ * This function might request a reboot, in which case it will
+ * not return.
+ */
+static int do_mount_all(const std::vector<std::string>& args) {
+ std::size_t na = 0;
+ bool import_rc = true;
+ bool queue_event = true;
+ int mount_mode = MOUNT_MODE_DEFAULT;
+ const char* fstabfile = args[1].c_str();
+ std::size_t path_arg_end = args.size();
+
+ for (na = args.size() - 1; na > 1; --na) {
+ if (args[na] == "--early") {
+ path_arg_end = na;
+ queue_event = false;
+ mount_mode = MOUNT_MODE_EARLY;
+ } else if (args[na] == "--late") {
+ path_arg_end = na;
+ import_rc = false;
+ mount_mode = MOUNT_MODE_LATE;
+ }
+ }
+
+ int ret = mount_fstab(fstabfile, mount_mode);
+
+ if (import_rc) {
+ /* Paths of .rc files are specified at the 2nd argument and beyond */
+ import_late(args, 2, path_arg_end);
+ }
+
+ if (queue_event) {
+ /* queue_fs_event will queue event based on mount_fstab return code
+ * and return processed return code*/
+ ret = queue_fs_event(ret);
+ }
+
+ return ret;
+}
+
static int do_swapon_all(const std::vector<std::string>& args) {
struct fstab *fstab;
int ret;
diff --git a/init/readme.txt b/init/readme.txt
index 4481e24..dad7e06 100644
--- a/init/readme.txt
+++ b/init/readme.txt
@@ -1,4 +1,3 @@
-
Android Init Language
---------------------
@@ -78,6 +77,14 @@
conflict resolution when multiple services are added to the system, as
each one will go into a separate file.
+There are two options "early" and "late" in mount_all command
+which can be set after optional paths. With "--early" set, the
+init executable will skip mounting entries with "latemount" flag
+and triggering fs encryption state event. With "--late" set,
+init executable will only mount entries with "latemount" flag but skip
+importing rc files. By default, no option is set, and mount_all will
+mount_all will process all entries in the given fstab.
+
Actions
-------
Actions are named sequences of commands. Actions have a trigger which
@@ -291,10 +298,11 @@
owned by the root user and root group. If provided, the mode, owner and group
will be updated if the directory exists already.
-mount_all <fstab> [ <path> ]*
+mount_all <fstab> [ <path> ]* [--<option>]
Calls fs_mgr_mount_all on the given fs_mgr-format fstab and imports .rc files
- at the specified paths (e.g., on the partitions just mounted). Refer to the
- section of "Init .rc Files" for detail.
+ at the specified paths (e.g., on the partitions just mounted) with optional
+ options "early" and "late".
+ Refer to the section of "Init .rc Files" for detail.
mount <type> <device> <dir> [ <flag> ]* [<options>]
Attempt to mount the named device at the directory <dir>
diff --git a/libbacktrace/BacktraceMap.cpp b/libbacktrace/BacktraceMap.cpp
index ba86632..85f2436 100644
--- a/libbacktrace/BacktraceMap.cpp
+++ b/libbacktrace/BacktraceMap.cpp
@@ -35,8 +35,8 @@
}
void BacktraceMap::FillIn(uintptr_t addr, backtrace_map_t* map) {
- for (BacktraceMap::const_iterator it = begin();
- it != end(); ++it) {
+ ScopedBacktraceMapIteratorLock lock(this);
+ for (BacktraceMap::const_iterator it = begin(); it != end(); ++it) {
if (addr >= it->start && addr < it->end) {
*map = *it;
return;
diff --git a/libbacktrace/UnwindMap.cpp b/libbacktrace/UnwindMap.cpp
index 34d79f9..af79562 100644
--- a/libbacktrace/UnwindMap.cpp
+++ b/libbacktrace/UnwindMap.cpp
@@ -14,6 +14,7 @@
* limitations under the License.
*/
+#include <pthread.h>
#include <stdint.h>
#include <stdlib.h>
#include <sys/types.h>
@@ -72,6 +73,7 @@
}
UnwindMapLocal::UnwindMapLocal() : UnwindMap(getpid()), map_created_(false) {
+ pthread_rwlock_init(&map_lock_, nullptr);
}
UnwindMapLocal::~UnwindMapLocal() {
@@ -82,9 +84,14 @@
}
bool UnwindMapLocal::GenerateMap() {
+ // Lock so that multiple threads cannot modify the maps data at the
+ // same time.
+ pthread_rwlock_wrlock(&map_lock_);
+
// It's possible for the map to be regenerated while this loop is occurring.
// If that happens, get the map again, but only try at most three times
// before giving up.
+ bool generated = false;
for (int i = 0; i < 3; i++) {
maps_.clear();
@@ -110,12 +117,17 @@
}
// Check to see if the map changed while getting the data.
if (ret != -UNW_EINVAL) {
- return true;
+ generated = true;
+ break;
}
}
- BACK_LOGW("Unable to generate the map.");
- return false;
+ pthread_rwlock_unlock(&map_lock_);
+
+ if (!generated) {
+ BACK_LOGW("Unable to generate the map.");
+ }
+ return generated;
}
bool UnwindMapLocal::Build() {
diff --git a/libbacktrace/UnwindMap.h b/libbacktrace/UnwindMap.h
index 111401f..f85b54a 100644
--- a/libbacktrace/UnwindMap.h
+++ b/libbacktrace/UnwindMap.h
@@ -17,6 +17,7 @@
#ifndef _LIBBACKTRACE_UNWIND_MAP_H
#define _LIBBACKTRACE_UNWIND_MAP_H
+#include <pthread.h>
#include <stdint.h>
#include <sys/types.h>
@@ -56,10 +57,15 @@
void FillIn(uintptr_t addr, backtrace_map_t* map) override;
+ void LockIterator() override { pthread_rwlock_rdlock(&map_lock_); }
+ void UnlockIterator() override { pthread_rwlock_unlock(&map_lock_); }
+
private:
bool GenerateMap();
bool map_created_;
+
+ pthread_rwlock_t map_lock_;
};
#endif // _LIBBACKTRACE_UNWIND_MAP_H
diff --git a/libbacktrace/backtrace_test.cpp b/libbacktrace/backtrace_test.cpp
index f6b2591..913e12d 100644
--- a/libbacktrace/backtrace_test.cpp
+++ b/libbacktrace/backtrace_test.cpp
@@ -896,6 +896,7 @@
std::unique_ptr<BacktraceMap> map(BacktraceMap::Create(pid));
// Basic test that verifies that the map is in the expected order.
+ ScopedBacktraceMapIteratorLock lock(map.get());
std::vector<map_test_t>::const_iterator test_it = test_maps.begin();
for (BacktraceMap::const_iterator it = map->begin(); it != map->end(); ++it) {
ASSERT_TRUE(test_it != test_maps.end());
diff --git a/liblog/event_tag_map.c b/liblog/event_tag_map.c
index 3cb04cf..345f0d3 100644
--- a/liblog/event_tag_map.c
+++ b/liblog/event_tag_map.c
@@ -99,6 +99,9 @@
if (processFile(newTagMap) != 0)
goto fail;
+ if (fd >= 0)
+ close(fd);
+
return newTagMap;
fail:
diff --git a/liblog/pmsg_writer.c b/liblog/pmsg_writer.c
index b338dca..944feba 100644
--- a/liblog/pmsg_writer.c
+++ b/liblog/pmsg_writer.c
@@ -31,8 +31,6 @@
#include <private/android_filesystem_config.h>
#include <private/android_logger.h>
-#include <sys/system_properties.h>
-
#include "config_write.h"
#include "log_portability.h"
#include "logger.h"
@@ -53,25 +51,8 @@
.write = pmsgWrite,
};
-static bool pmsgShouldUse = false;
-
-// Only use pmsg on eng builds
-static bool pmsgIsEng() {
- char buf[PROP_VALUE_MAX];
-
- if (__system_property_get("ro.build.type", buf) == 0) {
- return false;
- }
-
- if (!strncmp(buf, "eng", sizeof("eng"))) {
- return true;
- }
- return false;
-}
-
static int pmsgOpen()
{
- pmsgShouldUse = pmsgIsEng();
if (pmsgLoggerWrite.context.fd < 0) {
pmsgLoggerWrite.context.fd = TEMP_FAILURE_RETRY(open("/dev/pmsg0", O_WRONLY | O_CLOEXEC));
}
@@ -94,7 +75,7 @@
}
if ((logId != LOG_ID_SECURITY) &&
(logId != LOG_ID_EVENTS) &&
- (!pmsgShouldUse || !__android_log_is_debuggable())) {
+ !__android_log_is_debuggable()) {
return -EINVAL;
}
if (pmsgLoggerWrite.context.fd < 0) {
@@ -124,7 +105,7 @@
size_t i, payloadSize;
ssize_t ret;
- if ((logId == LOG_ID_EVENTS) && (!pmsgShouldUse || !__android_log_is_debuggable())) {
+ if ((logId == LOG_ID_EVENTS) && !__android_log_is_debuggable()) {
if (vec[0].iov_len < 4) {
return -EINVAL;
}
diff --git a/libutils/RefBase.cpp b/libutils/RefBase.cpp
index f90e28b..4ead19c 100644
--- a/libutils/RefBase.cpp
+++ b/libutils/RefBase.cpp
@@ -575,15 +575,14 @@
// grab a strong-reference, which is always safe due to the
// extended life-time.
curCount = impl->mStrong.fetch_add(1, std::memory_order_relaxed);
- }
-
- // If the strong reference count has already been incremented by
- // someone else, the implementor of onIncStrongAttempted() is holding
- // an unneeded reference. So call onLastStrongRef() here to remove it.
- // (No, this is not pretty.) Note that we MUST NOT do this if we
- // are in fact acquiring the first reference.
- if (curCount > 0 && curCount < INITIAL_STRONG_VALUE) {
- impl->mBase->onLastStrongRef(id);
+ // If the strong reference count has already been incremented by
+ // someone else, the implementor of onIncStrongAttempted() is holding
+ // an unneeded reference. So call onLastStrongRef() here to remove it.
+ // (No, this is not pretty.) Note that we MUST NOT do this if we
+ // are in fact acquiring the first reference.
+ if (curCount != 0 && curCount != INITIAL_STRONG_VALUE) {
+ impl->mBase->onLastStrongRef(id);
+ }
}
}
@@ -593,7 +592,7 @@
ALOGD("attemptIncStrong of %p from %p: cnt=%d\n", this, id, curCount);
#endif
- // curCount is the value of mStrong before we increment ed it.
+ // curCount is the value of mStrong before we incremented it.
// Now we need to fix-up the count if it was INITIAL_STRONG_VALUE.
// This must be done safely, i.e.: handle the case where several threads
// were here in attemptIncStrong().
diff --git a/logd/LogBuffer.cpp b/logd/LogBuffer.cpp
index 8c30f79..79a7e8c 100644
--- a/logd/LogBuffer.cpp
+++ b/logd/LogBuffer.cpp
@@ -691,7 +691,7 @@
&& ((!gc && (element->getPid() == worstPid))
|| (mLastWorstPidOfSystem[id].find(element->getPid())
== mLastWorstPidOfSystem[id].end()))) {
- mLastWorstPidOfSystem[id][element->getUid()] = it;
+ mLastWorstPidOfSystem[id][element->getPid()] = it;
}
if ((!gc && !worstPid && (element->getUid() == worst))
|| (mLastWorstUid[id].find(element->getUid())
diff --git a/rootdir/init.rc b/rootdir/init.rc
index 56379db..a9b6af0 100644
--- a/rootdir/init.rc
+++ b/rootdir/init.rc
@@ -236,6 +236,9 @@
export DOWNLOAD_CACHE /data/cache
+ # set RLIMIT_NICE to allow priorities from 19 to -20
+ setrlimit 13 40 40
+
# Healthd can trigger a full boot from charger mode by signaling this
# property when the power button is held.
on property:sys.boot_from_charger_mode=1
@@ -258,6 +261,11 @@
# Mount filesystems and start core system services.
on late-init
trigger early-fs
+
+ # Mount fstab in init.{$device}.rc by mount_all command. Optional parameter
+ # '--early' can be specified to skip entries with 'latemount'.
+ # /system and /vendor must be mounted by the end of the fs stage,
+ # while /data is optional.
trigger fs
trigger post-fs
@@ -266,9 +274,18 @@
# issued fs triggers have completed.
trigger load_system_props_action
+ # Mount fstab in init.{$device}.rc by mount_all with '--late' parameter
+ # to only mount entries with 'latemount'. This is needed if '--early' is
+ # specified in the previous mount_all command on the fs stage.
+ # With /system mounted and properties form /system + /factory available,
+ # some services can be started.
+ trigger late-fs
+
# Now we can mount /data. File encryption requires keymaster to decrypt
- # /data, which in turn can only be loaded when system properties are present
+ # /data, which in turn can only be loaded when system properties are present.
trigger post-fs-data
+
+ # Load persist properties and override properties (if enabled) from /data.
trigger load_persist_props_action
# Remove a file to wake up anything waiting for firmware.
@@ -484,9 +501,6 @@
hostname localhost
domainname localdomain
- # set RLIMIT_NICE to allow priorities from 19 to -20
- setrlimit 13 40 40
-
# Memory management. Basic kernel parameters, and allow the high
# level system server to be able to adjust the kernel OOM driver
# parameters to match how it is managing things.
diff --git a/sdcard/sdcard.c b/sdcard/sdcard.c
index 9480e4a..13ebaf1 100644
--- a/sdcard/sdcard.c
+++ b/sdcard/sdcard.c
@@ -1221,7 +1221,13 @@
}
out.fh = ptr_to_id(h);
out.open_flags = 0;
+
+#ifdef FUSE_SHORTCIRCUIT
+ out.lower_fd = h->fd;
+#else
out.padding = 0;
+#endif
+
fuse_reply(fuse, hdr->unique, &out, sizeof(out));
return NO_STATUS;
}
@@ -1385,7 +1391,13 @@
}
out.fh = ptr_to_id(h);
out.open_flags = 0;
+
+#ifdef FUSE_SHORTCIRCUIT
+ out.lower_fd = -1;
+#else
out.padding = 0;
+#endif
+
fuse_reply(fuse, hdr->unique, &out, sizeof(out));
return NO_STATUS;
}
@@ -1467,6 +1479,11 @@
out.major = FUSE_KERNEL_VERSION;
out.max_readahead = req->max_readahead;
out.flags = FUSE_ATOMIC_O_TRUNC | FUSE_BIG_WRITES;
+
+#ifdef FUSE_SHORTCIRCUIT
+ out.flags |= FUSE_SHORTCIRCUIT;
+#endif
+
out.max_background = 32;
out.congestion_threshold = 32;
out.max_write = MAX_WRITE;