Merge "init: small header clean up"
diff --git a/CleanSpec.mk b/CleanSpec.mk
index ebe5f4a..6f6481f 100644
--- a/CleanSpec.mk
+++ b/CleanSpec.mk
@@ -80,3 +80,5 @@
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/recovery/root/)
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/root/sbin/charger)
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/recovery/root/sbin/charger)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/root/sbin)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/recovery/root/sbin)
diff --git a/adb/adb.cpp b/adb/adb.cpp
index e417f05..2dd22b3 100644
--- a/adb/adb.cpp
+++ b/adb/adb.cpp
@@ -280,6 +280,9 @@
} else if (type == "sideload") {
D("setting connection_state to kCsSideload");
t->SetConnectionState(kCsSideload);
+ } else if (type == "rescue") {
+ D("setting connection_state to kCsRescue");
+ t->SetConnectionState(kCsRescue);
} else {
D("setting connection_state to kCsHost");
t->SetConnectionState(kCsHost);
diff --git a/adb/adb.h b/adb/adb.h
index c60dcbc..3a6f059 100644
--- a/adb/adb.h
+++ b/adb/adb.h
@@ -107,6 +107,7 @@
kCsHost,
kCsRecovery,
kCsSideload,
+ kCsRescue,
};
inline bool ConnectionStateIsOnline(ConnectionState state) {
@@ -116,6 +117,7 @@
case kCsHost:
case kCsRecovery:
case kCsSideload:
+ case kCsRescue:
return true;
default:
return false;
diff --git a/adb/client/commandline.cpp b/adb/client/commandline.cpp
index 43a3e5e..f25955d 100644
--- a/adb/client/commandline.cpp
+++ b/adb/client/commandline.cpp
@@ -190,7 +190,7 @@
"scripting:\n"
" wait-for[-TRANSPORT]-STATE\n"
" wait for device to be in the given state\n"
- " STATE: device, recovery, sideload, bootloader, or disconnect\n"
+ " STATE: device, recovery, rescue, sideload, bootloader, or disconnect\n"
" TRANSPORT: usb, local, or any [default=any]\n"
" get-state print offline | bootloader | device\n"
" get-serialno print <serial-number>\n"
@@ -1037,11 +1037,12 @@
}
if (components[3] != "any" && components[3] != "bootloader" && components[3] != "device" &&
- components[3] != "recovery" && components[3] != "sideload" &&
+ components[3] != "recovery" && components[3] != "rescue" && components[3] != "sideload" &&
components[3] != "disconnect") {
fprintf(stderr,
"adb: unknown state %s; "
- "expected 'any', 'bootloader', 'device', 'recovery', 'sideload', or 'disconnect'\n",
+ "expected 'any', 'bootloader', 'device', 'recovery', 'rescue', 'sideload', or "
+ "'disconnect'\n",
components[3].c_str());
return false;
}
diff --git a/adb/daemon/usb.cpp b/adb/daemon/usb.cpp
index 8c33ca5..3b29ab5 100644
--- a/adb/daemon/usb.cpp
+++ b/adb/daemon/usb.cpp
@@ -57,11 +57,12 @@
// We can't find out whether we have support for AIO on ffs endpoints until we submit a read.
static std::optional<bool> gFfsAioSupported;
+// Not all USB controllers support operations larger than 16k, so don't go above that.
static constexpr size_t kUsbReadQueueDepth = 32;
-static constexpr size_t kUsbReadSize = 8 * PAGE_SIZE;
+static constexpr size_t kUsbReadSize = 4 * PAGE_SIZE;
static constexpr size_t kUsbWriteQueueDepth = 32;
-static constexpr size_t kUsbWriteSize = 8 * PAGE_SIZE;
+static constexpr size_t kUsbWriteSize = 4 * PAGE_SIZE;
static const char* to_string(enum usb_functionfs_event_type type) {
switch (type) {
diff --git a/adb/services.cpp b/adb/services.cpp
index cf346ba..335ffc4 100644
--- a/adb/services.cpp
+++ b/adb/services.cpp
@@ -227,6 +227,8 @@
sinfo->state = kCsDevice;
} else if (name == "-recovery") {
sinfo->state = kCsRecovery;
+ } else if (name == "-rescue") {
+ sinfo->state = kCsRescue;
} else if (name == "-sideload") {
sinfo->state = kCsSideload;
} else if (name == "-bootloader") {
diff --git a/adb/transport.cpp b/adb/transport.cpp
index 15c3a9a..841865a 100644
--- a/adb/transport.cpp
+++ b/adb/transport.cpp
@@ -1012,6 +1012,8 @@
return "host";
case kCsRecovery:
return "recovery";
+ case kCsRescue:
+ return "rescue";
case kCsNoPerm:
return UsbNoPermissionsShortHelpText();
case kCsSideload:
diff --git a/debuggerd/Android.bp b/debuggerd/Android.bp
index 0cf3378..2e226da 100644
--- a/debuggerd/Android.bp
+++ b/debuggerd/Android.bp
@@ -183,6 +183,12 @@
],
},
},
+
+ product_variables: {
+ debuggable: {
+ cflags: ["-DROOT_POSSIBLE"],
+ },
+ },
}
cc_test {
diff --git a/debuggerd/libdebuggerd/backtrace.cpp b/debuggerd/libdebuggerd/backtrace.cpp
index 94fcfb2..c606970 100644
--- a/debuggerd/libdebuggerd/backtrace.cpp
+++ b/debuggerd/libdebuggerd/backtrace.cpp
@@ -74,10 +74,7 @@
return;
}
- unwinder->SetDisplayBuildID(true);
- for (size_t i = 0; i < unwinder->NumFrames(); i++) {
- _LOG(&log, logtype::BACKTRACE, " %s\n", unwinder->FormatFrame(i).c_str());
- }
+ log_backtrace(&log, unwinder, " ");
}
void dump_backtrace(android::base::unique_fd output_fd, unwindstack::Unwinder* unwinder,
diff --git a/debuggerd/libdebuggerd/include/libdebuggerd/utility.h b/debuggerd/libdebuggerd/include/libdebuggerd/utility.h
index 238c00c..f189c45 100644
--- a/debuggerd/libdebuggerd/include/libdebuggerd/utility.h
+++ b/debuggerd/libdebuggerd/include/libdebuggerd/utility.h
@@ -73,9 +73,12 @@
void _LOG(log_t* log, logtype ltype, const char* fmt, ...) __attribute__((format(printf, 3, 4)));
namespace unwindstack {
+class Unwinder;
class Memory;
}
+void log_backtrace(log_t* log, unwindstack::Unwinder* unwinder, const char* prefix);
+
void dump_memory(log_t* log, unwindstack::Memory* backtrace, uint64_t addr, const std::string&);
void read_with_default(const char* path, char* buf, size_t len, const char* default_value);
diff --git a/debuggerd/libdebuggerd/tombstone.cpp b/debuggerd/libdebuggerd/tombstone.cpp
index cc337ed..d1726cd 100644
--- a/debuggerd/libdebuggerd/tombstone.cpp
+++ b/debuggerd/libdebuggerd/tombstone.cpp
@@ -371,13 +371,6 @@
}
}
-void dump_backtrace(log_t* log, unwindstack::Unwinder* unwinder, const char* prefix) {
- unwinder->SetDisplayBuildID(true);
- for (size_t i = 0; i < unwinder->NumFrames(); i++) {
- _LOG(log, logtype::BACKTRACE, "%s%s\n", prefix, unwinder->FormatFrame(i).c_str());
- }
-}
-
static void print_register_row(log_t* log,
const std::vector<std::pair<std::string, uint64_t>>& registers) {
std::string output;
@@ -470,7 +463,7 @@
_LOG(log, logtype::THREAD, "Failed to unwind");
} else {
_LOG(log, logtype::BACKTRACE, "\nbacktrace:\n");
- dump_backtrace(log, unwinder, " ");
+ log_backtrace(log, unwinder, " ");
_LOG(log, logtype::STACK, "\nstack:\n");
dump_stack(log, unwinder->frames(), unwinder->GetMaps(), unwinder->GetProcessMemory().get());
diff --git a/debuggerd/libdebuggerd/utility.cpp b/debuggerd/libdebuggerd/utility.cpp
index 7aebea8..9b2779a 100644
--- a/debuggerd/libdebuggerd/utility.cpp
+++ b/debuggerd/libdebuggerd/utility.cpp
@@ -38,6 +38,7 @@
#include <debuggerd/handler.h>
#include <log/log.h>
#include <unwindstack/Memory.h>
+#include <unwindstack/Unwinder.h>
using android::base::unique_fd;
@@ -422,3 +423,22 @@
// Then give up...
return "?";
}
+
+void log_backtrace(log_t* log, unwindstack::Unwinder* unwinder, const char* prefix) {
+ if (unwinder->elf_from_memory_not_file()) {
+ _LOG(log, logtype::BACKTRACE,
+ "%sNOTE: Function names and BuildId information is missing for some frames due\n", prefix);
+ _LOG(log, logtype::BACKTRACE,
+ "%sNOTE: to unreadable libraries. For unwinds of apps, only shared libraries\n", prefix);
+ _LOG(log, logtype::BACKTRACE, "%sNOTE: found under the lib/ directory are readable.\n", prefix);
+#if defined(ROOT_POSSIBLE)
+ _LOG(log, logtype::BACKTRACE,
+ "%sNOTE: On this device, run setenforce 0 to make the libraries readable.\n", prefix);
+#endif
+ }
+
+ unwinder->SetDisplayBuildID(true);
+ for (size_t i = 0; i < unwinder->NumFrames(); i++) {
+ _LOG(log, logtype::BACKTRACE, "%s%s\n", prefix, unwinder->FormatFrame(i).c_str());
+ }
+}
diff --git a/fs_mgr/fs_mgr.cpp b/fs_mgr/fs_mgr.cpp
index 5114f55..c1aafda 100644
--- a/fs_mgr/fs_mgr.cpp
+++ b/fs_mgr/fs_mgr.cpp
@@ -1695,11 +1695,12 @@
std::string fs_mgr_get_super_partition_name(int slot) {
// Devices upgrading to dynamic partitions are allowed to specify a super
- // partition name, assumed to be A/B (non-A/B retrofit is not supported).
- // For devices launching with dynamic partition support, the partition
- // name must be "super".
+ // partition name. This includes cuttlefish, which is a non-A/B device.
std::string super_partition;
if (fs_mgr_get_boot_config_from_kernel_cmdline("super_partition", &super_partition)) {
+ if (fs_mgr_get_slot_suffix().empty()) {
+ return super_partition;
+ }
std::string suffix;
if (slot == 0) {
suffix = "_a";
diff --git a/init/builtins.cpp b/init/builtins.cpp
index fc75072..06da4be 100644
--- a/init/builtins.cpp
+++ b/init/builtins.cpp
@@ -451,78 +451,6 @@
if (false) DumpState();
}
-/* handle_fstab
- *
- * Read the given fstab file and execute func on it.
- */
-static Result<int> handle_fstab(const std::string& fstabfile, std::function<int(Fstab*)> func) {
- /*
- * Call fs_mgr_[u]mount_all() to [u]mount all filesystems. We fork(2) and
- * do the call in the child to provide protection to the main init
- * process if anything goes wrong (crash or memory leak), and wait for
- * the child to finish in the parent.
- */
- pid_t pid = fork();
- if (pid > 0) {
- /* Parent. Wait for the child to return */
- int status;
- int wp_ret = TEMP_FAILURE_RETRY(waitpid(pid, &status, 0));
- if (wp_ret == -1) {
- // Unexpected error code. We will continue anyway.
- PLOG(WARNING) << "waitpid failed";
- }
-
- if (WIFEXITED(status)) {
- return WEXITSTATUS(status);
- } else {
- return Error() << "child aborted";
- }
- } else if (pid == 0) {
- /* child, call fs_mgr_[u]mount_all() */
-
- // So we can always see what fs_mgr_[u]mount_all() does.
- // Only needed if someone explicitly changes the default log level in their init.rc.
- android::base::ScopedLogSeverity info(android::base::INFO);
-
- Fstab fstab;
- ReadFstabFromFile(fstabfile, &fstab);
-
- int child_ret = func(&fstab);
-
- _exit(child_ret);
- } else {
- return Error() << "fork() failed";
- }
-}
-
-/* mount_fstab
- *
- * Call fs_mgr_mount_all() to mount the given fstab
- */
-static Result<int> mount_fstab(const std::string& fstabfile, int mount_mode) {
- return handle_fstab(fstabfile, [mount_mode](Fstab* fstab) {
- int ret = fs_mgr_mount_all(fstab, mount_mode);
- if (ret == -1) {
- PLOG(ERROR) << "fs_mgr_mount_all returned an error";
- }
- return ret;
- });
-}
-
-/* umount_fstab
- *
- * Call fs_mgr_umount_all() to umount the given fstab
- */
-static Result<int> umount_fstab(const std::string& fstabfile) {
- return handle_fstab(fstabfile, [](Fstab* fstab) {
- int ret = fs_mgr_umount_all(fstab);
- if (ret != 0) {
- PLOG(ERROR) << "fs_mgr_umount_all returned " << ret;
- }
- return ret;
- });
-}
-
/* Queue event based on fs_mgr return code.
*
* code: return code of fs_mgr_mount_all
@@ -609,7 +537,7 @@
bool import_rc = true;
bool queue_event = true;
int mount_mode = MOUNT_MODE_DEFAULT;
- const auto& fstabfile = args[1];
+ const auto& fstab_file = args[1];
std::size_t path_arg_end = args.size();
const char* prop_post_fix = "default";
@@ -629,10 +557,12 @@
std::string prop_name = "ro.boottime.init.mount_all."s + prop_post_fix;
android::base::Timer t;
- auto mount_fstab_return_code = mount_fstab(fstabfile, mount_mode);
- if (!mount_fstab_return_code) {
- return Error() << "mount_fstab() failed " << mount_fstab_return_code.error();
+
+ Fstab fstab;
+ if (!ReadFstabFromFile(fstab_file, &fstab)) {
+ return Error() << "Could not read fstab";
}
+ auto mount_fstab_return_code = fs_mgr_mount_all(&fstab, mount_mode);
property_set(prop_name, std::to_string(t.duration().count()));
if (import_rc) {
@@ -643,7 +573,7 @@
if (queue_event) {
/* queue_fs_event will queue event based on mount_fstab return code
* and return processed return code*/
- auto queue_fs_result = queue_fs_event(*mount_fstab_return_code);
+ auto queue_fs_result = queue_fs_event(mount_fstab_return_code);
if (!queue_fs_result) {
return Error() << "queue_fs_event() failed: " << queue_fs_result.error();
}
@@ -654,9 +584,13 @@
/* umount_all <fstab> */
static Result<Success> do_umount_all(const BuiltinArguments& args) {
- auto umount_fstab_return_code = umount_fstab(args[1]);
- if (!umount_fstab_return_code) {
- return Error() << "umount_fstab() failed " << umount_fstab_return_code.error();
+ Fstab fstab;
+ if (!ReadFstabFromFile(args[1], &fstab)) {
+ return Error() << "Could not read fstab";
+ }
+
+ if (auto result = fs_mgr_umount_all(&fstab); result != 0) {
+ return Error() << "umount_fstab() failed " << result;
}
return Success();
}
diff --git a/init/init.cpp b/init/init.cpp
index 0f44efd..ac0e67a 100644
--- a/init/init.cpp
+++ b/init/init.cpp
@@ -630,6 +630,11 @@
InitKernelLogging(argv, InitAborter);
LOG(INFO) << "init second stage started!";
+ // Set init and its forked children's oom_adj.
+ if (auto result = WriteFile("/proc/1/oom_score_adj", "-1000"); !result) {
+ LOG(ERROR) << "Unable to write -1000 to /proc/1/oom_score_adj: " << result.error();
+ }
+
// Enable seccomp if global boot option was passed (otherwise it is enabled in zygote).
GlobalSeccomp();
diff --git a/libmeminfo/tools/procrank.cpp b/libmeminfo/tools/procrank.cpp
index 5e89254..cb3757d 100644
--- a/libmeminfo/tools/procrank.cpp
+++ b/libmeminfo/tools/procrank.cpp
@@ -42,7 +42,6 @@
public:
ProcessRecord(pid_t pid, bool get_wss = false, uint64_t pgflags = 0, uint64_t pgflags_mask = 0)
: pid_(-1),
- procmem_(nullptr),
oomadj_(OOM_SCORE_ADJ_MAX + 1),
cmdline_(""),
proportional_swap_(0),
@@ -79,15 +78,15 @@
// The .c_str() assignment below then takes care of trimming the cmdline at the first
// 0x00. This is how original procrank worked (luckily)
cmdline_.resize(strlen(cmdline_.c_str()));
- procmem_ = std::move(procmem);
+ usage_or_wss_ = get_wss ? procmem->Wss() : procmem->Usage();
+ swap_offsets_ = procmem->SwapOffsets();
pid_ = pid;
}
bool valid() const { return pid_ != -1; }
void CalculateSwap(const uint16_t* swap_offset_array, float zram_compression_ratio) {
- const std::vector<uint16_t>& swp_offs = procmem_->SwapOffsets();
- for (auto& off : swp_offs) {
+ for (auto& off : swap_offsets_) {
proportional_swap_ += getpagesize() / swap_offset_array[off];
unique_swap_ += swap_offset_array[off] == 1 ? getpagesize() : 0;
zswap_ = proportional_swap_ * zram_compression_ratio;
@@ -103,18 +102,19 @@
uint64_t zswap() const { return zswap_; }
// Wrappers to ProcMemInfo
- const std::vector<uint16_t>& SwapOffsets() const { return procmem_->SwapOffsets(); }
- const MemUsage& Usage() const { return procmem_->Usage(); }
- const MemUsage& Wss() const { return procmem_->Wss(); }
+ const std::vector<uint16_t>& SwapOffsets() const { return swap_offsets_; }
+ const MemUsage& Usage() const { return usage_or_wss_; }
+ const MemUsage& Wss() const { return usage_or_wss_; }
private:
pid_t pid_;
- std::unique_ptr<ProcMemInfo> procmem_;
int32_t oomadj_;
std::string cmdline_;
uint64_t proportional_swap_;
uint64_t unique_swap_;
uint64_t zswap_;
+ MemUsage usage_or_wss_;
+ std::vector<uint16_t> swap_offsets_;
};
// Show working set instead of memory consumption
@@ -171,7 +171,7 @@
while ((dir = readdir(procdir.get()))) {
if (!::android::base::ParseInt(dir->d_name, &pid)) continue;
if (!for_each_pid(pid)) return false;
- pids->push_back(pid);
+ pids->emplace_back(pid);
}
return true;
@@ -471,7 +471,7 @@
}
// Skip processes with no memory mappings
- uint64_t vss = proc.Usage().vss;
+ uint64_t vss = show_wss ? proc.Wss().vss : proc.Usage().vss;
if (vss == 0) return true;
// collect swap_offset counts from all processes in 1st pass
@@ -481,7 +481,7 @@
return false;
}
- procs.push_back(std::move(proc));
+ procs.emplace_back(std::move(proc));
return true;
};
diff --git a/libprocessgroup/sched_policy.cpp b/libprocessgroup/sched_policy.cpp
index c7d0cca..ab0f1ca 100644
--- a/libprocessgroup/sched_policy.cpp
+++ b/libprocessgroup/sched_policy.cpp
@@ -126,24 +126,15 @@
switch (policy) {
case SP_BACKGROUND:
- return SetTaskProfiles(tid, {"HighEnergySaving", "LowIoPriority", "TimerSlackHigh"})
- ? 0
- : -1;
+ return SetTaskProfiles(tid, {"HighEnergySaving", "TimerSlackHigh"}) ? 0 : -1;
case SP_FOREGROUND:
case SP_AUDIO_APP:
case SP_AUDIO_SYS:
- return SetTaskProfiles(tid, {"HighPerformance", "HighIoPriority", "TimerSlackNormal"})
- ? 0
- : -1;
+ return SetTaskProfiles(tid, {"HighPerformance", "TimerSlackNormal"}) ? 0 : -1;
case SP_TOP_APP:
- return SetTaskProfiles(tid, {"MaxPerformance", "MaxIoPriority", "TimerSlackNormal"})
- ? 0
- : -1;
+ return SetTaskProfiles(tid, {"MaxPerformance", "TimerSlackNormal"}) ? 0 : -1;
case SP_RT_APP:
- return SetTaskProfiles(tid,
- {"RealtimePerformance", "MaxIoPriority", "TimerSlackNormal"})
- ? 0
- : -1;
+ return SetTaskProfiles(tid, {"RealtimePerformance", "TimerSlackNormal"}) ? 0 : -1;
default:
return SetTaskProfiles(tid, {"TimerSlackNormal"}) ? 0 : -1;
}
diff --git a/libunwindstack/MapInfo.cpp b/libunwindstack/MapInfo.cpp
index 28373b2..03658b4 100644
--- a/libunwindstack/MapInfo.cpp
+++ b/libunwindstack/MapInfo.cpp
@@ -161,6 +161,7 @@
// option is used.
std::unique_ptr<MemoryRange> memory(new MemoryRange(process_memory, start, end - start, 0));
if (Elf::IsValidElf(memory.get())) {
+ memory_backed_elf = true;
return memory.release();
}
@@ -184,6 +185,7 @@
new MemoryRange(process_memory, prev_map->start, prev_map->end - prev_map->start, 0));
ranges->Insert(new MemoryRange(process_memory, start, end - start, elf_offset));
+ memory_backed_elf = true;
return ranges;
}
@@ -237,6 +239,7 @@
std::lock_guard<std::mutex> guard(prev_map->mutex_);
if (prev_map->elf.get() == nullptr) {
prev_map->elf = elf;
+ prev_map->memory_backed_elf = memory_backed_elf;
}
}
return elf.get();
diff --git a/libunwindstack/Unwinder.cpp b/libunwindstack/Unwinder.cpp
index f3d2b5e..26626b5 100644
--- a/libunwindstack/Unwinder.cpp
+++ b/libunwindstack/Unwinder.cpp
@@ -141,6 +141,7 @@
frames_.clear();
last_error_.code = ERROR_NONE;
last_error_.address = 0;
+ elf_from_memory_not_file_ = false;
ArchEnum arch = regs_->Arch();
@@ -164,6 +165,12 @@
break;
}
elf = map_info->GetElf(process_memory_, arch);
+ // If this elf is memory backed, and there is a valid file, then set
+ // an indicator that we couldn't open the file.
+ if (!elf_from_memory_not_file_ && map_info->memory_backed_elf && !map_info->name.empty() &&
+ map_info->name[0] != '[') {
+ elf_from_memory_not_file_ = true;
+ }
step_pc = regs_->pc();
rel_pc = elf->GetRelPc(step_pc, map_info);
// Everyone except elf data in gdb jit debug maps uses the relative pc.
diff --git a/libunwindstack/include/unwindstack/MapInfo.h b/libunwindstack/include/unwindstack/MapInfo.h
index e938986..025fd98 100644
--- a/libunwindstack/include/unwindstack/MapInfo.h
+++ b/libunwindstack/include/unwindstack/MapInfo.h
@@ -75,6 +75,9 @@
// make it easier to move to a fine grained lock in the future.
std::atomic_uintptr_t build_id;
+ // Set to true if the elf file data is coming from memory.
+ bool memory_backed_elf = false;
+
// This function guarantees it will never return nullptr.
Elf* GetElf(const std::shared_ptr<Memory>& process_memory, ArchEnum expected_arch);
diff --git a/libunwindstack/include/unwindstack/Unwinder.h b/libunwindstack/include/unwindstack/Unwinder.h
index 75be209..52b3578 100644
--- a/libunwindstack/include/unwindstack/Unwinder.h
+++ b/libunwindstack/include/unwindstack/Unwinder.h
@@ -111,6 +111,8 @@
void SetDexFiles(DexFiles* dex_files, ArchEnum arch);
#endif
+ bool elf_from_memory_not_file() { return elf_from_memory_not_file_; }
+
ErrorCode LastErrorCode() { return last_error_.code; }
uint64_t LastErrorAddress() { return last_error_.address; }
@@ -132,6 +134,9 @@
bool resolve_names_ = true;
bool embedded_soname_ = true;
bool display_build_id_ = false;
+ // True if at least one elf file is coming from memory and not the related
+ // file. This is only true if there is an actual file backing up the elf.
+ bool elf_from_memory_not_file_ = false;
ErrorData last_error_;
};
diff --git a/libunwindstack/tests/MapInfoCreateMemoryTest.cpp b/libunwindstack/tests/MapInfoCreateMemoryTest.cpp
index 2ddadef..6be8bdc 100644
--- a/libunwindstack/tests/MapInfoCreateMemoryTest.cpp
+++ b/libunwindstack/tests/MapInfoCreateMemoryTest.cpp
@@ -108,6 +108,7 @@
info.end = 0x101;
memory.reset(info.CreateMemory(process_memory_));
ASSERT_TRUE(memory.get() != nullptr);
+ EXPECT_FALSE(info.memory_backed_elf);
}
// Verify that if the offset is non-zero but there is no elf at the offset,
@@ -117,6 +118,7 @@
std::unique_ptr<Memory> memory(info.CreateMemory(process_memory_));
ASSERT_TRUE(memory.get() != nullptr);
+ EXPECT_FALSE(info.memory_backed_elf);
ASSERT_EQ(0x100U, info.elf_offset);
EXPECT_EQ(0x100U, info.elf_start_offset);
@@ -140,32 +142,40 @@
// offset to zero.
info.elf_offset = 0;
info.elf_start_offset = 0;
+ info.memory_backed_elf = false;
memory.reset(info.CreateMemory(process_memory_));
ASSERT_TRUE(memory.get() != nullptr);
+ EXPECT_FALSE(info.memory_backed_elf);
ASSERT_EQ(0x100U, info.elf_offset);
EXPECT_EQ(0x100U, info.elf_start_offset);
prev_info.offset = 0;
info.elf_offset = 0;
info.elf_start_offset = 0;
+ info.memory_backed_elf = false;
memory.reset(info.CreateMemory(process_memory_));
ASSERT_TRUE(memory.get() != nullptr);
+ EXPECT_FALSE(info.memory_backed_elf);
ASSERT_EQ(0x100U, info.elf_offset);
EXPECT_EQ(0x100U, info.elf_start_offset);
prev_info.flags = PROT_READ;
info.elf_offset = 0;
info.elf_start_offset = 0;
+ info.memory_backed_elf = false;
memory.reset(info.CreateMemory(process_memory_));
ASSERT_TRUE(memory.get() != nullptr);
+ EXPECT_FALSE(info.memory_backed_elf);
ASSERT_EQ(0x100U, info.elf_offset);
EXPECT_EQ(0x100U, info.elf_start_offset);
prev_info.name = info.name;
info.elf_offset = 0;
info.elf_start_offset = 0;
+ info.memory_backed_elf = false;
memory.reset(info.CreateMemory(process_memory_));
ASSERT_TRUE(memory.get() != nullptr);
+ EXPECT_FALSE(info.memory_backed_elf);
ASSERT_EQ(0x100U, info.elf_offset);
EXPECT_EQ(0U, info.elf_start_offset);
}
@@ -177,6 +187,7 @@
std::unique_ptr<Memory> memory(info.CreateMemory(process_memory_));
ASSERT_TRUE(memory.get() != nullptr);
+ EXPECT_FALSE(info.memory_backed_elf);
ASSERT_EQ(0U, info.elf_offset);
EXPECT_EQ(0x1000U, info.elf_start_offset);
@@ -201,6 +212,7 @@
std::unique_ptr<Memory> memory(info.CreateMemory(process_memory_));
ASSERT_TRUE(memory.get() != nullptr);
+ EXPECT_FALSE(info.memory_backed_elf);
ASSERT_EQ(0U, info.elf_offset);
EXPECT_EQ(0x1000U, info.elf_start_offset);
@@ -218,6 +230,7 @@
std::unique_ptr<Memory> memory(info.CreateMemory(process_memory_));
ASSERT_TRUE(memory.get() != nullptr);
+ EXPECT_FALSE(info.memory_backed_elf);
ASSERT_EQ(0U, info.elf_offset);
EXPECT_EQ(0x2000U, info.elf_start_offset);
@@ -259,6 +272,7 @@
std::unique_ptr<Memory> memory(info.CreateMemory(process_memory_));
ASSERT_TRUE(memory.get() != nullptr);
+ EXPECT_TRUE(info.memory_backed_elf);
memset(buffer.data(), 0, buffer.size());
ASSERT_TRUE(memory->ReadFully(0, buffer.data(), buffer.size()));
@@ -290,6 +304,7 @@
std::unique_ptr<Memory> mem(map_info->CreateMemory(process_memory_));
ASSERT_TRUE(mem.get() != nullptr);
+ EXPECT_TRUE(map_info->memory_backed_elf);
EXPECT_EQ(0x4000UL, map_info->elf_offset);
EXPECT_EQ(0x4000UL, map_info->offset);
EXPECT_EQ(0U, map_info->elf_start_offset);
@@ -336,6 +351,7 @@
std::unique_ptr<Memory> mem(map_info->CreateMemory(process_memory_));
ASSERT_TRUE(mem.get() != nullptr);
+ EXPECT_TRUE(map_info->memory_backed_elf);
EXPECT_EQ(0x1000UL, map_info->elf_offset);
EXPECT_EQ(0xb000UL, map_info->offset);
EXPECT_EQ(0xa000UL, map_info->elf_start_offset);
@@ -374,6 +390,7 @@
// extend over the executable segment.
std::unique_ptr<Memory> memory(map_info->CreateMemory(process_memory_));
ASSERT_TRUE(memory.get() != nullptr);
+ EXPECT_FALSE(map_info->memory_backed_elf);
std::vector<uint8_t> buffer(0x100);
EXPECT_EQ(0x2000U, map_info->offset);
EXPECT_EQ(0U, map_info->elf_offset);
@@ -388,7 +405,9 @@
ASSERT_EQ(0x1000, lseek(elf_at_1000_.fd, 0x1000, SEEK_SET));
ASSERT_TRUE(android::base::WriteFully(elf_at_1000_.fd, &ehdr, sizeof(ehdr)));
+ map_info->memory_backed_elf = false;
memory.reset(map_info->CreateMemory(process_memory_));
+ EXPECT_FALSE(map_info->memory_backed_elf);
EXPECT_EQ(0x2000U, map_info->offset);
EXPECT_EQ(0x1000U, map_info->elf_offset);
EXPECT_EQ(0x1000U, map_info->elf_start_offset);
diff --git a/libunwindstack/tests/UnwinderTest.cpp b/libunwindstack/tests/UnwinderTest.cpp
index 48e038e..f635021 100644
--- a/libunwindstack/tests/UnwinderTest.cpp
+++ b/libunwindstack/tests/UnwinderTest.cpp
@@ -108,6 +108,24 @@
const auto& info2 = *--maps_->end();
info2->elf_offset = 0x8000;
+ elf = new ElfFake(new MemoryFake);
+ elf->FakeSetInterface(new ElfInterfaceFake(nullptr));
+ AddMapInfo(0xc0000, 0xc1000, 0, PROT_READ | PROT_WRITE | PROT_EXEC, "/fake/unreadable.so", elf);
+ const auto& info3 = *--maps_->end();
+ info3->memory_backed_elf = true;
+
+ elf = new ElfFake(new MemoryFake);
+ elf->FakeSetInterface(new ElfInterfaceFake(nullptr));
+ AddMapInfo(0xc1000, 0xc2000, 0, PROT_READ | PROT_WRITE | PROT_EXEC, "[vdso]", elf);
+ const auto& info4 = *--maps_->end();
+ info4->memory_backed_elf = true;
+
+ elf = new ElfFake(new MemoryFake);
+ elf->FakeSetInterface(new ElfInterfaceFake(nullptr));
+ AddMapInfo(0xc2000, 0xc3000, 0, PROT_READ | PROT_WRITE | PROT_EXEC, "", elf);
+ const auto& info5 = *--maps_->end();
+ info5->memory_backed_elf = true;
+
process_memory_.reset(new MemoryFake);
}
@@ -140,6 +158,7 @@
Unwinder unwinder(64, maps_.get(), ®s_, process_memory_);
unwinder.Unwind();
EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
+ EXPECT_FALSE(unwinder.elf_from_memory_not_file());
ASSERT_EQ(3U, unwinder.NumFrames());
@@ -204,6 +223,7 @@
unwinder.SetResolveNames(false);
unwinder.Unwind();
EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
+ EXPECT_FALSE(unwinder.elf_from_memory_not_file());
ASSERT_EQ(3U, unwinder.NumFrames());
@@ -263,6 +283,7 @@
Unwinder unwinder(64, maps_.get(), ®s_, process_memory_);
unwinder.Unwind();
EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
+ EXPECT_FALSE(unwinder.elf_from_memory_not_file());
ASSERT_EQ(1U, unwinder.NumFrames());
@@ -292,6 +313,7 @@
Unwinder unwinder(64, maps_.get(), ®s_, process_memory_);
unwinder.Unwind();
EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
+ EXPECT_FALSE(unwinder.elf_from_memory_not_file());
ASSERT_EQ(1U, unwinder.NumFrames());
@@ -321,6 +343,7 @@
Unwinder unwinder(64, maps_.get(), ®s_, process_memory_);
unwinder.Unwind();
EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
+ EXPECT_FALSE(unwinder.elf_from_memory_not_file());
ASSERT_EQ(1U, unwinder.NumFrames());
@@ -351,6 +374,7 @@
unwinder.SetEmbeddedSoname(false);
unwinder.Unwind();
EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
+ EXPECT_FALSE(unwinder.elf_from_memory_not_file());
ASSERT_EQ(1U, unwinder.NumFrames());
@@ -387,6 +411,7 @@
Unwinder unwinder(64, maps_.get(), ®s_, process_memory_);
unwinder.Unwind();
EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
+ EXPECT_FALSE(unwinder.elf_from_memory_not_file());
ASSERT_EQ(1U, unwinder.NumFrames());
@@ -419,6 +444,7 @@
Unwinder unwinder(20, maps_.get(), ®s_, process_memory_);
unwinder.Unwind();
EXPECT_EQ(ERROR_MAX_FRAMES_EXCEEDED, unwinder.LastErrorCode());
+ EXPECT_FALSE(unwinder.elf_from_memory_not_file());
ASSERT_EQ(20U, unwinder.NumFrames());
@@ -461,6 +487,7 @@
std::vector<std::string> skip_libs{"libunwind.so", "libanother.so"};
unwinder.Unwind(&skip_libs);
EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
+ EXPECT_FALSE(unwinder.elf_from_memory_not_file());
ASSERT_EQ(3U, unwinder.NumFrames());
@@ -522,6 +549,7 @@
Unwinder unwinder(64, maps_.get(), ®s_, process_memory_);
unwinder.Unwind();
EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
+ EXPECT_FALSE(unwinder.elf_from_memory_not_file());
ASSERT_EQ(2U, unwinder.NumFrames());
@@ -569,6 +597,7 @@
Unwinder unwinder(64, maps_.get(), ®s_, process_memory_);
unwinder.Unwind();
EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
+ EXPECT_FALSE(unwinder.elf_from_memory_not_file());
ASSERT_EQ(1U, unwinder.NumFrames());
}
@@ -588,6 +617,7 @@
Unwinder unwinder(64, maps_.get(), ®s_, process_memory_);
unwinder.Unwind();
EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
+ EXPECT_FALSE(unwinder.elf_from_memory_not_file());
ASSERT_EQ(1U, unwinder.NumFrames());
}
@@ -602,6 +632,7 @@
Unwinder unwinder(64, maps_.get(), ®s_, process_memory_);
unwinder.Unwind();
EXPECT_EQ(ERROR_INVALID_MAP, unwinder.LastErrorCode());
+ EXPECT_FALSE(unwinder.elf_from_memory_not_file());
ASSERT_EQ(1U, unwinder.NumFrames());
@@ -638,6 +669,7 @@
Unwinder unwinder(64, maps_.get(), ®s_, process_memory_);
unwinder.Unwind();
EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
+ EXPECT_FALSE(unwinder.elf_from_memory_not_file());
ASSERT_EQ(3U, unwinder.NumFrames());
@@ -703,6 +735,7 @@
Unwinder unwinder(64, maps_.get(), ®s_, process_memory_);
unwinder.Unwind();
EXPECT_EQ(ERROR_INVALID_MAP, unwinder.LastErrorCode());
+ EXPECT_FALSE(unwinder.elf_from_memory_not_file());
ASSERT_EQ(2U, unwinder.NumFrames());
@@ -752,6 +785,7 @@
Unwinder unwinder(64, maps_.get(), ®s_, process_memory_);
unwinder.Unwind();
EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
+ EXPECT_FALSE(unwinder.elf_from_memory_not_file());
ASSERT_EQ(2U, unwinder.NumFrames());
@@ -799,6 +833,7 @@
std::vector<std::string> skip_names{"libanother.so"};
unwinder.Unwind(&skip_names);
EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
+ EXPECT_FALSE(unwinder.elf_from_memory_not_file());
ASSERT_EQ(0U, unwinder.NumFrames());
}
@@ -821,6 +856,7 @@
std::vector<std::string> suffixes{"oat"};
unwinder.Unwind(nullptr, &suffixes);
EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
+ EXPECT_FALSE(unwinder.elf_from_memory_not_file());
ASSERT_EQ(2U, unwinder.NumFrames());
// Make sure the elf was not initialized.
@@ -879,6 +915,7 @@
Unwinder unwinder(64, maps_.get(), ®s_, process_memory_);
unwinder.Unwind();
EXPECT_EQ(ERROR_REPEATED_FRAME, unwinder.LastErrorCode());
+ EXPECT_FALSE(unwinder.elf_from_memory_not_file());
ASSERT_EQ(3U, unwinder.NumFrames());
@@ -937,6 +974,7 @@
Unwinder unwinder(64, maps_.get(), ®s_, process_memory_);
unwinder.Unwind();
EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
+ EXPECT_FALSE(unwinder.elf_from_memory_not_file());
ASSERT_EQ(2U, unwinder.NumFrames());
@@ -980,6 +1018,7 @@
Unwinder unwinder(64, maps_.get(), ®s_, process_memory_);
unwinder.Unwind();
EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
+ EXPECT_FALSE(unwinder.elf_from_memory_not_file());
ASSERT_EQ(2U, unwinder.NumFrames());
@@ -1026,6 +1065,7 @@
Unwinder unwinder(64, maps_.get(), ®s_, process_memory_);
unwinder.Unwind();
EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
+ EXPECT_FALSE(unwinder.elf_from_memory_not_file());
ASSERT_EQ(3U, unwinder.NumFrames());
@@ -1084,6 +1124,7 @@
Unwinder unwinder(1, maps_.get(), ®s_, process_memory_);
unwinder.Unwind();
EXPECT_EQ(ERROR_MAX_FRAMES_EXCEEDED, unwinder.LastErrorCode());
+ EXPECT_FALSE(unwinder.elf_from_memory_not_file());
ASSERT_EQ(1U, unwinder.NumFrames());
@@ -1103,6 +1144,96 @@
EXPECT_EQ(PROT_READ | PROT_WRITE | PROT_EXEC, frame->map_flags);
}
+TEST_F(UnwinderTest, elf_from_memory_not_file) {
+ ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
+
+ regs_.set_pc(0xc0050);
+ regs_.set_sp(0x10000);
+ ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
+
+ Unwinder unwinder(64, maps_.get(), ®s_, process_memory_);
+ unwinder.Unwind();
+ EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
+ EXPECT_TRUE(unwinder.elf_from_memory_not_file());
+
+ ASSERT_EQ(1U, unwinder.NumFrames());
+
+ auto* frame = &unwinder.frames()[0];
+ EXPECT_EQ(0U, frame->num);
+ EXPECT_EQ(0x50U, frame->rel_pc);
+ EXPECT_EQ(0xc0050U, frame->pc);
+ EXPECT_EQ(0x10000U, frame->sp);
+ EXPECT_EQ("Frame0", frame->function_name);
+ EXPECT_EQ(0U, frame->function_offset);
+ EXPECT_EQ("/fake/unreadable.so", frame->map_name);
+ EXPECT_EQ(0U, frame->map_elf_start_offset);
+ EXPECT_EQ(0U, frame->map_exact_offset);
+ EXPECT_EQ(0xc0000U, frame->map_start);
+ EXPECT_EQ(0xc1000U, frame->map_end);
+ EXPECT_EQ(0U, frame->map_load_bias);
+ EXPECT_EQ(PROT_READ | PROT_WRITE | PROT_EXEC, frame->map_flags);
+}
+
+TEST_F(UnwinderTest, elf_from_memory_but_no_valid_file_with_bracket) {
+ ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
+
+ regs_.set_pc(0xc1050);
+ regs_.set_sp(0x10000);
+ ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
+
+ Unwinder unwinder(64, maps_.get(), ®s_, process_memory_);
+ unwinder.Unwind();
+ EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
+ EXPECT_FALSE(unwinder.elf_from_memory_not_file());
+
+ ASSERT_EQ(1U, unwinder.NumFrames());
+
+ auto* frame = &unwinder.frames()[0];
+ EXPECT_EQ(0U, frame->num);
+ EXPECT_EQ(0x50U, frame->rel_pc);
+ EXPECT_EQ(0xc1050U, frame->pc);
+ EXPECT_EQ(0x10000U, frame->sp);
+ EXPECT_EQ("Frame0", frame->function_name);
+ EXPECT_EQ(0U, frame->function_offset);
+ EXPECT_EQ("[vdso]", frame->map_name);
+ EXPECT_EQ(0U, frame->map_elf_start_offset);
+ EXPECT_EQ(0U, frame->map_exact_offset);
+ EXPECT_EQ(0xc1000U, frame->map_start);
+ EXPECT_EQ(0xc2000U, frame->map_end);
+ EXPECT_EQ(0U, frame->map_load_bias);
+ EXPECT_EQ(PROT_READ | PROT_WRITE | PROT_EXEC, frame->map_flags);
+}
+
+TEST_F(UnwinderTest, elf_from_memory_but_empty_filename) {
+ ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
+
+ regs_.set_pc(0xc2050);
+ regs_.set_sp(0x10000);
+ ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
+
+ Unwinder unwinder(64, maps_.get(), ®s_, process_memory_);
+ unwinder.Unwind();
+ EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
+ EXPECT_FALSE(unwinder.elf_from_memory_not_file());
+
+ ASSERT_EQ(1U, unwinder.NumFrames());
+
+ auto* frame = &unwinder.frames()[0];
+ EXPECT_EQ(0U, frame->num);
+ EXPECT_EQ(0x50U, frame->rel_pc);
+ EXPECT_EQ(0xc2050U, frame->pc);
+ EXPECT_EQ(0x10000U, frame->sp);
+ EXPECT_EQ("Frame0", frame->function_name);
+ EXPECT_EQ(0U, frame->function_offset);
+ EXPECT_EQ("", frame->map_name);
+ EXPECT_EQ(0U, frame->map_elf_start_offset);
+ EXPECT_EQ(0U, frame->map_exact_offset);
+ EXPECT_EQ(0xc2000U, frame->map_start);
+ EXPECT_EQ(0xc3000U, frame->map_end);
+ EXPECT_EQ(0U, frame->map_load_bias);
+ EXPECT_EQ(PROT_READ | PROT_WRITE | PROT_EXEC, frame->map_flags);
+}
+
// Verify format frame code.
TEST_F(UnwinderTest, format_frame) {
RegsFake regs_arm(10);
diff --git a/libziparchive/Android.bp b/libziparchive/Android.bp
index bc1543b..858c0bb 100644
--- a/libziparchive/Android.bp
+++ b/libziparchive/Android.bp
@@ -26,6 +26,8 @@
// Incorrectly warns when C++11 empty brace {} initializer is used.
// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61489
"-Wno-missing-field-initializers",
+ "-Wconversion",
+ "-Wno-sign-conversion",
],
// Enable -Wold-style-cast only for non-Windows targets. _islower_l,
diff --git a/libziparchive/entry_name_utils-inl.h b/libziparchive/entry_name_utils-inl.h
index 1714586..10311b5 100644
--- a/libziparchive/entry_name_utils-inl.h
+++ b/libziparchive/entry_name_utils-inl.h
@@ -20,9 +20,15 @@
#include <stddef.h>
#include <stdint.h>
+#include <limits>
+
// Check if |length| bytes at |entry_name| constitute a valid entry name.
-// Entry names must be valid UTF-8 and must not contain '0'.
+// Entry names must be valid UTF-8 and must not contain '0'. They also must
+// fit into the central directory record.
inline bool IsValidEntryName(const uint8_t* entry_name, const size_t length) {
+ if (length > std::numeric_limits<uint16_t>::max()) {
+ return false;
+ }
for (size_t i = 0; i < length; ++i) {
const uint8_t byte = entry_name[i];
if (byte == 0) {
@@ -35,7 +41,8 @@
return false;
} else {
// 2-5 byte sequences.
- for (uint8_t first = (byte & 0x7f) << 1; first & 0x80; first = (first & 0x7f) << 1) {
+ for (uint8_t first = static_cast<uint8_t>((byte & 0x7f) << 1); first & 0x80;
+ first = static_cast<uint8_t>((first & 0x7f) << 1)) {
++i;
// Missing continuation byte..
diff --git a/libziparchive/include/ziparchive/zip_writer.h b/libziparchive/include/ziparchive/zip_writer.h
index f6c8427..bd44fdb 100644
--- a/libziparchive/include/ziparchive/zip_writer.h
+++ b/libziparchive/include/ziparchive/zip_writer.h
@@ -76,7 +76,7 @@
uint32_t uncompressed_size;
uint16_t last_mod_time;
uint16_t last_mod_date;
- uint32_t padding_length;
+ uint16_t padding_length;
off64_t local_file_header_offset;
};
@@ -161,8 +161,8 @@
int32_t HandleError(int32_t error_code);
int32_t PrepareDeflate();
- int32_t StoreBytes(FileEntry* file, const void* data, size_t len);
- int32_t CompressBytes(FileEntry* file, const void* data, size_t len);
+ int32_t StoreBytes(FileEntry* file, const void* data, uint32_t len);
+ int32_t CompressBytes(FileEntry* file, const void* data, uint32_t len);
int32_t FlushCompressedBytes(FileEntry* file);
enum class State {
diff --git a/libziparchive/unzip.cpp b/libziparchive/unzip.cpp
index cc059d8..c6def73 100644
--- a/libziparchive/unzip.cpp
+++ b/libziparchive/unzip.cpp
@@ -85,7 +85,7 @@
static int CompressionRatio(int64_t uncompressed, int64_t compressed) {
if (uncompressed == 0) return 0;
- return (100LL * (uncompressed - compressed)) / uncompressed;
+ return static_cast<int>((100LL * (uncompressed - compressed)) / uncompressed);
}
static void MaybeShowHeader() {
diff --git a/libziparchive/zip_archive.cc b/libziparchive/zip_archive.cc
index e1ec47a..596786a 100644
--- a/libziparchive/zip_archive.cc
+++ b/libziparchive/zip_archive.cc
@@ -146,7 +146,7 @@
/*
* Add a new entry to the hash table.
*/
-static int32_t AddToHash(ZipStringOffset* hash_table, const uint64_t hash_table_size,
+static int32_t AddToHash(ZipStringOffset* hash_table, const uint32_t hash_table_size,
const ZipString& name, const uint8_t* start) {
const uint64_t hash = ComputeHash(name);
uint32_t ent = hash & (hash_table_size - 1);
@@ -214,7 +214,7 @@
}
static int32_t MapCentralDirectory0(const char* debug_file_name, ZipArchive* archive,
- off64_t file_length, off64_t read_amount,
+ off64_t file_length, uint32_t read_amount,
uint8_t* scan_buffer) {
const off64_t search_start = file_length - read_amount;
@@ -230,7 +230,8 @@
* doing an initial minimal read; if we don't find it, retry with a
* second read as above.)
*/
- int i = read_amount - sizeof(EocdRecord);
+ CHECK_LE(read_amount, std::numeric_limits<int32_t>::max());
+ int32_t i = read_amount - sizeof(EocdRecord);
for (; i >= 0; i--) {
if (scan_buffer[i] == 0x50) {
uint32_t* sig_addr = reinterpret_cast<uint32_t*>(&scan_buffer[i]);
@@ -333,9 +334,9 @@
*
* We start by pulling in the last part of the file.
*/
- off64_t read_amount = kMaxEOCDSearch;
+ uint32_t read_amount = kMaxEOCDSearch;
if (file_length < read_amount) {
- read_amount = file_length;
+ read_amount = static_cast<uint32_t>(file_length);
}
std::vector<uint8_t> scan_buffer(read_amount);
@@ -532,7 +533,7 @@
return 0;
}
-static int32_t FindEntry(const ZipArchive* archive, const int ent, ZipEntry* data) {
+static int32_t FindEntry(const ZipArchive* archive, const int32_t ent, ZipEntry* data) {
const uint16_t nameLen = archive->hash_table[ent].name_length;
// Recover the start of the central directory entry from the filename
@@ -751,9 +752,10 @@
archive->central_directory.GetBasePtr());
if (ent < 0) {
ALOGV("Zip: Could not find entry %.*s", entryName.name_length, entryName.name);
- return ent;
+ return static_cast<int32_t>(ent); // kEntryNotFound is safe to truncate.
}
- return FindEntry(archive, ent, data);
+ // We know there are at most hast_table_size entries, safe to truncate.
+ return FindEntry(archive, static_cast<uint32_t>(ent), data);
}
int32_t Next(void* cookie, ZipEntry* data, ZipString* name) {
@@ -836,7 +838,6 @@
return FileWriter{};
}
- int result = 0;
#if defined(__linux__)
if (declared_length > 0) {
// Make sure we have enough space on the volume to extract the compressed
@@ -848,7 +849,7 @@
// EOPNOTSUPP error when issued in other filesystems.
// Hence, check for the return error code before concluding that the
// disk does not have enough space.
- result = TEMP_FAILURE_RETRY(fallocate(fd, 0, current_offset, declared_length));
+ long result = TEMP_FAILURE_RETRY(fallocate(fd, 0, current_offset, declared_length));
if (result == -1 && errno == ENOSPC) {
ALOGW("Zip: unable to allocate %" PRId64 " bytes at offset %" PRId64 ": %s",
static_cast<int64_t>(declared_length), static_cast<int64_t>(current_offset),
@@ -866,7 +867,7 @@
// Block device doesn't support ftruncate(2).
if (!S_ISBLK(sb.st_mode)) {
- result = TEMP_FAILURE_RETRY(ftruncate(fd, declared_length + current_offset));
+ long 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));
@@ -985,16 +986,16 @@
std::unique_ptr<z_stream, decltype(zstream_deleter)> zstream_guard(&zstream, zstream_deleter);
const bool compute_crc = (crc_out != nullptr);
- uint64_t crc = 0;
+ uLong crc = 0;
uint32_t remaining_bytes = compressed_length;
do {
/* read as much as we can */
if (zstream.avail_in == 0) {
- const size_t read_size = (remaining_bytes > kBufSize) ? kBufSize : remaining_bytes;
+ const uint32_t read_size = (remaining_bytes > kBufSize) ? kBufSize : remaining_bytes;
const uint32_t offset = (compressed_length - remaining_bytes);
// Make sure to read at offset to ensure concurrent access to the fd.
if (!reader.ReadAtOffset(read_buf.data(), read_size, offset)) {
- ALOGW("Zip: inflate read failed, getSize = %zu: %s", read_size, strerror(errno));
+ ALOGW("Zip: inflate read failed, getSize = %u: %s", read_size, strerror(errno));
return kIoError;
}
@@ -1018,7 +1019,8 @@
if (!writer->Append(&write_buf[0], write_size)) {
return kIoError;
} else if (compute_crc) {
- crc = crc32(crc, &write_buf[0], write_size);
+ DCHECK_LE(write_size, kBufSize);
+ crc = crc32(crc, &write_buf[0], static_cast<uint32_t>(write_size));
}
zstream.next_out = &write_buf[0];
@@ -1063,17 +1065,17 @@
const uint32_t length = entry->uncompressed_length;
uint32_t count = 0;
- uint64_t crc = 0;
+ uLong crc = 0;
while (count < length) {
uint32_t remaining = length - count;
off64_t offset = entry->offset + count;
// Safe conversion because kBufSize is narrow enough for a 32 bit signed value.
- const size_t block_size = (remaining > kBufSize) ? kBufSize : remaining;
+ const uint32_t block_size = (remaining > kBufSize) ? kBufSize : remaining;
// Make sure to read at offset to ensure concurrent access to the fd.
if (!mapped_zip.ReadAtOffset(buf.data(), block_size, offset)) {
- ALOGW("CopyFileToFile: copy read failed, block_size = %zu, offset = %" PRId64 ": %s",
+ ALOGW("CopyFileToFile: copy read failed, block_size = %u, offset = %" PRId64 ": %s",
block_size, static_cast<int64_t>(offset), strerror(errno));
return kIoError;
}
diff --git a/libziparchive/zip_archive_stream_entry.cc b/libziparchive/zip_archive_stream_entry.cc
index 9ec89b1..1ec95b6 100644
--- a/libziparchive/zip_archive_stream_entry.cc
+++ b/libziparchive/zip_archive_stream_entry.cc
@@ -27,6 +27,7 @@
#include <vector>
#include <android-base/file.h>
+#include <android-base/logging.h>
#include <log/log.h>
#include <ziparchive/zip_archive.h>
@@ -77,6 +78,12 @@
}
const std::vector<uint8_t>* ZipArchiveStreamEntryUncompressed::Read() {
+ // Simple sanity check. The vector should *only* be handled by this code. A caller
+ // should not const-cast and modify the capacity. This may invalidate next_out.
+ //
+ // Note: it would be better to store the results of data() across Read calls.
+ CHECK_EQ(data_.capacity(), kBufSize);
+
if (length_ == 0) {
return nullptr;
}
@@ -97,7 +104,8 @@
if (bytes < data_.size()) {
data_.resize(bytes);
}
- computed_crc32_ = crc32(computed_crc32_, data_.data(), data_.size());
+ computed_crc32_ = static_cast<uint32_t>(
+ crc32(computed_crc32_, data_.data(), static_cast<uint32_t>(data_.size())));
length_ -= bytes;
offset_ += bytes;
return &data_;
@@ -192,9 +200,15 @@
}
const std::vector<uint8_t>* ZipArchiveStreamEntryCompressed::Read() {
+ // Simple sanity check. The vector should *only* be handled by this code. A caller
+ // should not const-cast and modify the capacity. This may invalidate next_out.
+ //
+ // Note: it would be better to store the results of data() across Read calls.
+ CHECK_EQ(out_.capacity(), kBufSize);
+
if (z_stream_.avail_out == 0) {
z_stream_.next_out = out_.data();
- z_stream_.avail_out = out_.size();
+ z_stream_.avail_out = static_cast<uint32_t>(out_.size());
;
}
@@ -203,7 +217,9 @@
if (compressed_length_ == 0) {
return nullptr;
}
- size_t bytes = (compressed_length_ > in_.size()) ? in_.size() : compressed_length_;
+ DCHECK_LE(in_.size(), std::numeric_limits<uint32_t>::max()); // Should be buf size = 64k.
+ uint32_t bytes = (compressed_length_ > in_.size()) ? static_cast<uint32_t>(in_.size())
+ : compressed_length_;
ZipArchive* archive = reinterpret_cast<ZipArchive*>(handle_);
errno = 0;
if (!archive->mapped_zip.ReadAtOffset(in_.data(), bytes, offset_)) {
@@ -230,14 +246,16 @@
if (z_stream_.avail_out == 0) {
uncompressed_length_ -= out_.size();
- computed_crc32_ = crc32(computed_crc32_, out_.data(), out_.size());
+ computed_crc32_ = static_cast<uint32_t>(
+ crc32(computed_crc32_, out_.data(), static_cast<uint32_t>(out_.size())));
return &out_;
}
if (zerr == Z_STREAM_END) {
if (z_stream_.avail_out != 0) {
// Resize the vector down to the actual size of the data.
out_.resize(out_.size() - z_stream_.avail_out);
- computed_crc32_ = crc32(computed_crc32_, out_.data(), out_.size());
+ computed_crc32_ = static_cast<uint32_t>(
+ crc32(computed_crc32_, out_.data(), static_cast<uint32_t>(out_.size())));
uncompressed_length_ -= out_.size();
return &out_;
}
diff --git a/libziparchive/zip_archive_test.cc b/libziparchive/zip_archive_test.cc
index cea42d4..e471d5e 100644
--- a/libziparchive/zip_archive_test.cc
+++ b/libziparchive/zip_archive_test.cc
@@ -27,6 +27,7 @@
#include <vector>
#include <android-base/file.h>
+#include <android-base/logging.h>
#include <android-base/mapped_file.h>
#include <android-base/unique_fd.h>
#include <gtest/gtest.h>
@@ -65,7 +66,8 @@
static void SetZipString(ZipString* zip_str, const std::string& str) {
zip_str->name = reinterpret_cast<const uint8_t*>(str.c_str());
- zip_str->name_length = str.size();
+ CHECK_LE(str.size(), std::numeric_limits<uint16_t>::max());
+ zip_str->name_length = static_cast<uint16_t>(str.size());
}
TEST(ziparchive, Open) {
@@ -332,7 +334,7 @@
// Extract the entry to memory.
std::vector<uint8_t> buffer(kAbUncompressedSize);
- ASSERT_EQ(0, ExtractToMemory(handle, &entry, &buffer[0], buffer.size()));
+ ASSERT_EQ(0, ExtractToMemory(handle, &entry, &buffer[0], static_cast<uint32_t>(buffer.size())));
// Extract the entry to a file.
TemporaryFile tmp_output_file;
@@ -415,7 +417,8 @@
ASSERT_EQ(0, fstat(fd, &sb));
// Memory map the file first and open the archive from the memory region.
- auto file_map{android::base::MappedFile::FromFd(fd, 0, sb.st_size, PROT_READ)};
+ auto file_map{
+ android::base::MappedFile::FromFd(fd, 0, static_cast<size_t>(sb.st_size), PROT_READ)};
ZipArchiveHandle handle;
ASSERT_EQ(0,
OpenArchiveFromMemory(file_map->data(), file_map->size(), zip_path.c_str(), &handle));
@@ -488,7 +491,8 @@
std::vector<uint8_t> cmp_data(entry.uncompressed_length);
ASSERT_EQ(entry.uncompressed_length, read_data.size());
- ASSERT_EQ(0, ExtractToMemory(handle, &entry, cmp_data.data(), cmp_data.size()));
+ ASSERT_EQ(
+ 0, ExtractToMemory(handle, &entry, cmp_data.data(), static_cast<uint32_t>(cmp_data.size())));
ASSERT_TRUE(memcmp(read_data.data(), cmp_data.data(), read_data.size()) == 0);
CloseArchive(handle);
@@ -737,8 +741,8 @@
};
TEST(ziparchive, Inflate) {
- const uint32_t compressed_length = kATxtContentsCompressed.size();
- const uint32_t uncompressed_length = kATxtContents.size();
+ const uint32_t compressed_length = static_cast<uint32_t>(kATxtContentsCompressed.size());
+ const uint32_t uncompressed_length = static_cast<uint32_t>(kATxtContents.size());
const VectorReader reader(kATxtContentsCompressed);
{
diff --git a/libziparchive/zip_writer.cc b/libziparchive/zip_writer.cc
index 0df0fa5..ae9d145 100644
--- a/libziparchive/zip_writer.cc
+++ b/libziparchive/zip_writer.cc
@@ -169,8 +169,8 @@
year = 80;
}
- *out_date = (year - 80) << 9 | (ptm->tm_mon + 1) << 5 | ptm->tm_mday;
- *out_time = ptm->tm_hour << 11 | ptm->tm_min << 5 | ptm->tm_sec >> 1;
+ *out_date = static_cast<uint16_t>((year - 80) << 9 | (ptm->tm_mon + 1) << 5 | ptm->tm_mday);
+ *out_time = static_cast<uint16_t>(ptm->tm_hour << 11 | ptm->tm_min << 5 | ptm->tm_sec >> 1);
}
static void CopyFromFileEntry(const ZipWriter::FileEntry& src, bool use_data_descriptor,
@@ -193,7 +193,8 @@
dst->compression_method = src.compression_method;
dst->last_mod_time = src.last_mod_time;
dst->last_mod_date = src.last_mod_date;
- dst->file_name_length = src.path.size();
+ DCHECK_LE(src.path.size(), std::numeric_limits<uint16_t>::max());
+ dst->file_name_length = static_cast<uint16_t>(src.path.size());
dst->extra_field_length = src.padding_length;
}
@@ -203,6 +204,11 @@
return kInvalidState;
}
+ // Can only have 16535 entries because of zip records.
+ if (files_.size() == std::numeric_limits<uint16_t>::max()) {
+ return HandleError(kIoError);
+ }
+
if (flags & kAlign32) {
return kInvalidAlign32Flag;
}
@@ -210,10 +216,17 @@
if (powerof2(alignment) == 0) {
return kInvalidAlignment;
}
+ if (alignment > std::numeric_limits<uint16_t>::max()) {
+ return kInvalidAlignment;
+ }
FileEntry file_entry = {};
file_entry.local_file_header_offset = current_offset_;
file_entry.path = path;
+ // No support for larger than 4GB files.
+ if (file_entry.local_file_header_offset > std::numeric_limits<uint32_t>::max()) {
+ return HandleError(kIoError);
+ }
if (!IsValidEntryName(reinterpret_cast<const uint8_t*>(file_entry.path.data()),
file_entry.path.size())) {
@@ -237,7 +250,7 @@
std::vector<char> zero_padding;
if (alignment != 0 && (offset & (alignment - 1))) {
// Pad the extra field so the data will be aligned.
- uint16_t padding = alignment - (offset % alignment);
+ uint16_t padding = static_cast<uint16_t>(alignment - (offset % alignment));
file_entry.padding_length = padding;
offset += padding;
zero_padding.resize(padding, 0);
@@ -314,7 +327,8 @@
}
z_stream_->next_out = buffer_.data();
- z_stream_->avail_out = buffer_.size();
+ DCHECK_EQ(buffer_.size(), kBufSize);
+ z_stream_->avail_out = static_cast<uint32_t>(buffer_.size());
return kNoError;
}
@@ -322,25 +336,31 @@
if (state_ != State::kWritingEntry) {
return HandleError(kInvalidState);
}
+ // Need to be able to mark down data correctly.
+ if (len + static_cast<uint64_t>(current_file_entry_.uncompressed_size) >
+ std::numeric_limits<uint32_t>::max()) {
+ return HandleError(kIoError);
+ }
+ uint32_t len32 = static_cast<uint32_t>(len);
int32_t result = kNoError;
if (current_file_entry_.compression_method & kCompressDeflated) {
- result = CompressBytes(¤t_file_entry_, data, len);
+ result = CompressBytes(¤t_file_entry_, data, len32);
} else {
- result = StoreBytes(¤t_file_entry_, data, len);
+ result = StoreBytes(¤t_file_entry_, data, len32);
}
if (result != kNoError) {
return result;
}
- current_file_entry_.crc32 =
- crc32(current_file_entry_.crc32, reinterpret_cast<const Bytef*>(data), len);
- current_file_entry_.uncompressed_size += len;
+ current_file_entry_.crc32 = static_cast<uint32_t>(
+ crc32(current_file_entry_.crc32, reinterpret_cast<const Bytef*>(data), len32));
+ current_file_entry_.uncompressed_size += len32;
return kNoError;
}
-int32_t ZipWriter::StoreBytes(FileEntry* file, const void* data, size_t len) {
+int32_t ZipWriter::StoreBytes(FileEntry* file, const void* data, uint32_t len) {
CHECK(state_ == State::kWritingEntry);
if (fwrite(data, 1, len, file_) != len) {
@@ -351,7 +371,7 @@
return kNoError;
}
-int32_t ZipWriter::CompressBytes(FileEntry* file, const void* data, size_t len) {
+int32_t ZipWriter::CompressBytes(FileEntry* file, const void* data, uint32_t len) {
CHECK(state_ == State::kWritingEntry);
CHECK(z_stream_);
CHECK(z_stream_->next_out != nullptr);
@@ -379,7 +399,8 @@
// Reset the output buffer for the next input.
z_stream_->next_out = buffer_.data();
- z_stream_->avail_out = buffer_.size();
+ DCHECK_EQ(buffer_.size(), kBufSize);
+ z_stream_->avail_out = static_cast<uint32_t>(buffer_.size());
}
}
return kNoError;
@@ -404,7 +425,8 @@
current_offset_ += write_bytes;
z_stream_->next_out = buffer_.data();
- z_stream_->avail_out = buffer_.size();
+ DCHECK_EQ(buffer_.size(), kBufSize);
+ z_stream_->avail_out = static_cast<uint32_t>(buffer_.size());
}
if (zerr != Z_STREAM_END) {
return HandleError(kZlibError);
@@ -491,7 +513,11 @@
cdr.crc32 = file.crc32;
cdr.compressed_size = file.compressed_size;
cdr.uncompressed_size = file.uncompressed_size;
- cdr.file_name_length = file.path.size();
+ // Checked in IsValidEntryName.
+ DCHECK_LE(file.path.size(), std::numeric_limits<uint16_t>::max());
+ cdr.file_name_length = static_cast<uint16_t>(file.path.size());
+ // Checked in StartAlignedEntryWithTime.
+ DCHECK_LE(file.local_file_header_offset, std::numeric_limits<uint32_t>::max());
cdr.local_file_header_offset = static_cast<uint32_t>(file.local_file_header_offset);
if (fwrite(&cdr, sizeof(cdr), 1, file_) != 1) {
return HandleError(kIoError);
@@ -508,10 +534,15 @@
er.eocd_signature = EocdRecord::kSignature;
er.disk_num = 0;
er.cd_start_disk = 0;
- er.num_records_on_disk = files_.size();
- er.num_records = files_.size();
- er.cd_size = current_offset_ - startOfCdr;
- er.cd_start_offset = startOfCdr;
+ // Checked when adding entries.
+ DCHECK_LE(files_.size(), std::numeric_limits<uint16_t>::max());
+ er.num_records_on_disk = static_cast<uint16_t>(files_.size());
+ er.num_records = static_cast<uint16_t>(files_.size());
+ if (current_offset_ > std::numeric_limits<uint32_t>::max()) {
+ return HandleError(kIoError);
+ }
+ er.cd_size = static_cast<uint32_t>(current_offset_ - startOfCdr);
+ er.cd_start_offset = static_cast<uint32_t>(startOfCdr);
if (fwrite(&er, sizeof(er), 1, file_) != 1) {
return HandleError(kIoError);
diff --git a/libziparchive/zip_writer_test.cc b/libziparchive/zip_writer_test.cc
index 7322afb..63adbbc 100644
--- a/libziparchive/zip_writer_test.cc
+++ b/libziparchive/zip_writer_test.cc
@@ -279,7 +279,8 @@
std::vector<uint8_t> decompress(kBufSize);
memset(decompress.data(), 0, kBufSize);
- ASSERT_EQ(0, ExtractToMemory(handle, &data, decompress.data(), decompress.size()));
+ ASSERT_EQ(0, ExtractToMemory(handle, &data, decompress.data(),
+ static_cast<uint32_t>(decompress.size())));
EXPECT_EQ(0, memcmp(decompress.data(), buffer.data(), kBufSize))
<< "Input buffer and output buffer are different.";
@@ -391,7 +392,7 @@
actual.resize(expected.size());
uint8_t* buffer = reinterpret_cast<uint8_t*>(&*actual.begin());
- if (ExtractToMemory(handle, zip_entry, buffer, actual.size()) != 0) {
+ if (ExtractToMemory(handle, zip_entry, buffer, static_cast<uint32_t>(actual.size())) != 0) {
return ::testing::AssertionFailure() << "failed to extract entry";
}
diff --git a/rootdir/Android.mk b/rootdir/Android.mk
index 462ae8b..0044534 100644
--- a/rootdir/Android.mk
+++ b/rootdir/Android.mk
@@ -97,7 +97,7 @@
#
# create some directories (some are mount points) and symlinks
LOCAL_POST_INSTALL_CMD := mkdir -p $(addprefix $(TARGET_ROOT_OUT)/, \
- sbin dev proc sys system data odm oem acct config storage mnt apex $(BOARD_ROOT_EXTRA_FOLDERS)); \
+ dev proc sys system data odm oem acct config storage mnt apex $(BOARD_ROOT_EXTRA_FOLDERS)); \
ln -sf /system/bin $(TARGET_ROOT_OUT)/bin; \
ln -sf /system/etc $(TARGET_ROOT_OUT)/etc; \
ln -sf /data/user_de/0/com.android.shell/files/bugreports $(TARGET_ROOT_OUT)/bugreports; \
diff --git a/rootdir/etc/ld.config.legacy.txt b/rootdir/etc/ld.config.legacy.txt
index 8792671..e081bdf 100644
--- a/rootdir/etc/ld.config.legacy.txt
+++ b/rootdir/etc/ld.config.legacy.txt
@@ -99,7 +99,6 @@
namespace.media.permitted.paths = /apex/com.android.media/${LIB}/extractors
namespace.media.links = default
-namespace.media.link.default.shared_libs = libandroid.so
namespace.media.link.default.shared_libs += libbinder_ndk.so
namespace.media.link.default.shared_libs += libc.so
namespace.media.link.default.shared_libs += libcgrouprc.so
diff --git a/rootdir/etc/ld.config.txt b/rootdir/etc/ld.config.txt
index b486411..3f9882a 100644
--- a/rootdir/etc/ld.config.txt
+++ b/rootdir/etc/ld.config.txt
@@ -179,7 +179,6 @@
namespace.media.links = default
namespace.media.link.default.shared_libs = %LLNDK_LIBRARIES%
-namespace.media.link.default.shared_libs += libandroid.so
namespace.media.link.default.shared_libs += libbinder_ndk.so
namespace.media.link.default.shared_libs += libmediametrics.so
namespace.media.link.default.shared_libs += %SANITIZER_RUNTIME_LIBRARIES%
@@ -622,7 +621,6 @@
namespace.media.links = default
namespace.media.link.default.shared_libs = %LLNDK_LIBRARIES%
-namespace.media.link.default.shared_libs += libandroid.so
namespace.media.link.default.shared_libs += libbinder_ndk.so
namespace.media.link.default.shared_libs += libmediametrics.so
namespace.media.link.default.shared_libs += %SANITIZER_RUNTIME_LIBRARIES%
diff --git a/rootdir/etc/ld.config.vndk_lite.txt b/rootdir/etc/ld.config.vndk_lite.txt
index 12007dc..6d89886 100644
--- a/rootdir/etc/ld.config.vndk_lite.txt
+++ b/rootdir/etc/ld.config.vndk_lite.txt
@@ -121,7 +121,6 @@
namespace.media.links = default
namespace.media.link.default.shared_libs = %LLNDK_LIBRARIES%
-namespace.media.link.default.shared_libs += libandroid.so
namespace.media.link.default.shared_libs += libbinder_ndk.so
namespace.media.link.default.shared_libs += libmediametrics.so
namespace.media.link.default.shared_libs += %SANITIZER_RUNTIME_LIBRARIES%
@@ -445,7 +444,6 @@
namespace.media.links = default
namespace.media.link.default.shared_libs = %LLNDK_LIBRARIES%
-namespace.media.link.default.shared_libs += libandroid.so
namespace.media.link.default.shared_libs += libbinder_ndk.so
namespace.media.link.default.shared_libs += libmediametrics.so
namespace.media.link.default.shared_libs += %SANITIZER_RUNTIME_LIBRARIES%
diff --git a/rootdir/init.rc b/rootdir/init.rc
index e94b8e2..9bb624a 100644
--- a/rootdir/init.rc
+++ b/rootdir/init.rc
@@ -13,9 +13,6 @@
# Cgroups are mounted right before early-init using list from /etc/cgroups.json
on early-init
- # Set init and its forked children's oom_adj.
- write /proc/1/oom_score_adj -1000
-
# Disable sysrq from keyboard
write /proc/sys/kernel/sysrq 0