Merge "liblp: Add an abstraction layer for opening partitions."
diff --git a/TEST_MAPPING b/TEST_MAPPING
new file mode 100644
index 0000000..c47230f
--- /dev/null
+++ b/TEST_MAPPING
@@ -0,0 +1,7 @@
+{
+ "presubmit": [
+ {
+ "name": "adbd_test"
+ }
+ ]
+}
diff --git a/adb/adb_utils.cpp b/adb/adb_utils.cpp
index ad77064..6960345 100644
--- a/adb/adb_utils.cpp
+++ b/adb/adb_utils.cpp
@@ -293,6 +293,9 @@
struct passwd pwent;
struct passwd* result;
int pwent_max = sysconf(_SC_GETPW_R_SIZE_MAX);
+ if (pwent_max == -1) {
+ pwent_max = 16384;
+ }
std::vector<char> buf(pwent_max);
int rc = getpwuid_r(getuid(), &pwent, buf.data(), buf.size(), &result);
if (rc == 0 && result) {
diff --git a/adb/client/commandline.cpp b/adb/client/commandline.cpp
index 3124852..b5bed28 100644
--- a/adb/client/commandline.cpp
+++ b/adb/client/commandline.cpp
@@ -204,8 +204,8 @@
" sideload OTAPACKAGE sideload the given full OTA package\n"
" root restart adbd with root permissions\n"
" unroot restart adbd without root permissions\n"
- " usb restart adb server listening on USB\n"
- " tcpip PORT restart adb server listening on TCP on PORT\n"
+ " usb restart adbd listening on USB\n"
+ " tcpip PORT restart adbd listening on TCP on PORT\n"
"\n"
"internal debugging:\n"
" start-server ensure that there is a server running\n"
diff --git a/base/Android.bp b/base/Android.bp
index daa820a..741664b 100644
--- a/base/Android.bp
+++ b/base/Android.bp
@@ -47,6 +47,7 @@
"chrono_utils.cpp",
"file.cpp",
"logging.cpp",
+ "mapped_file.cpp",
"parsenetaddress.cpp",
"properties.cpp",
"quick_exit.cpp",
@@ -124,6 +125,7 @@
"file_test.cpp",
"logging_test.cpp",
"macros_test.cpp",
+ "mapped_file_test.cpp",
"parsedouble_test.cpp",
"parseint_test.cpp",
"parsenetaddress_test.cpp",
diff --git a/base/file.cpp b/base/file.cpp
index d6fe753..3834ed4 100644
--- a/base/file.cpp
+++ b/base/file.cpp
@@ -38,7 +38,6 @@
#endif
#if defined(_WIN32)
#include <windows.h>
-#define O_CLOEXEC O_NOINHERIT
#define O_NOFOLLOW 0
#endif
diff --git a/base/include/android-base/file.h b/base/include/android-base/file.h
index 908690b..8f9bf80 100644
--- a/base/include/android-base/file.h
+++ b/base/include/android-base/file.h
@@ -21,11 +21,17 @@
#include <string>
#if !defined(_WIN32) && !defined(O_BINARY)
+/** Windows needs O_BINARY, but Unix never mangles line endings. */
#define O_BINARY 0
#endif
+#if defined(_WIN32) && !defined(O_CLOEXEC)
+/** Windows has O_CLOEXEC but calls it O_NOINHERIT for some reason. */
+#define O_CLOEXEC O_NOINHERIT
+#endif
+
#if defined(__APPLE__)
-/* Mac OS has always had a 64-bit off_t, so it doesn't have off64_t. */
+/** Mac OS has always had a 64-bit off_t, so it doesn't have off64_t. */
typedef off_t off64_t;
#endif
diff --git a/base/include/android-base/macros.h b/base/include/android-base/macros.h
index 1748665..5abf514 100644
--- a/base/include/android-base/macros.h
+++ b/base/include/android-base/macros.h
@@ -75,46 +75,6 @@
#define arraysize(array) (sizeof(ArraySizeHelper(array)))
-// ARRAYSIZE_UNSAFE performs essentially the same calculation as arraysize,
-// but can be used on anonymous types or types defined inside
-// functions. It's less safe than arraysize as it accepts some
-// (although not all) pointers. Therefore, you should use arraysize
-// whenever possible.
-//
-// The expression ARRAYSIZE_UNSAFE(a) is a compile-time constant of type
-// size_t.
-//
-// ARRAYSIZE_UNSAFE catches a few type errors. If you see a compiler error
-//
-// "warning: division by zero in ..."
-//
-// when using ARRAYSIZE_UNSAFE, you are (wrongfully) giving it a pointer.
-// You should only use ARRAYSIZE_UNSAFE on statically allocated arrays.
-//
-// The following comments are on the implementation details, and can
-// be ignored by the users.
-//
-// ARRAYSIZE_UNSAFE(arr) works by inspecting sizeof(arr) (the # of bytes in
-// the array) and sizeof(*(arr)) (the # of bytes in one array
-// element). If the former is divisible by the latter, perhaps arr is
-// indeed an array, in which case the division result is the # of
-// elements in the array. Otherwise, arr cannot possibly be an array,
-// and we generate a compiler error to prevent the code from
-// compiling.
-//
-// Since the size of bool is implementation-defined, we need to cast
-// !(sizeof(a) & sizeof(*(a))) to size_t in order to ensure the final
-// result has type size_t.
-//
-// This macro is not perfect as it wrongfully accepts certain
-// pointers, namely where the pointer size is divisible by the pointee
-// size. Since all our code has to go through a 32-bit compiler,
-// where a pointer is 4 bytes, this means all pointers to a type whose
-// size is 3 or greater than 4 will be (righteously) rejected.
-#define ARRAYSIZE_UNSAFE(a) \
- ((sizeof(a) / sizeof(*(a))) / \
- static_cast<size_t>(!(sizeof(a) % sizeof(*(a)))))
-
#define SIZEOF_MEMBER(t, f) sizeof(std::declval<t>().f)
// Changing this definition will cause you a lot of pain. A majority of
@@ -153,23 +113,23 @@
// case 42:
// ...
//
-// As shown in the example above, the FALLTHROUGH_INTENDED macro should be
-// followed by a semicolon. It is designed to mimic control-flow statements
-// like 'break;', so it can be placed in most places where 'break;' can, but
-// only if there are no statements on the execution path between it and the
-// next switch label.
+// As shown in the example above, the FALLTHROUGH_INTENDED macro should be
+// followed by a semicolon. It is designed to mimic control-flow statements
+// like 'break;', so it can be placed in most places where 'break;' can, but
+// only if there are no statements on the execution path between it and the
+// next switch label.
//
-// When compiled with clang, the FALLTHROUGH_INTENDED macro is expanded to
-// [[clang::fallthrough]] attribute, which is analysed when performing switch
-// labels fall-through diagnostic ('-Wimplicit-fallthrough'). See clang
-// documentation on language extensions for details:
-// http://clang.llvm.org/docs/LanguageExtensions.html#clang__fallthrough
+// When compiled with clang, the FALLTHROUGH_INTENDED macro is expanded to
+// [[clang::fallthrough]] attribute, which is analysed when performing switch
+// labels fall-through diagnostic ('-Wimplicit-fallthrough'). See clang
+// documentation on language extensions for details:
+// http://clang.llvm.org/docs/LanguageExtensions.html#clang__fallthrough
//
-// When used with unsupported compilers, the FALLTHROUGH_INTENDED macro has no
-// effect on diagnostics.
+// When used with unsupported compilers, the FALLTHROUGH_INTENDED macro has no
+// effect on diagnostics.
//
-// In either case this macro has no effect on runtime behavior and performance
-// of code.
+// In either case this macro has no effect on runtime behavior and performance
+// of code.
#ifndef FALLTHROUGH_INTENDED
#define FALLTHROUGH_INTENDED [[clang::fallthrough]] // NOLINT
#endif
diff --git a/base/include/android-base/mapped_file.h b/base/include/android-base/mapped_file.h
new file mode 100644
index 0000000..52d11ed
--- /dev/null
+++ b/base/include/android-base/mapped_file.h
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2018 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.
+ */
+
+#pragma once
+
+#include "android-base/macros.h"
+
+#include <sys/types.h>
+
+#include <memory>
+
+#if defined(_WIN32)
+#include <windows.h>
+#define PROT_READ 1
+#define PROT_WRITE 2
+#else
+#include <sys/mman.h>
+#endif
+
+namespace android {
+namespace base {
+
+/**
+ * A region of a file mapped into memory.
+ */
+class MappedFile {
+ public:
+ /**
+ * Creates a new mapping of the file pointed to by `fd`. Unlike the underlying OS primitives,
+ * `offset` does not need to be page-aligned. If `PROT_WRITE` is set in `prot`, the mapping
+ * will be writable, otherwise it will be read-only. Mappings are always `MAP_SHARED`.
+ */
+ static std::unique_ptr<MappedFile> FromFd(int fd, off64_t offset, size_t length, int prot);
+
+ /**
+ * Removes the mapping.
+ */
+ ~MappedFile();
+
+ char* data() { return base_ + offset_; }
+ size_t size() { return size_; }
+
+ private:
+ DISALLOW_IMPLICIT_CONSTRUCTORS(MappedFile);
+
+ char* base_;
+ size_t size_;
+
+ size_t offset_;
+
+#if defined(_WIN32)
+ MappedFile(char* base, size_t size, size_t offset, HANDLE handle)
+ : base_(base), size_(size), offset_(offset), handle_(handle) {}
+ HANDLE handle_;
+#else
+ MappedFile(char* base, size_t size, size_t offset) : base_(base), size_(size), offset_(offset) {}
+#endif
+};
+
+} // namespace base
+} // namespace android
diff --git a/base/mapped_file.cpp b/base/mapped_file.cpp
new file mode 100644
index 0000000..f7901af
--- /dev/null
+++ b/base/mapped_file.cpp
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2018 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.
+ */
+
+#include "android-base/mapped_file.h"
+
+namespace android {
+namespace base {
+
+static off64_t InitPageSize() {
+#if defined(_WIN32)
+ SYSTEM_INFO si;
+ GetSystemInfo(&si);
+ return si.dwAllocationGranularity;
+#else
+ return sysconf(_SC_PAGE_SIZE);
+#endif
+}
+
+std::unique_ptr<MappedFile> MappedFile::FromFd(int fd, off64_t offset, size_t length, int prot) {
+ static off64_t page_size = InitPageSize();
+ size_t slop = offset % page_size;
+ off64_t file_offset = offset - slop;
+ off64_t file_length = length + slop;
+
+#if defined(_WIN32)
+ HANDLE handle =
+ CreateFileMapping(reinterpret_cast<HANDLE>(_get_osfhandle(fd)), nullptr,
+ (prot & PROT_WRITE) ? PAGE_READWRITE : PAGE_READONLY, 0, 0, nullptr);
+ if (handle == nullptr) return nullptr;
+ void* base = MapViewOfFile(handle, (prot & PROT_WRITE) ? FILE_MAP_ALL_ACCESS : FILE_MAP_READ, 0,
+ file_offset, file_length);
+ if (base == nullptr) {
+ CloseHandle(handle);
+ return nullptr;
+ }
+ return std::unique_ptr<MappedFile>(
+ new MappedFile{static_cast<char*>(base), length, slop, handle});
+#else
+ void* base = mmap(nullptr, file_length, prot, MAP_SHARED, fd, file_offset);
+ if (base == MAP_FAILED) return nullptr;
+ return std::unique_ptr<MappedFile>(new MappedFile{static_cast<char*>(base), length, slop});
+#endif
+}
+
+MappedFile::~MappedFile() {
+#if defined(_WIN32)
+ if (base_ != nullptr) UnmapViewOfFile(base_);
+ if (handle_ != nullptr) CloseHandle(handle_);
+#else
+ if (base_ != nullptr) munmap(base_, size_);
+#endif
+
+ base_ = nullptr;
+ offset_ = size_ = 0;
+}
+
+} // namespace base
+} // namespace android
diff --git a/base/mapped_file_test.cpp b/base/mapped_file_test.cpp
new file mode 100644
index 0000000..57fde6f
--- /dev/null
+++ b/base/mapped_file_test.cpp
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2018 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.
+ */
+
+#include "android-base/mapped_file.h"
+
+#include <gtest/gtest.h>
+
+#include <errno.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+#include <string>
+
+#include "android-base/file.h"
+#include "android-base/test_utils.h"
+#include "android-base/unique_fd.h"
+
+TEST(mapped_file, smoke) {
+ TemporaryFile tf;
+ ASSERT_TRUE(tf.fd != -1);
+ ASSERT_TRUE(android::base::WriteStringToFd("hello world", tf.fd));
+
+ auto m = android::base::MappedFile::FromFd(tf.fd, 3, 2, PROT_READ);
+ ASSERT_EQ(2u, m->size());
+ ASSERT_EQ('l', m->data()[0]);
+ ASSERT_EQ('o', m->data()[1]);
+}
diff --git a/fastboot/fastboot.cpp b/fastboot/fastboot.cpp
index 6b6e659..5101410 100644
--- a/fastboot/fastboot.cpp
+++ b/fastboot/fastboot.cpp
@@ -79,10 +79,6 @@
using android::base::Trim;
using android::base::unique_fd;
-#ifndef O_BINARY
-#define O_BINARY 0
-#endif
-
static const char* serial = nullptr;
static bool g_long_listing = false;
diff --git a/fastboot/fastboot_driver.cpp b/fastboot/fastboot_driver.cpp
index b1f3bc9..65a5247 100644
--- a/fastboot/fastboot_driver.cpp
+++ b/fastboot/fastboot_driver.cpp
@@ -41,10 +41,10 @@
#include <vector>
#include <android-base/file.h>
+#include <android-base/mapped_file.h>
#include <android-base/stringprintf.h>
#include <android-base/strings.h>
#include <android-base/unique_fd.h>
-#include <utils/FileMap.h>
#include "constants.h"
#include "transport.h"
@@ -467,15 +467,14 @@
while (remaining) {
// Memory map the file
- android::FileMap filemap;
size_t len = std::min(remaining, MAX_MAP_SIZE);
-
- if (!filemap.create(NULL, fd, offset, len, true)) {
+ auto mapping{android::base::MappedFile::FromFd(fd, offset, len, PROT_READ)};
+ if (!mapping) {
error_ = "Creating filemap failed";
return IO_ERROR;
}
- if ((ret = SendBuffer(filemap.getDataPtr(), len))) {
+ if ((ret = SendBuffer(mapping->data(), mapping->size()))) {
return ret;
}
diff --git a/fs_mgr/fs_mgr_overlayfs.cpp b/fs_mgr/fs_mgr_overlayfs.cpp
index 64e9fb4..ad488a9 100644
--- a/fs_mgr/fs_mgr_overlayfs.cpp
+++ b/fs_mgr/fs_mgr_overlayfs.cpp
@@ -590,6 +590,7 @@
// Mount kScratchMountPoint
bool fs_mgr_overlayfs_mount_scratch(const std::string& device_path, const std::string mnt_type) {
+ if (!fs_mgr_rw_access(device_path)) return false;
if (setfscreatecon(kOverlayfsFileContext)) {
PERROR << "setfscreatecon " << kOverlayfsFileContext;
}
@@ -826,6 +827,19 @@
if (change) *change = false;
mount_point = fs_mgr_mount_point(mount_point);
auto ret = true;
+ // If scratch exists, but is not mounted, lets gain access to clean
+ // specific override entries.
+ if ((mount_point != nullptr) && !fs_mgr_overlayfs_already_mounted(kScratchMountPoint, false)) {
+ auto scratch_device = fs_mgr_overlayfs_scratch_device();
+ if (scratch_device.empty()) {
+ auto slot_number = fs_mgr_overlayfs_slot_number();
+ auto super_device = fs_mgr_overlayfs_super_device(slot_number);
+ const auto partition_name = android::base::Basename(kScratchMountPoint);
+ CreateLogicalPartition(super_device, slot_number, partition_name, true, 0s,
+ &scratch_device);
+ }
+ fs_mgr_overlayfs_mount_scratch(scratch_device, fs_mgr_overlayfs_scratch_mount_type());
+ }
for (const auto& overlay_mount_point : kOverlayMountPoints) {
ret &= fs_mgr_overlayfs_teardown_one(overlay_mount_point, mount_point ?: "", change);
}
diff --git a/init/action_parser.cpp b/init/action_parser.cpp
index 1481162..2d497b3 100644
--- a/init/action_parser.cpp
+++ b/init/action_parser.cpp
@@ -19,7 +19,11 @@
#include <android-base/properties.h>
#include <android-base/strings.h>
-#include "stable_properties.h"
+#if defined(__ANDROID__)
+#include "property_service.h"
+#else
+#include "host_init_stubs.h"
+#endif
using android::base::GetBoolProperty;
using android::base::StartsWith;
@@ -36,15 +40,7 @@
return true;
}
- if (kExportedActionableProperties.count(prop_name) == 1) {
- return true;
- }
- for (const auto& prefix : kPartnerPrefixes) {
- if (android::base::StartsWith(prop_name, prefix)) {
- return true;
- }
- }
- return false;
+ return CanReadProperty(subcontext->context(), prop_name);
}
Result<Success> ParsePropertyTrigger(const std::string& trigger, Subcontext* subcontext,
diff --git a/init/host_init_stubs.cpp b/init/host_init_stubs.cpp
index 8866bdc..b85e54a 100644
--- a/init/host_init_stubs.cpp
+++ b/init/host_init_stubs.cpp
@@ -30,6 +30,9 @@
std::string default_console = "/dev/console";
// property_service.h
+bool CanReadProperty(const std::string& source_context, const std::string& name) {
+ return true;
+}
uint32_t SetProperty(const std::string& key, const std::string& value) {
android::base::SetProperty(key, value);
return 0;
diff --git a/init/host_init_stubs.h b/init/host_init_stubs.h
index 0af11f6..63ceead 100644
--- a/init/host_init_stubs.h
+++ b/init/host_init_stubs.h
@@ -39,6 +39,7 @@
extern std::string default_console;
// property_service.h
+bool CanReadProperty(const std::string& source_context, const std::string& name);
extern uint32_t (*property_set)(const std::string& name, const std::string& value);
uint32_t HandlePropertySet(const std::string& name, const std::string& value,
const std::string& source_context, const ucred& cr, std::string* error);
diff --git a/init/property_service.cpp b/init/property_service.cpp
index 6aed0a3..5328869 100644
--- a/init/property_service.cpp
+++ b/init/property_service.cpp
@@ -111,6 +111,22 @@
LOG(FATAL) << "Failed to load serialized property info file";
}
}
+
+bool CanReadProperty(const std::string& source_context, const std::string& name) {
+ const char* target_context = nullptr;
+ property_info_area->GetPropertyInfo(name.c_str(), &target_context, nullptr);
+
+ PropertyAuditData audit_data;
+
+ audit_data.name = name.c_str();
+
+ ucred cr = {.pid = 0, .uid = 0, .gid = 0};
+ audit_data.cr = &cr;
+
+ return selinux_check_access(source_context.c_str(), target_context, "file", "read",
+ &audit_data) == 0;
+}
+
static bool CheckMacPerms(const std::string& name, const char* target_context,
const char* source_context, const ucred& cr) {
if (!target_context || !source_context) {
diff --git a/init/property_service.h b/init/property_service.h
index cacd987..9022f5a 100644
--- a/init/property_service.h
+++ b/init/property_service.h
@@ -26,6 +26,8 @@
namespace android {
namespace init {
+bool CanReadProperty(const std::string& source_context, const std::string& name);
+
extern uint32_t (*property_set)(const std::string& name, const std::string& value);
uint32_t HandlePropertySet(const std::string& name, const std::string& value,
diff --git a/init/stable_properties.h b/init/stable_properties.h
deleted file mode 100644
index baef833..0000000
--- a/init/stable_properties.h
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Copyright (C) 2018 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.
- */
-
-#ifndef _INIT_STABLE_PROPERTIES_H
-#define _INIT_STABLE_PROPERTIES_H
-
-#include <set>
-#include <string>
-
-namespace android {
-namespace init {
-
-static constexpr const char* kPartnerPrefixes[] = {
- "init.svc.vendor.", "ro.vendor.", "persist.vendor.", "vendor.", "init.svc.odm.", "ro.odm.",
- "persist.odm.", "odm.", "ro.boot.",
-};
-
-static const std::set<std::string> kExportedActionableProperties = {
- "dev.bootcomplete",
- "init.svc.console",
- "init.svc.dumpstatez",
- "init.svc.mediadrm",
- "init.svc.surfaceflinger",
- "init.svc.zygote",
- "persist.bluetooth.btsnoopenable",
- "persist.sys.crash_rcu",
- "persist.sys.usb.usbradio.config",
- "persist.sys.zram_enabled",
- "ro.board.platform",
- "ro.bootmode",
- "ro.build.type",
- "ro.crypto.state",
- "ro.crypto.type",
- "ro.debuggable",
- "sys.boot_completed",
- "sys.boot_from_charger_mode",
- "sys.retaildemo.enabled",
- "sys.shutdown.requested",
- "sys.usb.config",
- "sys.usb.configfs",
- "sys.usb.ffs.mtp.ready",
- "sys.usb.ffs.ready",
- "sys.user.0.ce_available",
- "sys.vdso",
- "vold.decrypt",
- "vold.post_fs_data_done",
- "vts.native_server.on",
- "wlan.driver.status",
-};
-
-} // namespace init
-} // namespace android
-
-#endif
diff --git a/libnativebridge/Android.bp b/libnativebridge/Android.bp
index 6e63b74..92fd2a2 100644
--- a/libnativebridge/Android.bp
+++ b/libnativebridge/Android.bp
@@ -10,9 +10,11 @@
host_supported: true,
srcs: ["native_bridge.cc"],
+ header_libs: [
+ "libbase_headers",
+ ],
shared_libs: [
"liblog",
- "libbase",
],
export_include_dirs: ["include"],
diff --git a/libnativebridge/tests/Android.mk b/libnativebridge/tests/Android.mk
index 5b9ba1c..4ed6e20 100644
--- a/libnativebridge/tests/Android.mk
+++ b/libnativebridge/tests/Android.mk
@@ -29,10 +29,12 @@
shared_libraries := \
liblog \
- libbase \
libnativebridge \
libnativebridge-dummy
+header_libraries := \
+ libbase_headers
+
libnativebridge_tests_common_cflags := \
-Wall \
-Werror \
@@ -40,6 +42,7 @@
$(foreach file,$(test_src_files), \
$(eval include $(CLEAR_VARS)) \
$(eval LOCAL_SHARED_LIBRARIES := $(shared_libraries)) \
+ $(eval LOCAL_HEADER_LIBRARIES := $(header_libraries)) \
$(eval LOCAL_SRC_FILES := $(file)) \
$(eval LOCAL_CFLAGS := $(libnativebridge_tests_common_cflags)) \
$(eval LOCAL_MODULE := $(notdir $(file:%.cpp=%))) \
@@ -49,6 +52,7 @@
$(foreach file,$(test_src_files), \
$(eval include $(CLEAR_VARS)) \
$(eval LOCAL_SHARED_LIBRARIES := $(shared_libraries)) \
+ $(eval LOCAL_HEADER_LIBRARIES := $(header_libraries)) \
$(eval LOCAL_SRC_FILES := $(file)) \
$(eval LOCAL_CFLAGS := $(libnativebridge_tests_common_cflags)) \
$(eval LOCAL_MODULE := $(notdir $(file:%.cpp=%))) \
diff --git a/libziparchive/Android.bp b/libziparchive/Android.bp
index 3308adf..608afb7 100644
--- a/libziparchive/Android.bp
+++ b/libziparchive/Android.bp
@@ -84,14 +84,6 @@
"libz",
],
target: {
- android: {
- shared_libs: [
- "libutils",
- ],
- },
- host: {
- static_libs: ["libutils"],
- },
linux_bionic: {
enabled: true,
},
diff --git a/libziparchive/include/ziparchive/zip_archive.h b/libziparchive/include/ziparchive/zip_archive.h
index 32d7901..3952532 100644
--- a/libziparchive/include/ziparchive/zip_archive.h
+++ b/libziparchive/include/ziparchive/zip_archive.h
@@ -14,17 +14,16 @@
* limitations under the License.
*/
+#pragma once
+
/*
* Read-only access to Zip archives, with minimal heap allocation.
*/
-#ifndef LIBZIPARCHIVE_ZIPARCHIVE_H_
-#define LIBZIPARCHIVE_ZIPARCHIVE_H_
#include <stdint.h>
#include <string.h>
#include <sys/cdefs.h>
#include <sys/types.h>
-#include <utils/Compat.h>
/* Zip compression methods we support */
enum {
@@ -273,5 +272,3 @@
int32_t Inflate(const Reader& reader, const uint32_t compressed_length,
const uint32_t uncompressed_length, Writer* writer, uint64_t* crc_out);
} // namespace zip_archive
-
-#endif // LIBZIPARCHIVE_ZIPARCHIVE_H_
diff --git a/libziparchive/include/ziparchive/zip_writer.h b/libziparchive/include/ziparchive/zip_writer.h
index 0e0caf1..6e4ca62 100644
--- a/libziparchive/include/ziparchive/zip_writer.h
+++ b/libziparchive/include/ziparchive/zip_writer.h
@@ -14,8 +14,7 @@
* limitations under the License.
*/
-#ifndef LIBZIPARCHIVE_ZIPWRITER_H_
-#define LIBZIPARCHIVE_ZIPWRITER_H_
+#pragma once
#include <cstdio>
#include <ctime>
@@ -25,7 +24,6 @@
#include <vector>
#include "android-base/macros.h"
-#include "utils/Compat.h"
struct z_stream_s;
typedef struct z_stream_s z_stream;
@@ -183,5 +181,3 @@
std::unique_ptr<z_stream, void (*)(z_stream*)> z_stream_;
std::vector<uint8_t> buffer_;
};
-
-#endif /* LIBZIPARCHIVE_ZIPWRITER_H_ */
diff --git a/libziparchive/zip_archive.cc b/libziparchive/zip_archive.cc
index 4221ee7..9d6d919 100644
--- a/libziparchive/zip_archive.cc
+++ b/libziparchive/zip_archive.cc
@@ -20,7 +20,8 @@
#define LOG_TAG "ziparchive"
-#include <assert.h>
+#include "ziparchive/zip_archive.h"
+
#include <errno.h>
#include <fcntl.h>
#include <inttypes.h>
@@ -40,12 +41,10 @@
#include <android-base/file.h>
#include <android-base/logging.h>
#include <android-base/macros.h> // TEMP_FAILURE_RETRY may or may not be in unistd
+#include <android-base/mapped_file.h>
#include <android-base/memory.h>
#include <android-base/utf8.h>
#include <log/log.h>
-#include <utils/Compat.h>
-#include <utils/FileMap.h>
-#include "ziparchive/zip_archive.h"
#include "zlib.h"
#include "entry_name_utils-inl.h"
@@ -58,12 +57,6 @@
// specified in the local file header and the central directory.
static const bool kCrcChecksEnabled = false;
-// This is for windows. If we don't open a file in binary mode, weird
-// things will happen.
-#ifndef O_BINARY
-#define O_BINARY 0
-#endif
-
// The maximum number of bytes to scan backwards for the EOCD start.
static const uint32_t kMaxEOCDSearch = kMaxCommentLen + sizeof(EocdRecord);
@@ -196,7 +189,7 @@
close_file(assume_ownership),
directory_offset(0),
central_directory(),
- directory_map(new android::FileMap()),
+ directory_map(),
num_entries(0),
hash_table_size(0),
hash_table(nullptr) {
@@ -212,7 +205,7 @@
close_file(false),
directory_offset(0),
central_directory(),
- directory_map(new android::FileMap()),
+ directory_map(),
num_entries(0),
hash_table_size(0),
hash_table(nullptr) {}
@@ -303,8 +296,7 @@
* in archive.
*/
- if (!archive->InitializeCentralDirectory(debug_file_name,
- static_cast<off64_t>(eocd->cd_start_offset),
+ if (!archive->InitializeCentralDirectory(static_cast<off64_t>(eocd->cd_start_offset),
static_cast<size_t>(eocd->cd_size))) {
ALOGE("Zip: failed to intialize central directory.\n");
return kMmapFailed;
@@ -823,7 +815,7 @@
virtual bool Append(uint8_t* buf, size_t buf_size) override {
if (bytes_written_ + buf_size > size_) {
- ALOGW("Zip: Unexpected size " ZD " (declared) vs " ZD " (actual)", size_,
+ ALOGW("Zip: Unexpected size %zu (declared) vs %zu (actual)", size_,
bytes_written_ + buf_size);
return false;
}
@@ -910,7 +902,7 @@
virtual bool Append(uint8_t* buf, size_t buf_size) override {
if (total_bytes_written_ + buf_size > declared_length_) {
- ALOGW("Zip: Unexpected size " ZD " (declared) vs " ZD " (actual)", declared_length_,
+ ALOGW("Zip: Unexpected size %zu (declared) vs %zu (actual)", declared_length_,
total_bytes_written_ + buf_size);
return false;
}
@@ -919,7 +911,7 @@
if (result) {
total_bytes_written_ += buf_size;
} else {
- ALOGW("Zip: unable to write " ZD " bytes to file; %s", buf_size, strerror(errno));
+ ALOGW("Zip: unable to write %zu bytes to file; %s", buf_size, strerror(errno));
}
return result;
@@ -1048,7 +1040,7 @@
}
} while (zerr == Z_OK);
- assert(zerr == Z_STREAM_END); /* other errors should've been caught */
+ CHECK_EQ(zerr, Z_STREAM_END); /* other errors should've been caught */
// NOTE: zstream.adler is always set to 0, because we're using the -MAX_WBITS
// "feature" of zlib to tell it there won't be a zlib file header. zlib
@@ -1255,16 +1247,14 @@
length_ = cd_size;
}
-bool ZipArchive::InitializeCentralDirectory(const char* debug_file_name, off64_t cd_start_offset,
- size_t cd_size) {
+bool ZipArchive::InitializeCentralDirectory(off64_t cd_start_offset, size_t cd_size) {
if (mapped_zip.HasFd()) {
- if (!directory_map->create(debug_file_name, mapped_zip.GetFileDescriptor(), cd_start_offset,
- cd_size, true /* read only */)) {
- return false;
- }
+ directory_map = android::base::MappedFile::FromFd(mapped_zip.GetFileDescriptor(),
+ cd_start_offset, cd_size, PROT_READ);
+ if (!directory_map) return false;
- CHECK_EQ(directory_map->getDataLength(), cd_size);
- central_directory.Initialize(directory_map->getDataPtr(), 0 /*offset*/, cd_size);
+ CHECK_EQ(directory_map->size(), cd_size);
+ central_directory.Initialize(directory_map->data(), 0 /*offset*/, cd_size);
} else {
if (mapped_zip.GetBasePtr() == nullptr) {
ALOGE("Zip: Failed to map central directory, bad mapped_zip base pointer\n");
diff --git a/libziparchive/zip_archive_private.h b/libziparchive/zip_archive_private.h
index 83cb11f..330a02a 100644
--- a/libziparchive/zip_archive_private.h
+++ b/libziparchive/zip_archive_private.h
@@ -14,8 +14,9 @@
* limitations under the License.
*/
-#ifndef LIBZIPARCHIVE_ZIPARCHIVE_PRIVATE_H_
-#define LIBZIPARCHIVE_ZIPARCHIVE_PRIVATE_H_
+#pragma once
+
+#include <ziparchive/zip_archive.h>
#include <stdint.h>
#include <stdlib.h>
@@ -24,9 +25,8 @@
#include <memory>
#include <vector>
-#include <utils/FileMap.h>
-#include <ziparchive/zip_archive.h>
#include "android-base/macros.h"
+#include "android-base/mapped_file.h"
static const char* kErrorMessages[] = {
"Success",
@@ -164,7 +164,7 @@
// mapped central directory area
off64_t directory_offset;
CentralDirectory central_directory;
- std::unique_ptr<android::FileMap> directory_map;
+ std::unique_ptr<android::base::MappedFile> directory_map;
// number of entries in the Zip archive
uint16_t num_entries;
@@ -180,8 +180,5 @@
ZipArchive(void* address, size_t length);
~ZipArchive();
- bool InitializeCentralDirectory(const char* debug_file_name, off64_t cd_start_offset,
- size_t cd_size);
+ bool InitializeCentralDirectory(off64_t cd_start_offset, size_t cd_size);
};
-
-#endif // LIBZIPARCHIVE_ZIPARCHIVE_PRIVATE_H_
diff --git a/libziparchive/zip_archive_test.cc b/libziparchive/zip_archive_test.cc
index 23dd5dc..af9f4c8 100644
--- a/libziparchive/zip_archive_test.cc
+++ b/libziparchive/zip_archive_test.cc
@@ -27,10 +27,10 @@
#include <vector>
#include <android-base/file.h>
+#include <android-base/mapped_file.h>
#include <android-base/test_utils.h>
#include <android-base/unique_fd.h>
#include <gtest/gtest.h>
-#include <utils/FileMap.h>
#include <ziparchive/zip_archive.h>
#include <ziparchive/zip_archive_stream_entry.h>
@@ -416,11 +416,10 @@
ASSERT_EQ(0, fstat(fd, &sb));
// Memory map the file first and open the archive from the memory region.
- android::FileMap file_map;
- file_map.create(zip_path.c_str(), fd, 0 /*offset*/, sb.st_size, true);
+ auto file_map{android::base::MappedFile::FromFd(fd, 0, sb.st_size, PROT_READ)};
ZipArchiveHandle handle;
- ASSERT_EQ(0, OpenArchiveFromMemory(file_map.getDataPtr(), file_map.getDataLength(),
- zip_path.c_str(), &handle));
+ ASSERT_EQ(0,
+ OpenArchiveFromMemory(file_map->data(), file_map->size(), zip_path.c_str(), &handle));
// Assert one entry can be found and extracted correctly.
std::string BINARY_PATH("META-INF/com/google/android/update-binary");
diff --git a/libziparchive/zip_writer.cc b/libziparchive/zip_writer.cc
index ed1d135..981df3a 100644
--- a/libziparchive/zip_writer.cc
+++ b/libziparchive/zip_writer.cc
@@ -26,8 +26,6 @@
#include <vector>
#include "android-base/logging.h"
-#include "utils/Compat.h"
-#include "utils/Log.h"
#include "entry_name_utils-inl.h"
#include "zip_archive_common.h"
@@ -303,10 +301,10 @@
if (zerr != Z_OK) {
if (zerr == Z_VERSION_ERROR) {
- ALOGE("Installed zlib is not compatible with linked version (%s)", ZLIB_VERSION);
+ LOG(ERROR) << "Installed zlib is not compatible with linked version (" << ZLIB_VERSION << ")";
return HandleError(kZlibError);
} else {
- ALOGE("deflateInit2 failed (zerr=%d)", zerr);
+ LOG(ERROR) << "deflateInit2 failed (zerr=" << zerr << ")";
return HandleError(kZlibError);
}
}
diff --git a/lmkd/include/lmkd.h b/lmkd/include/lmkd.h
index e8f51da..e72d159 100644
--- a/lmkd/include/lmkd.h
+++ b/lmkd/include/lmkd.h
@@ -31,6 +31,7 @@
LMK_PROCPRIO, /* Register a process and set its oom_adj_score */
LMK_PROCREMOVE, /* Unregister a process */
LMK_PROCPURGE, /* Purge all registered processes */
+ LMK_GETKILLCNT, /* Get number of kills */
};
/*
@@ -152,6 +153,44 @@
return sizeof(int);
}
+/* LMK_GETKILLCNT packet payload */
+struct lmk_getkillcnt {
+ int min_oomadj;
+ int max_oomadj;
+};
+
+/*
+ * For LMK_GETKILLCNT packet get its payload.
+ * Warning: no checks performed, caller should ensure valid parameters.
+ */
+inline void lmkd_pack_get_getkillcnt(LMKD_CTRL_PACKET packet,
+ struct lmk_getkillcnt *params) {
+ params->min_oomadj = ntohl(packet[1]);
+ params->max_oomadj = ntohl(packet[2]);
+}
+
+/*
+ * Prepare LMK_GETKILLCNT packet and return packet size in bytes.
+ * Warning: no checks performed, caller should ensure valid parameters.
+ */
+inline size_t lmkd_pack_set_getkillcnt(LMKD_CTRL_PACKET packet,
+ struct lmk_getkillcnt *params) {
+ packet[0] = htonl(LMK_GETKILLCNT);
+ packet[1] = htonl(params->min_oomadj);
+ packet[2] = htonl(params->max_oomadj);
+ return 3 * sizeof(int);
+}
+
+/*
+ * Prepare LMK_GETKILLCNT reply packet and return packet size in bytes.
+ * Warning: no checks performed, caller should ensure valid parameters.
+ */
+inline size_t lmkd_pack_set_getkillcnt_repl(LMKD_CTRL_PACKET packet, int kill_cnt) {
+ packet[0] = htonl(LMK_GETKILLCNT);
+ packet[1] = htonl(kill_cnt);
+ return 2 * sizeof(int);
+}
+
__END_DECLS
#endif /* _LMKD_H_ */
diff --git a/lmkd/lmkd.c b/lmkd/lmkd.c
index 0a469e8..e3c4ccc 100644
--- a/lmkd/lmkd.c
+++ b/lmkd/lmkd.c
@@ -313,7 +313,20 @@
#define pid_hashfn(x) ((((x) >> 8) ^ (x)) & (PIDHASH_SZ - 1))
#define ADJTOSLOT(adj) ((adj) + -OOM_SCORE_ADJ_MIN)
-static struct adjslot_list procadjslot_list[ADJTOSLOT(OOM_SCORE_ADJ_MAX) + 1];
+#define ADJTOSLOT_COUNT (ADJTOSLOT(OOM_SCORE_ADJ_MAX) + 1)
+static struct adjslot_list procadjslot_list[ADJTOSLOT_COUNT];
+
+#define MAX_DISTINCT_OOM_ADJ 32
+#define KILLCNT_INVALID_IDX 0xFF
+/*
+ * Because killcnt array is sparse a two-level indirection is used
+ * to keep the size small. killcnt_idx stores index of the element in
+ * killcnt array. Index KILLCNT_INVALID_IDX indicates an unused slot.
+ */
+static uint8_t killcnt_idx[ADJTOSLOT_COUNT];
+static uint16_t killcnt[MAX_DISTINCT_OOM_ADJ];
+static int killcnt_free_idx = 0;
+static uint32_t killcnt_total = 0;
/* PAGE_SIZE / 1024 */
static long page_k;
@@ -644,6 +657,67 @@
memset(&pidhash[0], 0, sizeof(pidhash));
}
+static void inc_killcnt(int oomadj) {
+ int slot = ADJTOSLOT(oomadj);
+ uint8_t idx = killcnt_idx[slot];
+
+ if (idx == KILLCNT_INVALID_IDX) {
+ /* index is not assigned for this oomadj */
+ if (killcnt_free_idx < MAX_DISTINCT_OOM_ADJ) {
+ killcnt_idx[slot] = killcnt_free_idx;
+ killcnt[killcnt_free_idx] = 1;
+ killcnt_free_idx++;
+ } else {
+ ALOGW("Number of distinct oomadj levels exceeds %d",
+ MAX_DISTINCT_OOM_ADJ);
+ }
+ } else {
+ /*
+ * wraparound is highly unlikely and is detectable using total
+ * counter because it has to be equal to the sum of all counters
+ */
+ killcnt[idx]++;
+ }
+ /* increment total kill counter */
+ killcnt_total++;
+}
+
+static int get_killcnt(int min_oomadj, int max_oomadj) {
+ int slot;
+ int count = 0;
+
+ if (min_oomadj > max_oomadj)
+ return 0;
+
+ /* special case to get total kill count */
+ if (min_oomadj > OOM_SCORE_ADJ_MAX)
+ return killcnt_total;
+
+ while (min_oomadj <= max_oomadj &&
+ (slot = ADJTOSLOT(min_oomadj)) < ADJTOSLOT_COUNT) {
+ uint8_t idx = killcnt_idx[slot];
+ if (idx != KILLCNT_INVALID_IDX) {
+ count += killcnt[idx];
+ }
+ min_oomadj++;
+ }
+
+ return count;
+}
+
+static int cmd_getkillcnt(LMKD_CTRL_PACKET packet) {
+ struct lmk_getkillcnt params;
+
+ if (use_inkernel_interface) {
+ /* kernel driver does not expose this information */
+ return 0;
+ }
+
+ lmkd_pack_get_getkillcnt(packet, ¶ms);
+
+ return get_killcnt(params.min_oomadj, params.max_oomadj);
+}
+
static void cmd_target(int ntargets, LMKD_CTRL_PACKET packet) {
int i;
struct lmk_target target;
@@ -748,12 +822,28 @@
return ret;
}
+static int ctrl_data_write(int dsock_idx, char *buf, size_t bufsz) {
+ int ret = 0;
+
+ ret = TEMP_FAILURE_RETRY(write(data_sock[dsock_idx].sock, buf, bufsz));
+
+ if (ret == -1) {
+ ALOGE("control data socket write failed; errno=%d", errno);
+ } else if (ret == 0) {
+ ALOGE("Got EOF on control data socket");
+ ret = -1;
+ }
+
+ return ret;
+}
+
static void ctrl_command_handler(int dsock_idx) {
LMKD_CTRL_PACKET packet;
int len;
enum lmk_cmd cmd;
int nargs;
int targets;
+ int kill_cnt;
len = ctrl_data_read(dsock_idx, (char *)packet, CTRL_PACKET_MAX_SIZE);
if (len <= 0)
@@ -791,6 +881,14 @@
goto wronglen;
cmd_procpurge();
break;
+ case LMK_GETKILLCNT:
+ if (nargs != 2)
+ goto wronglen;
+ kill_cnt = cmd_getkillcnt(packet);
+ len = lmkd_pack_set_getkillcnt_repl(packet, kill_cnt);
+ if (ctrl_data_write(dsock_idx, (char *)packet, len) != len)
+ return;
+ break;
default:
ALOGE("Received unknown command code %d", cmd);
return;
@@ -1200,6 +1298,7 @@
/* CAP_KILL required */
r = kill(pid, SIGKILL);
+ inc_killcnt(procp->oomadj);
ALOGI("Kill '%s' (%d), uid %d, oom_adj %d to free %ldkB",
taskname, pid, uid, procp->oomadj, tasksize * page_k);
@@ -1700,6 +1799,8 @@
procadjslot_list[i].prev = &procadjslot_list[i];
}
+ memset(killcnt_idx, KILLCNT_INVALID_IDX, sizeof(killcnt_idx));
+
return 0;
}
diff --git a/rootdir/init.rc b/rootdir/init.rc
index ea83ef9..025e3c3 100644
--- a/rootdir/init.rc
+++ b/rootdir/init.rc
@@ -489,6 +489,8 @@
mkdir /data/misc/profman 0770 system shell
mkdir /data/misc/gcov 0770 root root
+ mkdir /data/preloads 0775 system system
+
mkdir /data/vendor 0771 root root
mkdir /data/vendor_ce 0771 root root
mkdir /data/vendor_de 0771 root root