Merge changes If1a62a90,Ibce79cf1,Ia2bbf01a,I1763be56,I56762747, ...
* changes:
logd: don't send logs before the start time on the first flushTo()
Revert "logd: drop mSequence from LogBufferElement"
Revert "logd: regression in handling watermark boundary."
Revert "logd: logcat --clear respect pruneMargin"
logd: wait for timeout via CLOCK_MONOTONIC
Revert "logd: wakeup wrap timeout if realtime changes drastically"
logd: do not attempt to sort log messages by time
diff --git a/init/first_stage_init.cpp b/init/first_stage_init.cpp
index bd71cb5..ef8ffbe 100644
--- a/init/first_stage_init.cpp
+++ b/init/first_stage_init.cpp
@@ -234,7 +234,16 @@
old_root_dir.reset();
}
- Modprobe m({"/lib/modules"});
+ std::string module_load_file = "modules.load";
+ if (IsRecoveryMode() && !ForceNormalBoot(cmdline)) {
+ struct stat fileStat;
+ std::string recovery_load_path = "/lib/modules/modules.load.recovery";
+ if (!stat(recovery_load_path.c_str(), &fileStat)) {
+ module_load_file = "modules.load.recovery";
+ }
+ }
+
+ Modprobe m({"/lib/modules"}, module_load_file);
auto want_console = ALLOW_FIRST_STAGE_CONSOLE && FirstStageConsole(cmdline);
if (!m.LoadListedModules(!want_console)) {
if (want_console) {
diff --git a/init/test_kill_services/Android.bp b/init/test_kill_services/Android.bp
index f6e85e2..d59e548 100644
--- a/init/test_kill_services/Android.bp
+++ b/init/test_kill_services/Android.bp
@@ -3,5 +3,9 @@
srcs: ["init_kill_services_test.cpp"],
shared_libs: ["libbase"],
test_suites: ["general-tests"],
- require_root: true,
+
+ // TODO(b/153565474): switch back to auto-generation
+ // and add back:
+ // require_root: true,
+ auto_gen_config: false,
}
diff --git a/init/test_kill_services/AndroidTest.xml b/init/test_kill_services/AndroidTest.xml
new file mode 100644
index 0000000..c1dcd59
--- /dev/null
+++ b/init/test_kill_services/AndroidTest.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2020 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.
+-->
+<configuration description="Runs init_kill_services_test.">
+ <option name="test-suite-tag" value="apct" />
+ <option name="test-suite-tag" value="apct-native" />
+
+ <!-- cannot be autogenerated: b/153565474 -->
+ <target_preparer class="com.android.tradefed.targetprep.RebootTargetPreparer" />
+
+ <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer"/>
+
+ <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
+ <option name="cleanup" value="true" />
+ <option name="push" value="init_kill_services_test->/data/local/tmp/init_kill_services_test" />
+ </target_preparer>
+
+ <test class="com.android.tradefed.testtype.GTest" >
+ <option name="native-test-device-path" value="/data/local/tmp" />
+ <option name="module-name" value="init_kill_services_test" />
+ </test>
+</configuration>
diff --git a/libmodprobe/include/modprobe/modprobe.h b/libmodprobe/include/modprobe/modprobe.h
index ee6ae7a..297036e 100644
--- a/libmodprobe/include/modprobe/modprobe.h
+++ b/libmodprobe/include/modprobe/modprobe.h
@@ -24,7 +24,7 @@
class Modprobe {
public:
- Modprobe(const std::vector<std::string>&);
+ Modprobe(const std::vector<std::string>&, const std::string load_file = "modules.load");
bool LoadListedModules(bool strict = true);
bool LoadWithAliases(const std::string& module_name, bool strict,
diff --git a/libmodprobe/libmodprobe.cpp b/libmodprobe/libmodprobe.cpp
index f22bbf1..d193796 100644
--- a/libmodprobe/libmodprobe.cpp
+++ b/libmodprobe/libmodprobe.cpp
@@ -312,7 +312,7 @@
}
}
-Modprobe::Modprobe(const std::vector<std::string>& base_paths) {
+Modprobe::Modprobe(const std::vector<std::string>& base_paths, const std::string load_file) {
using namespace std::placeholders;
for (const auto& base_path : base_paths) {
@@ -326,7 +326,7 @@
ParseCfg(base_path + "/modules.softdep", softdep_callback);
auto load_callback = std::bind(&Modprobe::ParseLoadCallback, this, _1);
- ParseCfg(base_path + "/modules.load", load_callback);
+ ParseCfg(base_path + "/" + load_file, load_callback);
auto options_callback = std::bind(&Modprobe::ParseOptionsCallback, this, _1);
ParseCfg(base_path + "/modules.options", options_callback);
diff --git a/libunwindstack/DexFile.cpp b/libunwindstack/DexFile.cpp
index bf63abf..8fc3d23 100644
--- a/libunwindstack/DexFile.cpp
+++ b/libunwindstack/DexFile.cpp
@@ -50,6 +50,22 @@
std::unique_ptr<DexFile> DexFile::Create(uint64_t dex_file_offset_in_memory, Memory* memory,
MapInfo* info) {
+ if (UNLIKELY(!HasDexSupport())) {
+ return nullptr;
+ }
+
+ size_t max_size = info->end - dex_file_offset_in_memory;
+ if (memory->IsLocal()) {
+ size_t size = max_size;
+
+ std::string err_msg;
+ std::unique_ptr<art_api::dex::DexFile> art_dex_file = DexFile::OpenFromMemory(
+ reinterpret_cast<void const*>(dex_file_offset_in_memory), &size, info->name, &err_msg);
+ if (art_dex_file != nullptr && size <= max_size) {
+ return std::unique_ptr<DexFile>(new DexFile(art_dex_file));
+ }
+ }
+
if (!info->name.empty()) {
std::unique_ptr<DexFile> dex_file =
DexFileFromFile::Create(dex_file_offset_in_memory - info->start + info->offset, info->name);
@@ -57,7 +73,7 @@
return dex_file;
}
}
- return DexFileFromMemory::Create(dex_file_offset_in_memory, memory, info->name);
+ return DexFileFromMemory::Create(dex_file_offset_in_memory, memory, info->name, max_size);
}
bool DexFile::GetMethodInformation(uint64_t dex_offset, std::string* method_name,
@@ -94,7 +110,8 @@
std::unique_ptr<DexFileFromMemory> DexFileFromMemory::Create(uint64_t dex_file_offset_in_memory,
Memory* memory,
- const std::string& name) {
+ const std::string& name,
+ size_t max_size) {
if (UNLIKELY(!HasDexSupport())) {
return nullptr;
}
@@ -105,6 +122,9 @@
std::string error_msg;
std::unique_ptr<art_api::dex::DexFile> art_dex_file =
OpenFromMemory(backing_memory.data(), &size, name, &error_msg);
+ if (size > max_size) {
+ return nullptr;
+ }
if (art_dex_file != nullptr) {
return std::unique_ptr<DexFileFromMemory>(
diff --git a/libunwindstack/DexFile.h b/libunwindstack/DexFile.h
index 4e8369f..fe185da 100644
--- a/libunwindstack/DexFile.h
+++ b/libunwindstack/DexFile.h
@@ -55,7 +55,8 @@
class DexFileFromMemory : public DexFile {
public:
static std::unique_ptr<DexFileFromMemory> Create(uint64_t dex_file_offset_in_memory,
- Memory* memory, const std::string& name);
+ Memory* memory, const std::string& name,
+ size_t max_size);
private:
DexFileFromMemory(std::unique_ptr<art_api::dex::DexFile>& art_dex_file,
diff --git a/libunwindstack/MemoryLocal.h b/libunwindstack/MemoryLocal.h
index 29aaf12..7e027cf 100644
--- a/libunwindstack/MemoryLocal.h
+++ b/libunwindstack/MemoryLocal.h
@@ -28,6 +28,8 @@
MemoryLocal() = default;
virtual ~MemoryLocal() = default;
+ bool IsLocal() const override { return true; }
+
size_t Read(uint64_t addr, void* dst, size_t size) override;
};
diff --git a/libunwindstack/include/unwindstack/Memory.h b/libunwindstack/include/unwindstack/Memory.h
index 3106564..ecd908a 100644
--- a/libunwindstack/include/unwindstack/Memory.h
+++ b/libunwindstack/include/unwindstack/Memory.h
@@ -41,6 +41,8 @@
virtual void Clear() {}
+ virtual bool IsLocal() const { return false; }
+
virtual size_t Read(uint64_t addr, void* dst, size_t size) = 0;
bool ReadFully(uint64_t addr, void* dst, size_t size);
diff --git a/libunwindstack/tests/DexFileTest.cpp b/libunwindstack/tests/DexFileTest.cpp
index dc935a3..1deba01 100644
--- a/libunwindstack/tests/DexFileTest.cpp
+++ b/libunwindstack/tests/DexFileTest.cpp
@@ -21,6 +21,7 @@
#include <unordered_map>
+#include <MemoryLocal.h>
#include <android-base/file.h>
#include <gtest/gtest.h>
#include <unwindstack/MapInfo.h>
@@ -109,7 +110,7 @@
memory.SetMemory(0x1000, kDexData, 10);
- EXPECT_TRUE(DexFileFromMemory::Create(0x1000, &memory, "") == nullptr);
+ EXPECT_TRUE(DexFileFromMemory::Create(0x1000, &memory, "", sizeof(kDexData)) == nullptr);
}
TEST(DexFileTest, from_memory_fail_too_small_for_data) {
@@ -117,7 +118,7 @@
memory.SetMemory(0x1000, kDexData, sizeof(kDexData) - 2);
- EXPECT_TRUE(DexFileFromMemory::Create(0x1000, &memory, "") == nullptr);
+ EXPECT_TRUE(DexFileFromMemory::Create(0x1000, &memory, "", sizeof(kDexData)) == nullptr);
}
TEST(DexFileTest, from_memory_open) {
@@ -125,7 +126,7 @@
memory.SetMemory(0x1000, kDexData, sizeof(kDexData));
- EXPECT_TRUE(DexFileFromMemory::Create(0x1000, &memory, "") != nullptr);
+ EXPECT_TRUE(DexFileFromMemory::Create(0x1000, &memory, "", sizeof(kDexData)) != nullptr);
}
TEST(DexFileTest, from_memory_no_leak) {
@@ -136,7 +137,7 @@
size_t first_allocated_bytes = 0;
size_t last_allocated_bytes = 0;
for (size_t i = 0; i < kNumLeakLoops; i++) {
- EXPECT_TRUE(DexFileFromMemory::Create(0x1000, &memory, "") != nullptr);
+ EXPECT_TRUE(DexFileFromMemory::Create(0x1000, &memory, "", sizeof(kDexData)) != nullptr);
ASSERT_NO_FATAL_FAILURE(CheckForLeak(i, &first_allocated_bytes, &last_allocated_bytes));
}
}
@@ -213,6 +214,43 @@
EXPECT_TRUE(dex_file == nullptr);
}
+TEST(DexFileTest, create_using_memory_size_too_small) {
+ MemoryFake memory;
+ memory.SetMemory(0x4000, kDexData, sizeof(kDexData));
+ MapInfo info(nullptr, nullptr, 0x100, sizeof(kDexData) - 2, 0x200, 0x5, "/does/not/exist");
+ EXPECT_TRUE(DexFile::Create(0x4000, &memory, &info) != nullptr);
+}
+
+class MemoryLocalFake : public MemoryLocal {
+ public:
+ MemoryLocalFake(size_t memory_size) : backing_(memory_size) {}
+ virtual ~MemoryLocalFake() = default;
+
+ void* Data() { return backing_.data(); }
+
+ private:
+ std::vector<void*> backing_;
+};
+
+TEST(DexFileTest, create_using_local_memory) {
+ MemoryLocalFake memory(sizeof(kDexData));
+
+ memcpy(memory.Data(), kDexData, sizeof(kDexData));
+ uint64_t start = reinterpret_cast<uint64_t>(memory.Data());
+ MapInfo info(nullptr, nullptr, start, start + 0x1000, 0x200, 0x5, "/does/not/exist");
+ EXPECT_TRUE(DexFile::Create(start, &memory, &info) != nullptr);
+}
+
+TEST(DexFileTest, create_using_local_memory_size_too_small) {
+ MemoryLocalFake memory(sizeof(kDexData));
+
+ memcpy(memory.Data(), kDexData, sizeof(kDexData));
+ uint64_t start = reinterpret_cast<uint64_t>(memory.Data());
+ MapInfo info(nullptr, nullptr, start, start + sizeof(kDexData) - 2, 0x200, 0x5,
+ "/does/not/exist");
+ EXPECT_TRUE(DexFile::Create(start, &memory, &info) == nullptr);
+}
+
TEST(DexFileTest, get_method) {
MemoryFake memory;
memory.SetMemory(0x4000, kDexData, sizeof(kDexData));