Merge commit 'a63ccea6abc7ea02e2d98e41c80793ca97237bd3' from

oc-mr1-dev-plus-aosp into stage-aosp-master

Change-Id: Ia33311cd1fd26dfaea59a69317b306fb91203c40
Merged-In: I03d06b10807e8a313c9654c2e1db36bfb59e3f99
This commit is contained in:
Xin Li 2017-11-14 12:12:57 -08:00
commit 23e27db576
49 changed files with 580 additions and 683 deletions

View File

@ -60,4 +60,14 @@ $(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/lib/hw/gatekeeper.$(TARGET_D
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/lib64/hw/gatekeeper.$(TARGET_DEVICE).so)
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/root/vendor)
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/root/init.rc)
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/lib/libtrusty.so)
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/lib64/libtrusty.so)
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/lib/hw/keystore.trusty.so)
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/lib64/hw/keystore.trusty.so)
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/lib/hw/gatekeeper.trusty.so)
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/lib64/hw/gatekeeper.trusty.so)
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/bin/secure-storage-unit-test)
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/bin/storageproxyd)
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/bin/tipc-test)
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/bin/trusty_keymaster_tipc)
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/root/root)

View File

@ -12,8 +12,12 @@
// See the License for the specific language governing permissions and
// limitations under the License.
cc_library_static {
cc_library {
name: "libadf",
vendor_available: true,
vndk: {
enabled: true,
},
srcs: ["adf.cpp"],
cflags: ["-Werror"],
local_include_dirs: ["include"],

View File

@ -38,7 +38,6 @@ static int format_ext4(char *fs_blkdev, char *fs_mnt_point, bool crypt_footer)
{
uint64_t dev_sz;
int fd, rc = 0;
int status;
if ((fd = open(fs_blkdev, O_WRONLY)) < 0) {
PERROR << "Cannot open block device";
@ -62,7 +61,7 @@ static int format_ext4(char *fs_blkdev, char *fs_mnt_point, bool crypt_footer)
const char* const mke2fs_args[] = {
"/system/bin/mke2fs", "-t", "ext4", "-b", "4096", fs_blkdev, size_str.c_str(), nullptr};
rc = android_fork_execvp_ext(arraysize(mke2fs_args), const_cast<char**>(mke2fs_args), &status,
rc = android_fork_execvp_ext(arraysize(mke2fs_args), const_cast<char**>(mke2fs_args), NULL,
true, LOG_KLOG, true, nullptr, nullptr, 0);
if (rc) {
LERROR << "mke2fs returned " << rc;
@ -78,7 +77,7 @@ static int format_ext4(char *fs_blkdev, char *fs_mnt_point, bool crypt_footer)
nullptr};
rc = android_fork_execvp_ext(arraysize(e2fsdroid_args), const_cast<char**>(e2fsdroid_args),
&status, true, LOG_KLOG, true, nullptr, nullptr, 0);
NULL, true, LOG_KLOG, true, nullptr, nullptr, 0);
if (rc) {
LERROR << "e2fsdroid returned " << rc;
}
@ -88,10 +87,9 @@ static int format_ext4(char *fs_blkdev, char *fs_mnt_point, bool crypt_footer)
static int format_f2fs(char *fs_blkdev)
{
int status;
const char* const args[] = {"/system/bin/make_f2fs", "-f", "-O encrypt", fs_blkdev, nullptr};
return android_fork_execvp_ext(arraysize(args), const_cast<char**>(args), &status, true,
return android_fork_execvp_ext(arraysize(args), const_cast<char**>(args), NULL, true,
LOG_KLOG, true, nullptr, nullptr, 0);
}

View File

@ -21,8 +21,7 @@ LOCAL_CFLAGS := -Wall -Wextra -Werror -Wunused
LOCAL_SRC_FILES := \
SoftGateKeeperDevice.cpp \
IGateKeeperService.cpp \
gatekeeperd.cpp \
IUserManager.cpp
gatekeeperd.cpp
LOCAL_MODULE := gatekeeperd
LOCAL_SHARED_LIBRARIES := \

View File

@ -1,57 +0,0 @@
/*
* Copyright (C) 2015 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.
*/
#define LOG_TAG "IUserManager"
#include <stdint.h>
#include <sys/types.h>
#include <utils/Log.h>
#include <binder/Parcel.h>
#include "IUserManager.h"
namespace android {
class BpUserManager : public BpInterface<IUserManager>
{
public:
explicit BpUserManager(const sp<IBinder>& impl) :
BpInterface<IUserManager>(impl) {
}
virtual int32_t getCredentialOwnerProfile(int32_t user_id) {
Parcel data, reply;
data.writeInterfaceToken(IUserManager::getInterfaceDescriptor());
data.writeInt32(user_id);
status_t rc = remote()->transact(GET_CREDENTIAL_OWNER_PROFILE, data, &reply, 0);
if (rc != NO_ERROR) {
ALOGE("%s: failed (%d)\n", __func__, rc);
return -1;
}
int32_t exception = reply.readExceptionCode();
if (exception != 0) {
ALOGE("%s: got exception (%d)\n", __func__, exception);
return -1;
}
return reply.readInt32();
}
};
IMPLEMENT_META_INTERFACE(UserManager, "android.os.IUserManager");
}; // namespace android

View File

@ -1,46 +0,0 @@
/*
* Copyright (C) 2015 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 IUSERMANAGER_H_
#define IUSERMANAGER_H_
#include <inttypes.h>
#include <utils/Errors.h>
#include <binder/IInterface.h>
#include <binder/Parcel.h>
#include <utils/Vector.h>
namespace android {
/*
* Communication channel to UserManager
*/
class IUserManager : public IInterface {
public:
// must be kept in sync with IUserManager.aidl
enum {
GET_CREDENTIAL_OWNER_PROFILE = IBinder::FIRST_CALL_TRANSACTION + 0,
};
virtual int32_t getCredentialOwnerProfile(int32_t user_id) = 0;
DECLARE_META_INTERFACE(UserManager);
};
}; // namespace android
#endif // IUSERMANAGER_H_

View File

@ -38,7 +38,6 @@
#include <utils/String16.h>
#include "SoftGateKeeperDevice.h"
#include "IUserManager.h"
#include <hidl/HidlSupport.h>
#include <android/hardware/gatekeeper/1.0/IGatekeeper.h>
@ -335,23 +334,7 @@ public:
return ret;
}
virtual uint64_t getSecureUserId(uint32_t uid) {
uint64_t sid = read_sid(uid);
if (sid == 0) {
// might be a work profile, look up the parent
sp<IServiceManager> sm = defaultServiceManager();
sp<IBinder> binder = sm->getService(String16("user"));
sp<IUserManager> um = interface_cast<IUserManager>(binder);
int32_t parent = um->getCredentialOwnerProfile(uid);
if (parent < 0) {
return 0;
} else if (parent != (int32_t) uid) {
return read_sid(parent);
}
}
return sid;
}
virtual uint64_t getSecureUserId(uint32_t uid) { return read_sid(uid); }
virtual void clearSecureUserId(uint32_t uid) {
IPCThreadState* ipc = IPCThreadState::self();

7
healthd/Android.bp Normal file
View File

@ -0,0 +1,7 @@
cc_library_headers {
name: "libhealthd_headers",
vendor_available: true,
export_include_dirs: ["include"],
header_libs: ["libbatteryservice_headers"],
export_header_lib_headers: ["libbatteryservice_headers"],
}

View File

@ -418,7 +418,6 @@ void SelinuxRestoreContext() {
selinux_android_restorecon("/dev/urandom", 0);
selinux_android_restorecon("/dev/__properties__", 0);
selinux_android_restorecon("/file_contexts.bin", 0);
selinux_android_restorecon("/plat_file_contexts", 0);
selinux_android_restorecon("/nonplat_file_contexts", 0);
selinux_android_restorecon("/plat_property_contexts", 0);

View File

@ -179,7 +179,11 @@ class FuseBridgeEntry {
}
const uint32_t opcode = buffer_.request.header.opcode;
LOG(VERBOSE) << "Read a fuse packet, opcode=" << opcode;
const uint64_t unique = buffer_.request.header.unique;
LOG(VERBOSE) << "Read a fuse packet, opcode=" << opcode << " unique=" << unique;
if (unique == 0) {
return FuseBridgeState::kWaitToReadEither;
}
switch (opcode) {
case FUSE_FORGET:
// Do not reply to FUSE_FORGET.

View File

@ -67,6 +67,7 @@ class FuseBridgeLoopTest : public ::testing::Test {
memset(&request_, 0, sizeof(FuseRequest));
request_.header.opcode = opcode;
request_.header.len = sizeof(fuse_in_header);
request_.header.unique = 1;
ASSERT_TRUE(request_.Write(dev_sockets_[0]));
memset(&response_, 0, sizeof(FuseResponse));

View File

@ -54,7 +54,7 @@ test_c_flags := \
-Werror \
-fno-builtin \
test_src_files := \
cts_src_files := \
libc_test.cpp \
liblog_test_default.cpp \
liblog_test_local.cpp \
@ -67,6 +67,9 @@ test_src_files := \
log_time_test.cpp \
log_wrap_test.cpp
test_src_files := \
$(cts_src_files) \
# Build tests for the device (with .so). Run with:
# adb shell /data/nativetest/liblog-unit-tests/liblog-unit-tests
include $(CLEAR_VARS)
@ -82,15 +85,15 @@ cts_executable := CtsLiblogTestCases
include $(CLEAR_VARS)
LOCAL_MODULE := $(cts_executable)
LOCAL_MODULE_TAGS := tests
LOCAL_CFLAGS += $(test_c_flags)
LOCAL_SRC_FILES := $(test_src_files)
LOCAL_CFLAGS += $(test_c_flags) -DNO_PSTORE
LOCAL_SRC_FILES := $(cts_src_files)
LOCAL_MODULE_PATH := $(TARGET_OUT_DATA)/nativetest
LOCAL_MULTILIB := both
LOCAL_MODULE_STEM_32 := $(LOCAL_MODULE)32
LOCAL_MODULE_STEM_64 := $(LOCAL_MODULE)64
LOCAL_SHARED_LIBRARIES := liblog libcutils libbase
LOCAL_STATIC_LIBRARIES := libgtest libgtest_main
LOCAL_COMPATIBILITY_SUITE := cts
LOCAL_COMPATIBILITY_SUITE := cts vts
LOCAL_CTS_TEST_PACKAGE := android.core.liblog
include $(BUILD_CTS_EXECUTABLE)

View File

@ -116,6 +116,7 @@ static std::string popenToString(const std::string& command) {
return ret;
}
#ifndef NO_PSTORE
static bool isPmsgActive() {
pid_t pid = getpid();
@ -125,6 +126,7 @@ static bool isPmsgActive() {
return std::string::npos != myPidFds.find(" -> /dev/pmsg0");
}
#endif /* NO_PSTORE */
static bool isLogdwActive() {
std::string logdwSignature =
@ -189,22 +191,25 @@ TEST(liblog, __android_log_btwrite__android_logger_list_read) {
EXPECT_LT(0, __android_log_btwrite(0, EVENT_TYPE_LONG, &ts, sizeof(ts)));
#ifdef USING_LOGGER_DEFAULT
// Check that we can close and reopen the logger
bool pmsgActiveAfter__android_log_btwrite;
bool logdwActiveAfter__android_log_btwrite;
if (getuid() == AID_ROOT) {
tested__android_log_close = true;
pmsgActiveAfter__android_log_btwrite = isPmsgActive();
logdwActiveAfter__android_log_btwrite = isLogdwActive();
#ifndef NO_PSTORE
bool pmsgActiveAfter__android_log_btwrite = isPmsgActive();
EXPECT_TRUE(pmsgActiveAfter__android_log_btwrite);
#endif /* NO_PSTORE */
logdwActiveAfter__android_log_btwrite = isLogdwActive();
EXPECT_TRUE(logdwActiveAfter__android_log_btwrite);
} else if (!tested__android_log_close) {
fprintf(stderr, "WARNING: can not test __android_log_close()\n");
}
__android_log_close();
if (getuid() == AID_ROOT) {
#ifndef NO_PSTORE
bool pmsgActiveAfter__android_log_close = isPmsgActive();
bool logdwActiveAfter__android_log_close = isLogdwActive();
EXPECT_FALSE(pmsgActiveAfter__android_log_close);
#endif /* NO_PSTORE */
bool logdwActiveAfter__android_log_close = isLogdwActive();
EXPECT_FALSE(logdwActiveAfter__android_log_close);
}
#endif
@ -213,9 +218,11 @@ TEST(liblog, __android_log_btwrite__android_logger_list_read) {
EXPECT_LT(0, __android_log_btwrite(0, EVENT_TYPE_LONG, &ts1, sizeof(ts1)));
#ifdef USING_LOGGER_DEFAULT
if (getuid() == AID_ROOT) {
pmsgActiveAfter__android_log_btwrite = isPmsgActive();
logdwActiveAfter__android_log_btwrite = isLogdwActive();
#ifndef NO_PSTORE
bool pmsgActiveAfter__android_log_btwrite = isPmsgActive();
EXPECT_TRUE(pmsgActiveAfter__android_log_btwrite);
#endif /* NO_PSTORE */
logdwActiveAfter__android_log_btwrite = isLogdwActive();
EXPECT_TRUE(logdwActiveAfter__android_log_btwrite);
}
#endif
@ -3036,12 +3043,15 @@ TEST(liblog, android_log_write_list_buffer) {
#ifdef USING_LOGGER_DEFAULT // Do not retest pmsg functionality
#ifdef __ANDROID__
#ifndef NO_PSTORE
static const char __pmsg_file[] =
"/data/william-shakespeare/MuchAdoAboutNothing.txt";
#endif /* NO_PSTORE */
#endif
TEST(liblog, __android_log_pmsg_file_write) {
#ifdef __ANDROID__
#ifndef NO_PSTORE
__android_log_close();
if (getuid() == AID_ROOT) {
tested__android_log_close = true;
@ -3092,12 +3102,16 @@ TEST(liblog, __android_log_pmsg_file_write) {
EXPECT_TRUE(pmsgActiveAfter__android_pmsg_file_write);
EXPECT_TRUE(logdwActiveAfter__android_pmsg_file_write);
}
#else /* NO_PSTORE */
GTEST_LOG_(INFO) << "This test does nothing because of NO_PSTORE.\n";
#endif /* NO_PSTORE */
#else
GTEST_LOG_(INFO) << "This test does nothing.\n";
#endif
}
#ifdef __ANDROID__
#ifndef NO_PSTORE
static ssize_t __pmsg_fn(log_id_t logId, char prio, const char* filename,
const char* buf, size_t len, void* arg) {
EXPECT_TRUE(NULL == arg);
@ -3118,10 +3132,12 @@ static ssize_t __pmsg_fn(log_id_t logId, char prio, const char* filename,
? -ENOEXEC
: 1;
}
#endif /* NO_PSTORE */
#endif
TEST(liblog, __android_log_pmsg_file_read) {
#ifdef __ANDROID__
#ifndef NO_PSTORE
signaled = 0;
__android_log_close();
@ -3155,6 +3171,9 @@ TEST(liblog, __android_log_pmsg_file_read) {
EXPECT_LT(0, ret);
EXPECT_EQ(1U, signaled);
#else /* NO_PSTORE */
GTEST_LOG_(INFO) << "This test does nothing because of NO_PSTORE.\n";
#endif /* NO_PSTORE */
#else
GTEST_LOG_(INFO) << "This test does nothing.\n";
#endif

View File

@ -34,6 +34,7 @@ jstring CreateClassLoaderNamespace(JNIEnv* env,
int32_t target_sdk_version,
jobject class_loader,
bool is_shared,
bool is_for_vendor,
jstring library_path,
jstring permitted_path);

View File

@ -82,6 +82,11 @@ static constexpr const char* kPublicNativeLibrariesSystemConfigPathFromRoot =
"/etc/public.libraries.txt";
static constexpr const char* kPublicNativeLibrariesVendorConfig =
"/vendor/etc/public.libraries.txt";
static constexpr const char* kLlndkNativeLibrariesSystemConfigPathFromRoot =
"/etc/llndk.libraries.txt";
static constexpr const char* kVndkspNativeLibrariesSystemConfigPathFromRoot =
"/etc/vndksp.libraries.txt";
// The device may be configured to have the vendor libraries loaded to a separate namespace.
// For historical reasons this namespace was named sphal but effectively it is intended
@ -89,6 +94,11 @@ static constexpr const char* kPublicNativeLibrariesVendorConfig =
// vendor and system namespaces.
static constexpr const char* kVendorNamespaceName = "sphal";
static constexpr const char* kVndkNamespaceName = "vndk";
static constexpr const char* kClassloaderNamespaceName = "classloader-namespace";
static constexpr const char* kVendorClassloaderNamespaceName = "vendor-classloader-namespace";
// (http://b/27588281) This is a workaround for apps using custom classloaders and calling
// System.load() with an absolute path which is outside of the classloader library search path.
// This list includes all directories app is allowed to access this way.
@ -108,6 +118,7 @@ class LibraryNamespaces {
uint32_t target_sdk_version,
jobject class_loader,
bool is_shared,
bool is_for_vendor,
jstring java_library_path,
jstring java_permitted_path,
NativeLoaderNamespace* ns,
@ -163,9 +174,39 @@ class LibraryNamespaces {
is_native_bridge = NativeBridgeIsPathSupported(library_path.c_str());
}
std::string system_exposed_libraries = system_public_libraries_;
const char* namespace_name = kClassloaderNamespaceName;
android_namespace_t* vndk_ns = nullptr;
if (is_for_vendor && !is_shared) {
LOG_FATAL_IF(is_native_bridge, "Unbundled vendor apk must not use translated architecture");
// For vendor apks, give access to the vendor lib even though
// they are treated as unbundled; the libs and apks are still bundled
// together in the vendor partition.
#if defined(__LP64__)
std::string vendor_lib_path = "/vendor/lib64";
#else
std::string vendor_lib_path = "/vendor/lib";
#endif
library_path = library_path + ":" + vendor_lib_path.c_str();
permitted_path = permitted_path + ":" + vendor_lib_path.c_str();
// Also give access to LLNDK libraries since they are available to vendors
system_exposed_libraries = system_exposed_libraries + ":" + system_llndk_libraries_.c_str();
// Give access to VNDK-SP libraries from the 'vndk' namespace.
vndk_ns = android_get_exported_namespace(kVndkNamespaceName);
LOG_ALWAYS_FATAL_IF(vndk_ns == nullptr,
"Cannot find \"%s\" namespace for vendor apks", kVndkNamespaceName);
// Different name is useful for debugging
namespace_name = kVendorClassloaderNamespaceName;
ALOGD("classloader namespace configured for unbundled vendor apk. library_path=%s", library_path.c_str());
}
NativeLoaderNamespace native_loader_ns;
if (!is_native_bridge) {
android_namespace_t* ns = android_create_namespace("classloader-namespace",
android_namespace_t* ns = android_create_namespace(namespace_name,
nullptr,
library_path.c_str(),
namespace_type,
@ -181,11 +222,19 @@ class LibraryNamespaces {
// which is expected behavior in this case.
android_namespace_t* vendor_ns = android_get_exported_namespace(kVendorNamespaceName);
if (!android_link_namespaces(ns, nullptr, system_public_libraries_.c_str())) {
if (!android_link_namespaces(ns, nullptr, system_exposed_libraries.c_str())) {
*error_msg = dlerror();
return false;
}
if (vndk_ns != nullptr && !system_vndksp_libraries_.empty()) {
// vendor apks are allowed to use VNDK-SP libraries.
if (!android_link_namespaces(ns, vndk_ns, system_vndksp_libraries_.c_str())) {
*error_msg = dlerror();
return false;
}
}
if (!vendor_public_libraries_.empty()) {
if (!android_link_namespaces(ns, vendor_ns, vendor_public_libraries_.c_str())) {
*error_msg = dlerror();
@ -195,7 +244,7 @@ class LibraryNamespaces {
native_loader_ns = NativeLoaderNamespace(ns);
} else {
native_bridge_namespace_t* ns = NativeBridgeCreateNamespace("classloader-namespace",
native_bridge_namespace_t* ns = NativeBridgeCreateNamespace(namespace_name,
nullptr,
library_path.c_str(),
namespace_type,
@ -209,7 +258,7 @@ class LibraryNamespaces {
native_bridge_namespace_t* vendor_ns = NativeBridgeGetVendorNamespace();
if (!NativeBridgeLinkNamespaces(ns, nullptr, system_public_libraries_.c_str())) {
if (!NativeBridgeLinkNamespaces(ns, nullptr, system_exposed_libraries.c_str())) {
*error_msg = NativeBridgeGetError();
return false;
}
@ -259,6 +308,10 @@ class LibraryNamespaces {
std::string root_dir = android_root_env != nullptr ? android_root_env : "/system";
std::string public_native_libraries_system_config =
root_dir + kPublicNativeLibrariesSystemConfigPathFromRoot;
std::string llndk_native_libraries_system_config =
root_dir + kLlndkNativeLibrariesSystemConfigPathFromRoot;
std::string vndksp_native_libraries_system_config =
root_dir + kVndkspNativeLibrariesSystemConfigPathFromRoot;
std::string error_msg;
LOG_ALWAYS_FATAL_IF(!ReadConfig(public_native_libraries_system_config, &sonames, &error_msg),
@ -293,6 +346,14 @@ class LibraryNamespaces {
system_public_libraries_ = base::Join(sonames, ':');
sonames.clear();
ReadConfig(kLlndkNativeLibrariesSystemConfigPathFromRoot, &sonames);
system_llndk_libraries_ = base::Join(sonames, ':');
sonames.clear();
ReadConfig(kVndkspNativeLibrariesSystemConfigPathFromRoot, &sonames);
system_vndksp_libraries_ = base::Join(sonames, ':');
sonames.clear();
// This file is optional, quietly ignore if the file does not exist.
ReadConfig(kPublicNativeLibrariesVendorConfig, &sonames);
@ -404,6 +465,8 @@ class LibraryNamespaces {
std::vector<std::pair<jweak, NativeLoaderNamespace>> namespaces_;
std::string system_public_libraries_;
std::string vendor_public_libraries_;
std::string system_llndk_libraries_;
std::string system_vndksp_libraries_;
DISALLOW_COPY_AND_ASSIGN(LibraryNamespaces);
};
@ -430,6 +493,7 @@ jstring CreateClassLoaderNamespace(JNIEnv* env,
int32_t target_sdk_version,
jobject class_loader,
bool is_shared,
bool is_for_vendor,
jstring library_path,
jstring permitted_path) {
#if defined(__ANDROID__)
@ -441,6 +505,7 @@ jstring CreateClassLoaderNamespace(JNIEnv* env,
target_sdk_version,
class_loader,
is_shared,
is_for_vendor,
library_path,
permitted_path,
&ns,
@ -449,7 +514,7 @@ jstring CreateClassLoaderNamespace(JNIEnv* env,
return env->NewStringUTF(error_msg.c_str());
}
#else
UNUSED(env, target_sdk_version, class_loader, is_shared,
UNUSED(env, target_sdk_version, class_loader, is_shared, is_for_vendor,
library_path, permitted_path);
#endif
return nullptr;
@ -478,7 +543,8 @@ void* OpenNativeLibrary(JNIEnv* env,
if (!g_namespaces->Create(env,
target_sdk_version,
class_loader,
false,
false /* is_shared */,
false /* is_for_vendor */,
library_path,
nullptr,
&ns,

View File

@ -55,6 +55,9 @@ enum {
/* ui service treads might want to run at a urgent display (uncommon) */
ANDROID_PRIORITY_URGENT_DISPLAY = HAL_PRIORITY_URGENT_DISPLAY,
/* all normal video threads */
ANDROID_PRIORITY_VIDEO = -10,
/* all normal audio threads */
ANDROID_PRIORITY_AUDIO = -16,

View File

@ -180,7 +180,15 @@ ssize_t utf32_to_utf8_length(const char32_t *src, size_t src_len)
size_t ret = 0;
const char32_t *end = src + src_len;
while (src < end) {
ret += utf32_codepoint_utf8_length(*src++);
size_t char_len = utf32_codepoint_utf8_length(*src++);
if (SSIZE_MAX - char_len < ret) {
// If this happens, we would overflow the ssize_t type when
// returning from this function, so we cannot express how
// long this string is in an ssize_t.
android_errorWriteLog(0x534e4554, "37723026");
return -1;
}
ret += char_len;
}
return ret;
}
@ -439,14 +447,23 @@ ssize_t utf16_to_utf8_length(const char16_t *src, size_t src_len)
size_t ret = 0;
const char16_t* const end = src + src_len;
while (src < end) {
size_t char_len;
if ((*src & 0xFC00) == 0xD800 && (src + 1) < end
&& (*(src + 1) & 0xFC00) == 0xDC00) {
// surrogate pairs are always 4 bytes.
ret += 4;
char_len = 4;
src += 2;
} else {
ret += utf32_codepoint_utf8_length((char32_t) *src++);
char_len = utf32_codepoint_utf8_length((char32_t)*src++);
}
if (SSIZE_MAX - char_len < ret) {
// If this happens, we would overflow the ssize_t type when
// returning from this function, so we cannot express how
// long this string is in an ssize_t.
android_errorWriteLog(0x534e4554, "37723026");
return -1;
}
ret += char_len;
}
return ret;
}

View File

@ -379,6 +379,22 @@ static int32_t ParseZipArchive(ZipArchive* archive) {
return -1;
}
}
uint32_t lfh_start_bytes;
if (!archive->mapped_zip.ReadAtOffset(reinterpret_cast<uint8_t*>(&lfh_start_bytes),
sizeof(uint32_t), 0)) {
ALOGW("Zip: Unable to read header for entry at offset == 0.");
return -1;
}
if (lfh_start_bytes != LocalFileHeader::kSignature) {
ALOGW("Zip: Entry at offset zero has invalid LFH signature %" PRIx32, lfh_start_bytes);
#if defined(__ANDROID__)
android_errorWriteLog(0x534e4554, "64211847");
#endif
return -1;
}
ALOGV("+++ zip good scan %" PRIu16 " entries", num_entries);
return 0;

View File

@ -18,19 +18,21 @@
#include <arpa/inet.h>
#include <errno.h>
#include <inttypes.h>
#include <sched.h>
#include <signal.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <sys/cdefs.h>
#include <sys/epoll.h>
#include <sys/eventfd.h>
#include <sys/mman.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <time.h>
#include <unistd.h>
#include <cutils/properties.h>
#include <cutils/sockets.h>
#include <log/log.h>
#include <processgroup/processgroup.h>
@ -40,7 +42,10 @@
#endif
#define MEMCG_SYSFS_PATH "/dev/memcg/"
#define MEMPRESSURE_WATCH_LEVEL "low"
#define MEMCG_MEMORY_USAGE "/dev/memcg/memory.usage_in_bytes"
#define MEMCG_MEMORYSW_USAGE "/dev/memcg/memory.memsw.usage_in_bytes"
#define MEMPRESSURE_WATCH_MEDIUM_LEVEL "medium"
#define MEMPRESSURE_WATCH_CRITICAL_LEVEL "critical"
#define ZONEINFO_PATH "/proc/zoneinfo"
#define LINE_MAX 128
@ -48,6 +53,7 @@
#define INKERNEL_ADJ_PATH "/sys/module/lowmemorykiller/parameters/adj"
#define ARRAY_SIZE(x) (sizeof(x) / sizeof(*(x)))
#define EIGHT_MEGA (1 << 23)
enum lmk_cmd {
LMK_TARGET,
@ -64,17 +70,28 @@ enum lmk_cmd {
/* default to old in-kernel interface if no memory pressure events */
static int use_inkernel_interface = 1;
static bool has_inkernel_module;
/* memory pressure level medium event */
static int mpevfd;
static int mpevfd[2];
#define CRITICAL_INDEX 1
#define MEDIUM_INDEX 0
static int medium_oomadj;
static int critical_oomadj;
static bool debug_process_killing;
static bool enable_pressure_upgrade;
static int64_t upgrade_pressure;
static int64_t downgrade_pressure;
static bool is_go_device;
/* control socket listen and data */
static int ctrl_lfd;
static int ctrl_dfd = -1;
static int ctrl_dfd_reopened; /* did we reopen ctrl conn on this loop? */
/* 1 memory pressure level, 1 ctrl listen socket, 1 ctrl data socket */
#define MAX_EPOLL_EVENTS 3
/* 2 memory pressure levels, 1 ctrl listen socket, 1 ctrl data socket */
#define MAX_EPOLL_EVENTS 4
static int epollfd;
static int maxevents;
@ -113,14 +130,6 @@ static struct proc *pidhash[PIDHASH_SZ];
#define ADJTOSLOT(adj) ((adj) + -OOM_SCORE_ADJ_MIN)
static struct adjslot_list procadjslot_list[ADJTOSLOT(OOM_SCORE_ADJ_MAX) + 1];
/*
* Wait 1-2 seconds for the death report of a killed process prior to
* considering killing more processes.
*/
#define KILL_TIMEOUT 2
/* Time of last process kill we initiated, stop me before I kill again */
static time_t kill_lasttime;
/* PAGE_SIZE / 1024 */
static long page_k;
@ -241,6 +250,7 @@ static void cmd_procprio(int pid, int uid, int oomadj) {
struct proc *procp;
char path[80];
char val[20];
int soft_limit_mult;
if (oomadj < OOM_SCORE_ADJ_MIN || oomadj > OOM_SCORE_ADJ_MAX) {
ALOGE("Invalid PROCPRIO oomadj argument %d", oomadj);
@ -254,6 +264,38 @@ static void cmd_procprio(int pid, int uid, int oomadj) {
if (use_inkernel_interface)
return;
if (oomadj >= 900) {
soft_limit_mult = 0;
} else if (oomadj >= 800) {
soft_limit_mult = 0;
} else if (oomadj >= 700) {
soft_limit_mult = 0;
} else if (oomadj >= 600) {
// Launcher should be perceptible, don't kill it.
oomadj = 200;
soft_limit_mult = 1;
} else if (oomadj >= 500) {
soft_limit_mult = 0;
} else if (oomadj >= 400) {
soft_limit_mult = 0;
} else if (oomadj >= 300) {
soft_limit_mult = 1;
} else if (oomadj >= 200) {
soft_limit_mult = 2;
} else if (oomadj >= 100) {
soft_limit_mult = 10;
} else if (oomadj >= 0) {
soft_limit_mult = 20;
} else {
// Persistent processes will have a large
// soft limit 512MB.
soft_limit_mult = 64;
}
snprintf(path, sizeof(path), "/dev/memcg/apps/uid_%d/pid_%d/memory.soft_limit_in_bytes", uid, pid);
snprintf(val, sizeof(val), "%d", soft_limit_mult * EIGHT_MEGA);
writefilestring(path, val);
procp = pid_lookup(pid);
if (!procp) {
procp = malloc(sizeof(struct proc));
@ -278,7 +320,6 @@ static void cmd_procremove(int pid) {
return;
pid_remove(pid);
kill_lasttime = 0;
}
static void cmd_target(int ntargets, int *params) {
@ -294,7 +335,7 @@ static void cmd_target(int ntargets, int *params) {
lowmem_targets_size = ntargets;
if (use_inkernel_interface) {
if (has_inkernel_module) {
char minfreestr[128];
char killpriostr[128];
@ -309,9 +350,9 @@ static void cmd_target(int ntargets, int *params) {
strlcat(killpriostr, ",", sizeof(killpriostr));
}
snprintf(val, sizeof(val), "%d", lowmem_minfree[i]);
snprintf(val, sizeof(val), "%d", use_inkernel_interface ? lowmem_minfree[i] : 0);
strlcat(minfreestr, val, sizeof(minfreestr));
snprintf(val, sizeof(val), "%d", lowmem_adj[i]);
snprintf(val, sizeof(val), "%d", use_inkernel_interface ? lowmem_adj[i] : 0);
strlcat(killpriostr, val, sizeof(killpriostr));
}
@ -546,9 +587,7 @@ static struct proc *proc_adj_lru(int oomadj) {
}
/* Kill one process specified by procp. Returns the size of the process killed */
static int kill_one_process(struct proc *procp, int other_free, int other_file,
int minfree, int min_score_adj, bool first)
{
static int kill_one_process(struct proc* procp, int min_score_adj, bool is_critical) {
int pid = procp->pid;
uid_t uid = procp->uid;
char *taskname;
@ -567,14 +606,12 @@ static int kill_one_process(struct proc *procp, int other_free, int other_file,
return -1;
}
ALOGI("Killing '%s' (%d), uid %d, adj %d\n"
" to free %ldkB because cache %s%ldkB is below limit %ldkB for oom_adj %d\n"
" Free memory is %s%ldkB %s reserved",
taskname, pid, uid, procp->oomadj, tasksize * page_k,
first ? "" : "~", other_file * page_k, minfree * page_k, min_score_adj,
first ? "" : "~", other_free * page_k, other_free >= 0 ? "above" : "below");
ALOGI(
"Killing '%s' (%d), uid %d, adj %d\n"
" to free %ldkB because system is under %s memory pressure oom_adj %d\n",
taskname, pid, uid, procp->oomadj, tasksize * page_k, is_critical ? "critical" : "medium",
min_score_adj);
r = kill(pid, SIGKILL);
killProcessGroup(uid, pid, SIGKILL);
pid_remove(pid);
if (r) {
@ -589,23 +626,10 @@ static int kill_one_process(struct proc *procp, int other_free, int other_file,
* Find a process to kill based on the current (possibly estimated) free memory
* and cached memory sizes. Returns the size of the killed processes.
*/
static int find_and_kill_process(int other_free, int other_file, bool first)
{
static int find_and_kill_process(bool is_critical) {
int i;
int min_score_adj = OOM_SCORE_ADJ_MAX + 1;
int minfree = 0;
int killed_size = 0;
for (i = 0; i < lowmem_targets_size; i++) {
minfree = lowmem_minfree[i];
if (other_free < minfree && other_file < minfree) {
min_score_adj = lowmem_adj[i];
break;
}
}
if (min_score_adj == OOM_SCORE_ADJ_MAX + 1)
return 0;
int min_score_adj = is_critical ? critical_oomadj : medium_oomadj;
for (i = OOM_SCORE_ADJ_MAX; i >= min_score_adj; i--) {
struct proc *procp;
@ -614,7 +638,7 @@ retry:
procp = proc_adj_lru(i);
if (procp) {
killed_size = kill_one_process(procp, other_free, other_file, minfree, min_score_adj, first);
killed_size = kill_one_process(procp, min_score_adj, is_critical);
if (killed_size < 0) {
goto retry;
} else {
@ -626,42 +650,91 @@ retry:
return 0;
}
static void mp_event(uint32_t events __unused) {
static int64_t get_memory_usage(const char* path) {
int ret;
int64_t mem_usage;
char buf[32];
int fd = open(path, O_RDONLY | O_CLOEXEC);
if (fd == -1) {
ALOGE("%s open: errno=%d", path, errno);
return -1;
}
ret = read_all(fd, buf, sizeof(buf) - 1);
close(fd);
if (ret < 0) {
ALOGE("%s error: errno=%d", path, errno);
return -1;
}
sscanf(buf, "%" SCNd64, &mem_usage);
if (mem_usage == 0) {
ALOGE("No memory!");
return -1;
}
return mem_usage;
}
static void mp_event_common(bool is_critical) {
int ret;
unsigned long long evcount;
struct sysmeminfo mi;
int other_free;
int other_file;
int killed_size;
bool first = true;
int index = is_critical ? CRITICAL_INDEX : MEDIUM_INDEX;
int64_t mem_usage, memsw_usage;
int64_t mem_pressure;
ret = read(mpevfd, &evcount, sizeof(evcount));
ret = read(mpevfd[index], &evcount, sizeof(evcount));
if (ret < 0)
ALOGE("Error reading memory pressure event fd; errno=%d",
errno);
if (time(NULL) - kill_lasttime < KILL_TIMEOUT)
mem_usage = get_memory_usage(MEMCG_MEMORY_USAGE);
memsw_usage = get_memory_usage(MEMCG_MEMORYSW_USAGE);
if (memsw_usage < 0 || mem_usage < 0) {
find_and_kill_process(is_critical);
return;
while (zoneinfo_parse(&mi) < 0) {
// Failed to read /proc/zoneinfo, assume ENOMEM and kill something
find_and_kill_process(0, 0, true);
}
other_free = mi.nr_free_pages - mi.totalreserve_pages;
other_file = mi.nr_file_pages - mi.nr_shmem;
// Calculate percent for swappinness.
mem_pressure = (mem_usage * 100) / memsw_usage;
do {
killed_size = find_and_kill_process(other_free, other_file, first);
if (killed_size > 0) {
first = false;
other_free += killed_size;
other_file += killed_size;
if (enable_pressure_upgrade && !is_critical) {
// We are swapping too much.
if (mem_pressure < upgrade_pressure) {
ALOGI("Event upgraded to critical.");
is_critical = true;
}
} while (killed_size > 0);
}
// If the pressure is larger than downgrade_pressure lmk will not
// kill any process, since enough memory is available.
if (mem_pressure > downgrade_pressure) {
if (debug_process_killing) {
ALOGI("Ignore %s memory pressure", is_critical ? "critical" : "medium");
}
return;
} else if (is_critical && mem_pressure > upgrade_pressure) {
if (debug_process_killing) {
ALOGI("Downgrade critical memory pressure");
}
// Downgrade event to medium, since enough memory available.
is_critical = false;
}
if (find_and_kill_process(is_critical) == 0) {
if (debug_process_killing) {
ALOGI("Nothing to kill");
}
}
}
static int init_mp(char *levelstr, void *event_handler)
static void mp_event(uint32_t events __unused) {
mp_event_common(false);
}
static void mp_event_critical(uint32_t events __unused) {
mp_event_common(true);
}
static int init_mp_common(char *levelstr, void *event_handler, bool is_critical)
{
int mpfd;
int evfd;
@ -669,6 +742,7 @@ static int init_mp(char *levelstr, void *event_handler)
char buf[256];
struct epoll_event epev;
int ret;
int mpevfd_index = is_critical ? CRITICAL_INDEX : MEDIUM_INDEX;
mpfd = open(MEMCG_SYSFS_PATH "memory.pressure_level", O_RDONLY | O_CLOEXEC);
if (mpfd < 0) {
@ -709,7 +783,7 @@ static int init_mp(char *levelstr, void *event_handler)
goto err;
}
maxevents++;
mpevfd = evfd;
mpevfd[mpevfd_index] = evfd;
return 0;
err:
@ -722,6 +796,16 @@ err_open_mpfd:
return -1;
}
static int init_mp_medium()
{
return init_mp_common(MEMPRESSURE_WATCH_MEDIUM_LEVEL, (void *)&mp_event, false);
}
static int init_mp_critical()
{
return init_mp_common(MEMPRESSURE_WATCH_CRITICAL_LEVEL, (void *)&mp_event_critical, true);
}
static int init(void) {
struct epoll_event epev;
int i;
@ -758,12 +842,14 @@ static int init(void) {
}
maxevents++;
use_inkernel_interface = !access(INKERNEL_MINFREE_PATH, W_OK);
has_inkernel_module = !access(INKERNEL_MINFREE_PATH, W_OK);
use_inkernel_interface = has_inkernel_module && !is_go_device;
if (use_inkernel_interface) {
ALOGI("Using in-kernel low memory killer interface");
} else {
ret = init_mp(MEMPRESSURE_WATCH_LEVEL, (void *)&mp_event);
ret = init_mp_medium();
ret |= init_mp_critical();
if (ret)
ALOGE("Kernel does not support memory pressure events or in-kernel low memory killer");
}
@ -806,6 +892,14 @@ int main(int argc __unused, char **argv __unused) {
.sched_priority = 1,
};
medium_oomadj = property_get_int32("ro.lmk.medium", 800);
critical_oomadj = property_get_int32("ro.lmk.critical", 0);
debug_process_killing = property_get_bool("ro.lmk.debug", false);
enable_pressure_upgrade = property_get_bool("ro.lmk.critical_upgrade", false);
upgrade_pressure = (int64_t)property_get_int32("ro.lmk.upgrade_pressure", 50);
downgrade_pressure = (int64_t)property_get_int32("ro.lmk.downgrade_pressure", 60);
is_go_device = property_get_bool("ro.config.low_ram", false);
mlockall(MCL_FUTURE);
sched_setscheduler(0, SCHED_FIFO, &param);
if (!init())

View File

@ -63,7 +63,7 @@ LOCAL_MODULE_STEM_32 := $(LOCAL_MODULE)32
LOCAL_MODULE_STEM_64 := $(LOCAL_MODULE)64
LOCAL_SHARED_LIBRARIES := libbase libcutils liblog libselinux
LOCAL_STATIC_LIBRARIES := libgtest libgtest_main
LOCAL_COMPATIBILITY_SUITE := cts
LOCAL_COMPATIBILITY_SUITE := cts vts
LOCAL_CTS_TEST_PACKAGE := android.core.logd
include $(BUILD_CTS_EXECUTABLE)

View File

@ -257,3 +257,45 @@ LOCAL_MODULE_PATH := $(TARGET_OUT_ETC)
LOCAL_MODULE_STEM := $(LOCAL_MODULE)
include $(BUILD_PREBUILT)
endif
#######################################
# llndk.libraries.txt
include $(CLEAR_VARS)
LOCAL_MODULE := llndk.libraries.txt
LOCAL_MODULE_CLASS := ETC
LOCAL_MODULE_PATH := $(TARGET_OUT_ETC)
LOCAL_MODULE_STEM := $(LOCAL_MODULE)
include $(BUILD_SYSTEM)/base_rules.mk
llndk_md5 = $(word 1, $(shell echo $(LLNDK_LIBRARIES) | $(MD5SUM)))
llndk_dep = $(intermediates)/$(llndk_md5).dep
$(llndk_dep):
$(hide) mkdir -p $(dir $@) && rm -rf $(dir $@)*.dep && touch $@
$(LOCAL_BUILT_MODULE): PRIVATE_LLNDK_LIBRARIES := $(LLNDK_LIBRARIES)
$(LOCAL_BUILT_MODULE): $(llndk_dep)
@echo "Generate: $@"
@mkdir -p $(dir $@)
$(hide) echo -n > $@
$(hide) $(foreach lib,$(PRIVATE_LLNDK_LIBRARIES), \
echo $(lib).so >> $@;)
#######################################
# vndksp.libraries.txt
include $(CLEAR_VARS)
LOCAL_MODULE := vndksp.libraries.txt
LOCAL_MODULE_CLASS := ETC
LOCAL_MODULE_PATH := $(TARGET_OUT_ETC)
LOCAL_MODULE_STEM := $(LOCAL_MODULE)
include $(BUILD_SYSTEM)/base_rules.mk
vndksp_md5 = $(word 1, $(shell echo $(LLNDK_LIBRARIES) | $(MD5SUM)))
vndksp_dep = $(intermediates)/$(vndksp_md5).dep
$(vndksp_dep):
$(hide) mkdir -p $(dir $@) && rm -rf $(dir $@)*.dep && touch $@
$(LOCAL_BUILT_MODULE): PRIVATE_VNDK_SAMEPROCESS_LIBRARIES := $(VNDK_SAMEPROCESS_LIBRARIES)
$(LOCAL_BUILT_MODULE): $(vndksp_dep)
@echo "Generate: $@"
@mkdir -p $(dir $@)
$(hide) echo -n > $@
$(hide) $(foreach lib,$(PRIVATE_VNDK_SAMEPROCESS_LIBRARIES), \
echo $(lib).so >> $@;)

View File

@ -27,16 +27,12 @@ additional.namespaces = sphal,vndk,rs
# can't be loaded in this namespace.
###############################################################################
namespace.default.isolated = true
# TODO(b/63553457): remove /vendor/lib from the search path. For now, this is
# required since the classloader namespace for vendor apks should have access
# vendor libraries in the directory. These search paths are copied to the search
# paths of the classloader namespace.
namespace.default.search.paths = /system/${LIB}:/vendor/${LIB}
namespace.default.search.paths = /system/${LIB}
# /vendor/app, /vendor/framework were added since libart should be able to dlopen
# the odex files from the directory.
namespace.default.permitted.paths = /system/${LIB}/drm:/system/${LIB}/hw:/system/framework:/system/app:/system/priv-app:/vendor/app:/vendor/framework:/oem/app:/data:/mnt/expand
namespace.default.asan.search.paths = /data/asan/system/${LIB}:/system/${LIB}:/data/asan/vendor/${LIB}:/vendor/${LIB}
namespace.default.asan.search.paths = /data/asan/system/${LIB}:/system/${LIB}
namespace.default.asan.permitted.paths = /data:/system/${LIB}/drm:/system/${LIB}/hw:/system/framework:/system/app:/system/priv-app:/vendor/app:/vendor/framework:/oem/app:/mnt/expand
###############################################################################
@ -99,6 +95,7 @@ namespace.rs.link.vndk.shared_libs = %VNDK_SAMEPROCESS_LIBRARIES%
# This namespace is exclusively for vndk-sp libs.
###############################################################################
namespace.vndk.isolated = true
namespace.vndk.visible = true
namespace.vndk.search.paths = /vendor/${LIB}/vndk-sp:/system/${LIB}/vndk-sp
namespace.vndk.permitted.paths = /vendor/${LIB}/hw:/vendor/${LIB}/egl
@ -135,9 +132,7 @@ namespace.default.asan.search.paths = /data/asan/vendor/${LIB}/hw:/vendor/${LIB}
namespace.default.asan.permitted.paths = /data/asan/vendor:/vendor:/data/asan/system/${LIB}/vndk:/system/${LIB}/vndk:/data/asan/system/${LIB}/vndk-sp:/system/${LIB}/vndk-sp
namespace.default.links = system
namespace.default.link.system.shared_libs = %LLNDK_LIBRARIES%:libmedia.so:libandroid_runtime.so
# libmedia.so must be removed after we have fix for lib-dplmedia.so (b/64427765)
# libandroid_runtime.so must be removed after we have a fix for qseeproxydaemon (b/64820887)
namespace.default.link.system.shared_libs = %LLNDK_LIBRARIES%
###############################################################################
# "system" namespace

View File

@ -15,6 +15,7 @@ liblog.so
libmediandk.so
libm.so
libnativewindow.so
libneuralnetworks.so
libOpenMAXAL.so
libOpenSLES.so
libRS.so

View File

@ -15,6 +15,7 @@ liblog.so
libmediandk.so
libm.so
libnativewindow.so
libneuralnetworks.so
libOpenMAXAL.so
libOpenSLES.so
libRS.so

View File

@ -148,6 +148,9 @@ on init
write /proc/sys/net/ipv4/conf/all/accept_redirects 0
write /proc/sys/net/ipv6/conf/all/accept_redirects 0
# /proc/net/fib_trie leaks interface IP addresses
chmod 0400 /proc/net/fib_trie
# Create cgroup mount points for process groups
mkdir /dev/cpuctl
mount cgroup none /dev/cpuctl cpu

View File

@ -319,17 +319,31 @@ static void run(const char* source_path, const char* label, uid_t uid,
LOG(FATAL) << "terminated prematurely";
}
static bool sdcardfs_setup(const std::string& source_path, const std::string& dest_path, uid_t fsuid,
gid_t fsgid, bool multi_user, userid_t userid, gid_t gid, mode_t mask) {
std::string opts = android::base::StringPrintf("fsuid=%d,fsgid=%d,%smask=%d,userid=%d,gid=%d",
fsuid, fsgid, multi_user?"multiuser,":"", mask, userid, gid);
static bool sdcardfs_setup(const std::string& source_path, const std::string& dest_path,
uid_t fsuid, gid_t fsgid, bool multi_user, userid_t userid, gid_t gid,
mode_t mask, bool derive_gid) {
std::string opts = android::base::StringPrintf(
"fsuid=%d,fsgid=%d,%s%smask=%d,userid=%d,gid=%d", fsuid, fsgid,
multi_user ? "multiuser," : "", derive_gid ? "derive_gid," : "", mask, userid, gid);
if (mount(source_path.c_str(), dest_path.c_str(), "sdcardfs",
MS_NOSUID | MS_NODEV | MS_NOEXEC | MS_NOATIME, opts.c_str()) == -1) {
PLOG(ERROR) << "failed to mount sdcardfs filesystem";
return false;
if (derive_gid) {
PLOG(ERROR) << "trying to mount sdcardfs filesystem without derive_gid";
/* Maybe this isn't supported on this kernel. Try without. */
opts = android::base::StringPrintf("fsuid=%d,fsgid=%d,%smask=%d,userid=%d,gid=%d",
fsuid, fsgid, multi_user ? "multiuser," : "", mask,
userid, gid);
if (mount(source_path.c_str(), dest_path.c_str(), "sdcardfs",
MS_NOSUID | MS_NODEV | MS_NOEXEC | MS_NOATIME, opts.c_str()) == -1) {
PLOG(ERROR) << "failed to mount sdcardfs filesystem";
return false;
}
} else {
PLOG(ERROR) << "failed to mount sdcardfs filesystem";
return false;
}
}
return true;
}
@ -355,7 +369,8 @@ static bool sdcardfs_setup_bind_remount(const std::string& source_path, const st
}
static void run_sdcardfs(const std::string& source_path, const std::string& label, uid_t uid,
gid_t gid, userid_t userid, bool multi_user, bool full_write) {
gid_t gid, userid_t userid, bool multi_user, bool full_write,
bool derive_gid) {
std::string dest_path_default = "/mnt/runtime/default/" + label;
std::string dest_path_read = "/mnt/runtime/read/" + label;
std::string dest_path_write = "/mnt/runtime/write/" + label;
@ -365,10 +380,10 @@ static void run_sdcardfs(const std::string& source_path, const std::string& labe
// Multi-user storage is fully isolated per user, so "other"
// permissions are completely masked off.
if (!sdcardfs_setup(source_path, dest_path_default, uid, gid, multi_user, userid,
AID_SDCARD_RW, 0006)
|| !sdcardfs_setup_bind_remount(dest_path_default, dest_path_read, AID_EVERYBODY, 0027)
|| !sdcardfs_setup_bind_remount(dest_path_default, dest_path_write,
AID_EVERYBODY, full_write ? 0007 : 0027)) {
AID_SDCARD_RW, 0006, derive_gid) ||
!sdcardfs_setup_bind_remount(dest_path_default, dest_path_read, AID_EVERYBODY, 0027) ||
!sdcardfs_setup_bind_remount(dest_path_default, dest_path_write, AID_EVERYBODY,
full_write ? 0007 : 0027)) {
LOG(FATAL) << "failed to sdcardfs_setup";
}
} else {
@ -376,11 +391,11 @@ static void run_sdcardfs(const std::string& source_path, const std::string& labe
// the Android directories are masked off to a single user
// deep inside attr_from_stat().
if (!sdcardfs_setup(source_path, dest_path_default, uid, gid, multi_user, userid,
AID_SDCARD_RW, 0006)
|| !sdcardfs_setup_bind_remount(dest_path_default, dest_path_read,
AID_EVERYBODY, full_write ? 0027 : 0022)
|| !sdcardfs_setup_bind_remount(dest_path_default, dest_path_write,
AID_EVERYBODY, full_write ? 0007 : 0022)) {
AID_SDCARD_RW, 0006, derive_gid) ||
!sdcardfs_setup_bind_remount(dest_path_default, dest_path_read, AID_EVERYBODY,
full_write ? 0027 : 0022) ||
!sdcardfs_setup_bind_remount(dest_path_default, dest_path_write, AID_EVERYBODY,
full_write ? 0007 : 0022)) {
LOG(FATAL) << "failed to sdcardfs_setup";
}
}
@ -437,7 +452,8 @@ static int usage() {
<< " -g: specify GID to run as"
<< " -U: specify user ID that owns device"
<< " -m: source_path is multi-user"
<< " -w: runtime write mount has full write access";
<< " -w: runtime write mount has full write access"
<< " -P preserve owners on the lower file system";
return 1;
}
@ -449,12 +465,13 @@ int main(int argc, char **argv) {
userid_t userid = 0;
bool multi_user = false;
bool full_write = false;
bool derive_gid = false;
int i;
struct rlimit rlim;
int fs_version;
int opt;
while ((opt = getopt(argc, argv, "u:g:U:mw")) != -1) {
while ((opt = getopt(argc, argv, "u:g:U:mwG")) != -1) {
switch (opt) {
case 'u':
uid = strtoul(optarg, NULL, 10);
@ -471,6 +488,9 @@ int main(int argc, char **argv) {
case 'w':
full_write = true;
break;
case 'G':
derive_gid = true;
break;
case '?':
default:
return usage();
@ -514,7 +534,7 @@ int main(int argc, char **argv) {
}
if (should_use_sdcardfs()) {
run_sdcardfs(source_path, label, uid, gid, userid, multi_user, full_write);
run_sdcardfs(source_path, label, uid, gid, userid, multi_user, full_write, derive_gid);
} else {
run(source_path, label, uid, gid, userid, multi_user, full_write);
}

View File

@ -9,7 +9,6 @@ LIBSTORAGED_SHARED_LIBRARIES := \
libcutils \
liblog \
libsysutils \
libpackagelistparser \
libbatteryservice \
include $(CLEAR_VARS)

View File

@ -256,6 +256,7 @@ private:
uid_monitor mUidm;
time_t mStarttime;
sp<IBatteryPropertiesRegistrar> battery_properties;
std::unique_ptr<storage_info_t> storage_info;
public:
storaged_t(void);
~storaged_t() {}
@ -285,6 +286,8 @@ public:
void init_battery_service();
virtual void batteryPropertiesChanged(struct BatteryProperties props);
void binderDied(const wp<IBinder>& who);
void report_storage_info();
};
// Eventlog tag

View File

@ -27,39 +27,46 @@ using namespace std;
class storage_info_t {
protected:
FRIEND_TEST(storaged_test, storage_info_t);
// emmc lifetime
uint16_t eol; // pre-eol (end of life) information
uint16_t lifetime_a; // device life time estimation (type A)
uint16_t lifetime_b; // device life time estimation (type B)
string version; // version string
// free space
const string userdata_path = "/data";
uint64_t userdata_total_kb;
uint64_t userdata_free_kb;
storage_info_t() : eol(0), lifetime_a(0), lifetime_b(0),
userdata_total_kb(0), userdata_free_kb(0) {}
void publish();
storage_info_t* s_info;
public:
storage_info_t() : eol(0), lifetime_a(0), lifetime_b(0) {}
static storage_info_t* get_storage_info();
virtual ~storage_info_t() {}
virtual bool report() = 0;
virtual void report() {};
void refresh();
};
class emmc_info_t : public storage_info_t {
private:
const string emmc_sysfs = "/sys/bus/mmc/devices/mmc0:0001/";
const string emmc_debugfs = "/d/mmc0/mmc0:0001/ext_csd";
const char* emmc_ver_str[9] = {
"4.0", "4.1", "4.2", "4.3", "Obsolete", "4.41", "4.5", "5.0", "5.1"
};
public:
virtual ~emmc_info_t() {}
bool report();
bool report_sysfs();
bool report_debugfs();
public:
static const string emmc_sysfs;
static const string emmc_debugfs;
static const char* emmc_ver_str[];
virtual ~emmc_info_t() {}
virtual void report();
};
class ufs_info_t : public storage_info_t {
private:
const string health_file = "/sys/devices/soc/624000.ufshc/health";
public:
static const string health_file;
virtual ~ufs_info_t() {}
bool report();
virtual void report();
};
void report_storage_health();
#endif /* _STORAGED_INFO_H_ */

View File

@ -49,6 +49,7 @@ void* storaged_main(void* /* unused */) {
storaged = new storaged_t();
storaged->init_battery_service();
storaged->report_storage_info();
LOG_TO(SYSTEM, INFO) << "storaged: Start";
@ -113,7 +114,6 @@ int main(int argc, char** argv) {
}
if (flag_main_service) { // start main thread
report_storage_health();
// Start the main thread of storaged
pthread_t storaged_main_thread;
errno = pthread_create(&storaged_main_thread, NULL, storaged_main, NULL);

View File

@ -200,6 +200,10 @@ void storaged_t::binderDied(const wp<IBinder>& who) {
}
}
void storaged_t::report_storage_info() {
storage_info->report();
}
/* storaged_t */
storaged_t::storaged_t(void) {
if (access(MMC_DISK_STATS_PATH, R_OK) < 0 && access(SDA_DISK_STATS_PATH, R_OK) < 0) {
@ -222,6 +226,8 @@ storaged_t::storaged_t(void) {
mConfig.periodic_chores_interval_uid_io =
property_get_int32("ro.storaged.uid_io.interval", DEFAULT_PERIODIC_CHORES_INTERVAL_UID_IO);
storage_info.reset(storage_info_t::get_storage_info());
mStarttime = time(NULL);
}
@ -229,6 +235,7 @@ void storaged_t::event(void) {
if (mConfig.diskstats_available) {
mDiskStats.update();
mDsm.update();
storage_info->refresh();
if (mTimer && (mTimer % mConfig.periodic_chores_interval_disk_stats_publish) == 0) {
mDiskStats.publish();
}

View File

@ -18,6 +18,7 @@
#include <stdio.h>
#include <string.h>
#include <sys/statvfs.h>
#include <android-base/file.h>
#include <android-base/parseint.h>
@ -30,13 +31,42 @@
using namespace std;
using namespace android::base;
void report_storage_health()
{
emmc_info_t mmc;
ufs_info_t ufs;
const string emmc_info_t::emmc_sysfs = "/sys/bus/mmc/devices/mmc0:0001/";
const string emmc_info_t::emmc_debugfs = "/d/mmc0/mmc0:0001/ext_csd";
const char* emmc_info_t::emmc_ver_str[9] = {
"4.0", "4.1", "4.2", "4.3", "Obsolete", "4.41", "4.5", "5.0", "5.1"
};
mmc.report();
ufs.report();
const string ufs_info_t::health_file = "/sys/devices/soc/624000.ufshc/health";
static bool FileExists(const std::string& filename)
{
struct stat buffer;
return stat(filename.c_str(), &buffer) == 0;
}
storage_info_t* storage_info_t::get_storage_info()
{
if (FileExists(emmc_info_t::emmc_sysfs) ||
FileExists(emmc_info_t::emmc_debugfs)) {
return new emmc_info_t;
}
if (FileExists(ufs_info_t::health_file)) {
return new ufs_info_t;
}
return new storage_info_t;
}
void storage_info_t::refresh()
{
struct statvfs buf;
if (statvfs(userdata_path.c_str(), &buf) != 0) {
PLOG_TO(SYSTEM, WARNING) << "Failed to get userdata info";
return;
}
userdata_total_kb = buf.f_bsize * buf.f_blocks >> 10;
userdata_free_kb = buf.f_bfree * buf.f_blocks >> 10;
}
void storage_info_t::publish()
@ -46,13 +76,12 @@ void storage_info_t::publish()
<< LOG_ID_EVENTS;
}
bool emmc_info_t::report()
void emmc_info_t::report()
{
if (!report_sysfs() && !report_debugfs())
return false;
return;
publish();
return true;
}
bool emmc_info_t::report_sysfs()
@ -136,21 +165,21 @@ bool emmc_info_t::report_debugfs()
return true;
}
bool ufs_info_t::report()
void ufs_info_t::report()
{
string buffer;
if (!ReadFileToString(health_file, &buffer)) {
return false;
return;
}
vector<string> lines = Split(buffer, "\n");
if (lines.empty()) {
return false;
return;
}
char rev[8];
if (sscanf(lines[0].c_str(), "ufs version: 0x%7s\n", rev) < 1) {
return false;
return;
}
version = "ufs " + string(rev);
@ -175,10 +204,9 @@ bool ufs_info_t::report()
}
if (eol == 0 || (lifetime_a == 0 && lifetime_b == 0)) {
return false;
return;
}
publish();
return true;
}

View File

@ -22,33 +22,24 @@
#include <string>
#include <unordered_map>
#include <android/content/pm/IPackageManagerNative.h>
#include <android-base/file.h>
#include <android-base/logging.h>
#include <android-base/macros.h>
#include <android-base/parseint.h>
#include <android-base/strings.h>
#include <android-base/stringprintf.h>
#include <binder/IServiceManager.h>
#include <log/log_event_list.h>
#include <packagelistparser/packagelistparser.h>
#include "storaged.h"
#include "storaged_uid_monitor.h"
using namespace android;
using namespace android::base;
using namespace android::content::pm;
static bool packagelist_parse_cb(pkg_info* info, void* userdata)
{
std::unordered_map<uint32_t, struct uid_info>* uids =
reinterpret_cast<std::unordered_map<uint32_t, struct uid_info>*>(userdata);
if (uids->find(info->uid) != uids->end()) {
(*uids)[info->uid].name = info->name;
}
packagelist_free(info);
return true;
}
static bool refresh_uid_names;
std::unordered_map<uint32_t, struct uid_info> uid_monitor::get_uid_io_stats()
{
@ -56,6 +47,38 @@ std::unordered_map<uint32_t, struct uid_info> uid_monitor::get_uid_io_stats()
return get_uid_io_stats_locked();
};
static void get_uid_names(const vector<int>& uids, const vector<std::string*>& uid_names)
{
sp<IServiceManager> sm = defaultServiceManager();
if (sm == NULL) {
LOG_TO(SYSTEM, ERROR) << "defaultServiceManager failed";
return;
}
sp<IBinder> binder = sm->getService(String16("package_native"));
if (binder == NULL) {
LOG_TO(SYSTEM, ERROR) << "getService package_native failed";
return;
}
sp<IPackageManagerNative> package_mgr = interface_cast<IPackageManagerNative>(binder);
std::vector<std::string> names;
binder::Status status = package_mgr->getNamesForUids(uids, &names);
if (!status.isOk()) {
LOG_TO(SYSTEM, ERROR) << "package_native::getNamesForUids failed: "
<< status.exceptionMessage();
return;
}
for (uint32_t i = 0; i < uid_names.size(); i++) {
if (!names[i].empty()) {
*uid_names[i] = names[i];
}
}
refresh_uid_names = false;
}
std::unordered_map<uint32_t, struct uid_info> uid_monitor::get_uid_io_stats_locked()
{
std::unordered_map<uint32_t, struct uid_info> uid_io_stats;
@ -67,7 +90,8 @@ std::unordered_map<uint32_t, struct uid_info> uid_monitor::get_uid_io_stats_lock
std::vector<std::string> io_stats = Split(buffer, "\n");
struct uid_info u;
bool refresh_uid = false;
vector<int> uids;
vector<std::string*> uid_names;
for (uint32_t i = 0; i < io_stats.size(); i++) {
if (io_stats[i].empty()) {
@ -91,17 +115,19 @@ std::unordered_map<uint32_t, struct uid_info> uid_monitor::get_uid_io_stats_lock
continue;
}
if (last_uid_io_stats.find(u.uid) == last_uid_io_stats.end()) {
refresh_uid = true;
u.name = std::to_string(u.uid);
} else {
u.name = last_uid_io_stats[u.uid].name;
}
uid_io_stats[u.uid] = u;
uid_io_stats[u.uid].name = std::to_string(u.uid);
uids.push_back(u.uid);
uid_names.push_back(&uid_io_stats[u.uid].name);
if (last_uid_io_stats.find(u.uid) == last_uid_io_stats.end()) {
refresh_uid_names = true;
} else {
uid_io_stats[u.uid].name = last_uid_io_stats[u.uid].name;
}
}
if (refresh_uid) {
packagelist_parse(packagelist_parse_cb, &uid_io_stats);
if (!uids.empty() && refresh_uid_names) {
get_uid_names(uids, uid_names);
}
return uid_io_stats;
@ -228,13 +254,13 @@ void uid_monitor::update_curr_io_stats_locked()
last_uid_io_stats[uid.uid].io[BACKGROUND].write_bytes;
usage.bytes[READ][FOREGROUND][charger_stat] +=
(fg_rd_delta < 0) ? uid.io[FOREGROUND].read_bytes : fg_rd_delta;
(fg_rd_delta < 0) ? 0 : fg_rd_delta;
usage.bytes[READ][BACKGROUND][charger_stat] +=
(bg_rd_delta < 0) ? uid.io[BACKGROUND].read_bytes : bg_rd_delta;
(bg_rd_delta < 0) ? 0 : bg_rd_delta;
usage.bytes[WRITE][FOREGROUND][charger_stat] +=
(fg_wr_delta < 0) ? uid.io[FOREGROUND].write_bytes : fg_wr_delta;
(fg_wr_delta < 0) ? 0 : fg_wr_delta;
usage.bytes[WRITE][BACKGROUND][charger_stat] +=
(bg_wr_delta < 0) ? uid.io[BACKGROUND].write_bytes : bg_wr_delta;
(bg_wr_delta < 0) ? 0 : bg_wr_delta;
}
last_uid_io_stats = uid_io_stats;

View File

@ -2,6 +2,5 @@ subdirs = [
"gatekeeper",
"keymaster",
"libtrusty",
"nvram",
"storage/*",
]

View File

@ -22,6 +22,7 @@
cc_library_shared {
name: "gatekeeper.trusty",
vendor: true,
relative_install_path: "hw",
@ -43,4 +44,5 @@ cc_library_shared {
"libcutils",
"libtrusty",
],
header_libs: ["libhardware_headers"],
}

View File

@ -25,6 +25,7 @@
// and ECDSA keys.
cc_binary {
name: "trusty_keymaster_tipc",
vendor: true,
srcs: [
"trusty_keymaster_device.cpp",
"trusty_keymaster_ipc.cpp",
@ -46,6 +47,7 @@ cc_binary {
// keystore.trusty is the HAL used by keystore on Trusty devices.
cc_library_shared {
name: "keystore.trusty",
vendor: true,
relative_install_path: "hw",
srcs: [
"module.cpp",
@ -66,4 +68,5 @@ cc_library_shared {
"liblog",
"libcutils",
],
header_libs: ["libhardware_headers"],
}

View File

@ -18,6 +18,7 @@ subdirs = [
cc_library {
name: "libtrusty",
vendor: true,
srcs: ["trusty.c"],
export_include_dirs: ["include"],

View File

@ -14,12 +14,14 @@
cc_test {
name: "tipc-test",
static_executable: true,
vendor: true,
srcs: ["tipc_test.c"],
static_libs: [
"libc",
"libtrusty",
],
shared_libs: [
"libc",
"liblog",
],
gtest: false,

View File

@ -1,61 +0,0 @@
//
// Copyright (C) 2016 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.
//
// nvram.trusty is the Trusty NVRAM HAL module.
cc_library_shared {
name: "nvram.trusty",
relative_install_path: "hw",
srcs: [
"module.c",
"trusty_nvram_device.cpp",
"trusty_nvram_implementation.cpp",
],
cflags: [
"-Wall",
"-Werror",
"-Wextra",
"-fvisibility=hidden",
],
static_libs: ["libnvram-hal"],
shared_libs: [
"libtrusty",
"libnvram-messages",
"liblog",
],
}
// nvram-wipe is a helper tool for clearing NVRAM state.
cc_binary {
name: "nvram-wipe",
srcs: [
"nvram_wipe.cpp",
"trusty_nvram_implementation.cpp",
],
cflags: [
"-Wall",
"-Werror",
"-Wextra",
"-fvisibility=hidden",
],
static_libs: ["libnvram-hal"],
shared_libs: [
"libtrusty",
"libnvram-messages",
"liblog",
],
}

View File

@ -1,39 +0,0 @@
/*
* Copyright (C) 2016 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 <hardware/nvram.h>
// This function is defined in trusty_nvram_device.cpp.
int trusty_nvram_open(const hw_module_t* module,
const char* device_id,
hw_device_t** device_ptr);
static struct hw_module_methods_t nvram_module_methods = {
.open = trusty_nvram_open,
};
struct nvram_module HAL_MODULE_INFO_SYM
__attribute__((visibility("default"))) = {
.common = {.tag = HARDWARE_MODULE_TAG,
.module_api_version = NVRAM_MODULE_API_VERSION_0_1,
.hal_api_version = HARDWARE_HAL_API_VERSION,
.id = NVRAM_HARDWARE_MODULE_ID,
.name = "Trusty NVRAM HAL",
.author = "The Android Open Source Project",
.methods = &nvram_module_methods,
.dso = 0,
.reserved = {}},
};

View File

@ -1,66 +0,0 @@
/*
* Copyright (C) 2016 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 <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <nvram/messages/nvram_messages.h>
#include "trusty_nvram_implementation.h"
void usage(const char* program_name) {
fprintf(stderr, "Usage: %s [status|disable|wipe]\n", program_name);
exit(-1);
}
int main(int argc, char* argv[]) {
if (argc < 2) {
usage(argv[0]);
}
nvram::TrustyNvramImplementation nvram_proxy;
nvram::Request request;
nvram::Response response;
if (!strcmp(argv[1], "status")) {
request.payload.Activate<nvram::COMMAND_GET_INFO>();
nvram_proxy.Execute(request, &response);
const nvram::GetInfoResponse* get_info_response =
response.payload.get<nvram::COMMAND_GET_INFO>();
if (response.result == NV_RESULT_SUCCESS) {
int status = get_info_response && get_info_response->wipe_disabled;
printf("Wiping disabled: %d\n", status);
return status;
}
} else if (!strcmp(argv[1], "disable")) {
request.payload.Activate<nvram::COMMAND_DISABLE_WIPE>();
nvram_proxy.Execute(request, &response);
} else if (!strcmp(argv[1], "wipe")) {
request.payload.Activate<nvram::COMMAND_WIPE_STORAGE>();
nvram_proxy.Execute(request, &response);
} else {
usage(argv[0]);
}
if (response.result != NV_RESULT_SUCCESS) {
fprintf(stderr, "Command execution failure: %u\n", response.result);
return -1;
}
return 0;
}

View File

@ -1,34 +0,0 @@
/*
* Copyright (C) 2016 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 <errno.h>
#include <nvram/hal/nvram_device_adapter.h>
#include "trusty_nvram_implementation.h"
extern "C" int trusty_nvram_open(const hw_module_t* module,
const char* device_id,
hw_device_t** device_ptr) {
if (strcmp(NVRAM_HARDWARE_DEVICE_ID, device_id) != 0) {
return -EINVAL;
}
nvram::NvramDeviceAdapter* adapter = new nvram::NvramDeviceAdapter(
module, new nvram::TrustyNvramImplementation);
*device_ptr = adapter->as_device();
return 0;
}

View File

@ -1,113 +0,0 @@
/*
* Copyright (C) 2016 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.
*/
#define LOG_TAG "TrustyNVRAM"
#include "trusty_nvram_implementation.h"
#include <errno.h>
#include <string.h>
#include <unistd.h>
#include <hardware/nvram.h>
#include <log/log.h>
#include <trusty/tipc.h>
#include <nvram/messages/blob.h>
namespace nvram {
namespace {
// Character device to open for Trusty IPC connections.
const char kTrustyDeviceName[] = "/dev/trusty-ipc-dev0";
// App identifier of the NVRAM app.
const char kTrustyNvramAppId[] = "com.android.trusty.nvram";
} // namespace
TrustyNvramImplementation::~TrustyNvramImplementation() {
if (tipc_nvram_fd_ != -1) {
tipc_close(tipc_nvram_fd_);
tipc_nvram_fd_ = -1;
}
}
void TrustyNvramImplementation::Execute(const nvram::Request& request,
nvram::Response* response) {
if (!SendRequest(request, response)) {
response->result = NV_RESULT_INTERNAL_ERROR;
}
}
bool TrustyNvramImplementation::Connect() {
if (tipc_nvram_fd_ != -1) {
return true;
}
int rc = tipc_connect(kTrustyDeviceName, kTrustyNvramAppId);
if (rc < 0) {
ALOGE("Failed to connect to Trusty NVRAM app: %s\n", strerror(-rc));
return false;
}
tipc_nvram_fd_ = rc;
return true;
}
bool TrustyNvramImplementation::SendRequest(const nvram::Request& request,
nvram::Response* response) {
if (!Connect()) {
return false;
}
nvram::Blob request_buffer;
if (!nvram::Encode(request, &request_buffer)) {
ALOGE("Failed to encode NVRAM request.\n");
return false;
}
ssize_t rc =
write(tipc_nvram_fd_, request_buffer.data(), request_buffer.size());
if (rc < 0) {
ALOGE("Failed to send NVRAM request: %s\n", strerror(-rc));
return false;
}
if (static_cast<size_t>(rc) != request_buffer.size()) {
ALOGE("Failed to send full request buffer: %zd\n", rc);
return false;
}
rc = read(tipc_nvram_fd_, response_buffer_, sizeof(response_buffer_));
if (rc < 0) {
ALOGE("Failed to read NVRAM response: %s\n", strerror(-rc));
return false;
}
if (static_cast<size_t>(rc) >= sizeof(response_buffer_)) {
ALOGE("NVRAM response exceeds response buffer size.\n");
return false;
}
if (!nvram::Decode(response_buffer_, static_cast<size_t>(rc), response)) {
ALOGE("Failed to decode NVRAM response.\n");
return false;
}
return true;
}
} // namespace nvram

View File

@ -1,59 +0,0 @@
/*
* Copyright (C) 2016 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 TRUSTY_NVRAM_TRUSTY_NVRAM_IMPLEMENTATION_H_
#define TRUSTY_NVRAM_TRUSTY_NVRAM_IMPLEMENTATION_H_
#include <stdint.h>
#include <nvram/hal/nvram_device_adapter.h>
#include <nvram/messages/nvram_messages.h>
namespace nvram {
// |TrustyNvramImplementation| proxies requests to the Trusty NVRAM app. It
// serializes the request objects, sends it to the Trusty app and finally reads
// back the result and decodes it.
class TrustyNvramImplementation : public nvram::NvramImplementation {
public:
~TrustyNvramImplementation() override;
void Execute(const nvram::Request& request,
nvram::Response* response) override;
private:
// Connects the IPC channel to the Trusty app if it is not already open.
// Returns true if the channel is open, false on errors.
bool Connect();
// Dispatches a command to the trust app. Returns true if successful (note
// that the response may still indicate an error on the Trusty side), false if
// there are any I/O or encoding/decoding errors.
bool SendRequest(const nvram::Request& request,
nvram::Response* response);
// The file descriptor for the IPC connection to the Trusty app.
int tipc_nvram_fd_ = -1;
// Response buffer. This puts a hard size limit on the responses from the
// Trusty app. 4096 matches the maximum IPC message size currently supported
// by Trusty.
uint8_t response_buffer_[4096];
};
} // namespace nvram
#endif // TRUSTY_NVRAM_TRUSTY_NVRAM_IMPLEMENTATION_H_

View File

@ -16,5 +16,6 @@
cc_library_static {
name: "libtrustystorageinterface",
vendor: true,
export_include_dirs: ["include"],
}

View File

@ -16,16 +16,19 @@
cc_library_static {
name: "libtrustystorage",
vendor: true,
srcs: ["storage.c"],
export_include_dirs: ["include"],
static_libs: [
"liblog",
"libtrusty",
"libtrustystorageinterface",
],
shared_libs: [
"liblog",
],
cflags: [
"-fvisibility=hidden",

View File

@ -16,6 +16,7 @@
cc_binary {
name: "storageproxyd",
vendor: true,
srcs: [
"ipc.c",
@ -25,6 +26,7 @@ cc_binary {
],
shared_libs: ["liblog"],
header_libs: ["libcutils_headers"],
static_libs: [
"libtrustystorageinterface",

View File

@ -24,7 +24,7 @@
#include <sys/stat.h>
#include <unistd.h>
#include <private/android_filesystem_config.h>
#include <cutils/android_filesystem_config.h>
#include "ipc.h"
#include "log.h"

View File

@ -16,6 +16,7 @@
cc_test {
name: "secure-storage-unit-test",
vendor: true,
cflags: [
"-g",
@ -28,6 +29,8 @@ cc_test {
"libtrustystorageinterface",
"libtrustystorage",
"libtrusty",
],
shared_libs: [
"liblog",
],