Merge "Add "require partition-exists=" support."
diff --git a/adb/Android.bp b/adb/Android.bp
index bbf7cb4..d81bb4b 100644
--- a/adb/Android.bp
+++ b/adb/Android.bp
@@ -72,8 +72,17 @@
"-DUNICODE=1",
"-D_UNICODE=1",
- // -std=gnu++14 doesn't set _GNU_SOURCE on Windows.
+ // -std=gnu++11 doesn't set _GNU_SOURCE on Windows.
"-D_GNU_SOURCE",
+
+ // MinGW hides some things behind _POSIX_SOURCE.
+ "-D_POSIX_SOURCE",
+ ],
+
+ host_ldlibs: [
+ "-lws2_32",
+ "-lgdi32",
+ "-luserenv",
],
},
},
@@ -173,6 +182,13 @@
"libdiagnose_usb",
"libusb",
],
+
+ target: {
+ windows: {
+ enabled: true,
+ shared_libs: ["AdbWinApi"],
+ },
+ },
}
cc_binary_host {
@@ -220,11 +236,6 @@
windows: {
enabled: true,
ldflags: ["-municode"],
- host_ldlibs: [
- "-lws2_32",
- "-lgdi32",
- ],
-
shared_libs: ["AdbWinApi"],
required: [
"AdbWinUsbApi",
diff --git a/adb/daemon/usb.cpp b/adb/daemon/usb.cpp
index c58c67a..ab11bdd 100644
--- a/adb/daemon/usb.cpp
+++ b/adb/daemon/usb.cpp
@@ -269,7 +269,7 @@
if (h->control < 0) { // might have already done this before
LOG(INFO) << "opening control endpoint " << USB_FFS_ADB_EP0;
- h->control = adb_open(USB_FFS_ADB_EP0, O_RDWR);
+ h->control = adb_open(USB_FFS_ADB_EP0, O_WRONLY);
if (h->control < 0) {
PLOG(ERROR) << "cannot open control endpoint " << USB_FFS_ADB_EP0;
goto err;
@@ -300,13 +300,13 @@
android::base::SetProperty("sys.usb.ffs.ready", "1");
}
- h->bulk_out = adb_open(USB_FFS_ADB_OUT, O_RDWR);
+ h->bulk_out = adb_open(USB_FFS_ADB_OUT, O_RDONLY);
if (h->bulk_out < 0) {
PLOG(ERROR) << "cannot open bulk-out endpoint " << USB_FFS_ADB_OUT;
goto err;
}
- h->bulk_in = adb_open(USB_FFS_ADB_IN, O_RDWR);
+ h->bulk_in = adb_open(USB_FFS_ADB_IN, O_WRONLY);
if (h->bulk_in < 0) {
PLOG(ERROR) << "cannot open bulk-in endpoint " << USB_FFS_ADB_IN;
goto err;
diff --git a/adb/fdevent_test.cpp b/adb/fdevent_test.cpp
index 95dc4c2..e3d5a35 100644
--- a/adb/fdevent_test.cpp
+++ b/adb/fdevent_test.cpp
@@ -26,6 +26,7 @@
#include "adb_io.h"
#include "fdevent_test.h"
+#include "sysdeps/memory.h"
class FdHandler {
public:
diff --git a/adb/sysdeps.h b/adb/sysdeps.h
index fd08ad8..3be99f6 100644
--- a/adb/sysdeps.h
+++ b/adb/sysdeps.h
@@ -106,14 +106,14 @@
#define mkdir ___xxx_mkdir
// See the comments for the !defined(_WIN32) versions of adb_*().
-extern int adb_open(const char* path, int options);
-extern int adb_creat(const char* path, int mode);
-extern int adb_read(int fd, void* buf, int len);
-extern int adb_write(int fd, const void* buf, int len);
-extern int adb_lseek(int fd, int pos, int where);
-extern int adb_shutdown(int fd);
-extern int adb_close(int fd);
-extern int adb_register_socket(SOCKET s);
+extern int adb_open(const char* path, int options);
+extern int adb_creat(const char* path, int mode);
+extern int adb_read(int fd, void* buf, int len);
+extern int adb_write(int fd, const void* buf, int len);
+extern int adb_lseek(int fd, int pos, int where);
+extern int adb_shutdown(int fd, int direction = SHUT_RDWR);
+extern int adb_close(int fd);
+extern int adb_register_socket(SOCKET s);
// See the comments for the !defined(_WIN32) version of unix_close().
static __inline__ int unix_close(int fd)
@@ -414,14 +414,10 @@
#undef open
#define open ___xxx_open
-static __inline__ int adb_shutdown(int fd)
-{
- return shutdown(fd, SHUT_RDWR);
-}
-static __inline__ int adb_shutdown(int fd, int direction)
-{
+static __inline__ int adb_shutdown(int fd, int direction = SHUT_RDWR) {
return shutdown(fd, direction);
}
+
#undef shutdown
#define shutdown ____xxx_shutdown
diff --git a/adb/sysdeps_win32.cpp b/adb/sysdeps_win32.cpp
index cd7d187..62f4ac8 100644
--- a/adb/sysdeps_win32.cpp
+++ b/adb/sysdeps_win32.cpp
@@ -1011,9 +1011,8 @@
return ntohs(reinterpret_cast<sockaddr_in*>(&addr_storage)->sin_port);
}
-int adb_shutdown(int fd)
-{
- FH f = _fh_from_int(fd, __func__);
+int adb_shutdown(int fd, int direction) {
+ FH f = _fh_from_int(fd, __func__);
if (!f || f->clazz != &_fh_socket_class) {
D("adb_shutdown: invalid fd %d", fd);
@@ -1021,8 +1020,8 @@
return -1;
}
- D( "adb_shutdown: %s", f->name);
- if (shutdown(f->fh_socket, SD_BOTH) == SOCKET_ERROR) {
+ D("adb_shutdown: %s", f->name);
+ if (shutdown(f->fh_socket, direction) == SOCKET_ERROR) {
const DWORD err = WSAGetLastError();
D("socket shutdown fd %d failed: %s", fd,
android::base::SystemErrorCodeToString(err).c_str());
diff --git a/base/include/android-base/scopeguard.h b/base/include/android-base/scopeguard.h
index abcf4bc..c314e02 100644
--- a/base/include/android-base/scopeguard.h
+++ b/base/include/android-base/scopeguard.h
@@ -17,20 +17,27 @@
#ifndef ANDROID_BASE_SCOPEGUARD_H
#define ANDROID_BASE_SCOPEGUARD_H
-#include <utility> // for std::move
+#include <utility> // for std::move, std::forward
namespace android {
namespace base {
+// ScopeGuard ensures that the specified functor is executed no matter how the
+// current scope exits.
template <typename F>
class ScopeGuard {
public:
- ScopeGuard(F f) : f_(f), active_(true) {}
+ ScopeGuard(F&& f) : f_(std::forward<F>(f)), active_(true) {}
ScopeGuard(ScopeGuard&& that) : f_(std::move(that.f_)), active_(that.active_) {
that.active_ = false;
}
+ template <typename Functor>
+ ScopeGuard(ScopeGuard<Functor>&& that) : f_(std::move(that.f_)), active_(that.active_) {
+ that.active_ = false;
+ }
+
~ScopeGuard() {
if (active_) f_();
}
@@ -45,13 +52,16 @@
bool active() const { return active_; }
private:
+ template <typename Functor>
+ friend class ScopeGuard;
+
F f_;
bool active_;
};
-template <typename T>
-ScopeGuard<T> make_scope_guard(T f) {
- return ScopeGuard<T>(f);
+template <typename F>
+ScopeGuard<F> make_scope_guard(F&& f) {
+ return ScopeGuard<F>(std::forward<F>(f));
}
} // namespace base
diff --git a/base/scopeguard_test.cpp b/base/scopeguard_test.cpp
index e11154a..9236d7b 100644
--- a/base/scopeguard_test.cpp
+++ b/base/scopeguard_test.cpp
@@ -17,6 +17,7 @@
#include "android-base/scopeguard.h"
#include <utility>
+#include <vector>
#include <gtest/gtest.h>
@@ -44,3 +45,15 @@
EXPECT_FALSE(scopeguard.active());
ASSERT_FALSE(guarded_var);
}
+
+TEST(scopeguard, vector) {
+ int guarded_var = 0;
+ {
+ std::vector<android::base::ScopeGuard<std::function<void()>>> scopeguards;
+ scopeguards.emplace_back(android::base::make_scope_guard(
+ std::bind([](int& guarded_var) { guarded_var++; }, std::ref(guarded_var))));
+ scopeguards.emplace_back(android::base::make_scope_guard(
+ std::bind([](int& guarded_var) { guarded_var++; }, std::ref(guarded_var))));
+ }
+ ASSERT_EQ(guarded_var, 2);
+}
diff --git a/fastboot/fastboot.cpp b/fastboot/fastboot.cpp
index 4089490..237f081 100644
--- a/fastboot/fastboot.cpp
+++ b/fastboot/fastboot.cpp
@@ -123,6 +123,8 @@
{ nullptr, "boot_other.img", "boot.sig", "boot", true, true },
{ "dtbo", "dtbo.img", "dtbo.sig", "dtbo", true, false },
{ "dts", "dt.img", "dt.sig", "dts", true, false },
+ { "odm", "odm.img", "odm.sig", "odm", true, false },
+ { "product", "product.img", "product.sig", "product", true, false },
{ "recovery", "recovery.img", "recovery.sig", "recovery", true, false },
{ "system", "system.img", "system.sig", "system", false, false },
{ nullptr, "system_other.img", "system.sig", "system", true, true },
diff --git a/init/stable_properties.h b/init/stable_properties.h
index bd568f0..c8bdaa4 100644
--- a/init/stable_properties.h
+++ b/init/stable_properties.h
@@ -37,6 +37,7 @@
"persist.sys.zram_enabled",
"ro.bootmode",
"ro.build.type",
+ "ro.debuggable",
"sys.boot_completed",
"sys.retaildemo.enabled",
"sys.shutdown.requested",
diff --git a/libbacktrace/UnwindStack.cpp b/libbacktrace/UnwindStack.cpp
index 711a12a..e087b2e 100644
--- a/libbacktrace/UnwindStack.cpp
+++ b/libbacktrace/UnwindStack.cpp
@@ -163,6 +163,9 @@
}
std::vector<std::string> skip_names{"libunwindstack.so", "libbacktrace.so"};
+ if (!skip_frames_) {
+ skip_names.clear();
+ }
return Backtrace::Unwind(regs.get(), GetMap(), &frames_, num_ignore_frames, &skip_names, &error_);
}
diff --git a/libbacktrace/backtrace_test.cpp b/libbacktrace/backtrace_test.cpp
index aab6db9..1e3d379 100644
--- a/libbacktrace/backtrace_test.cpp
+++ b/libbacktrace/backtrace_test.cpp
@@ -69,6 +69,9 @@
// Number of simultaneous threads running in our forked process.
#define NUM_PTRACE_THREADS 5
+// The list of shared libaries that make up the backtrace library.
+static std::vector<std::string> kBacktraceLibs{"libunwindstack.so", "libbacktrace.so"};
+
struct thread_t {
pid_t tid;
int32_t state;
@@ -256,16 +259,49 @@
VERIFY_NO_ERROR(backtrace->GetError().error_code);
ASSERT_TRUE(backtrace->NumFrames() != 0);
+ // None of the frames should be in the backtrace libraries.
for (const auto& frame : *backtrace ) {
if (BacktraceMap::IsValid(frame.map)) {
const std::string name = basename(frame.map.name.c_str());
- ASSERT_TRUE(name != "libunwind.so" && name != "libbacktrace.so")
- << DumpFrames(backtrace.get());
+ for (const auto& lib : kBacktraceLibs) {
+ ASSERT_TRUE(name != lib) << DumpFrames(backtrace.get());
+ }
}
- break;
}
}
+TEST(libbacktrace, local_unwind_frames) {
+ // Verify that a local unwind with the skip frames disabled does include
+ // frames within the backtrace libraries.
+ std::unique_ptr<Backtrace> backtrace(Backtrace::Create(getpid(), getpid()));
+ ASSERT_TRUE(backtrace.get() != nullptr);
+ backtrace->SetSkipFrames(false);
+ ASSERT_TRUE(backtrace->Unwind(0));
+ VERIFY_NO_ERROR(backtrace->GetError().error_code);
+
+ ASSERT_TRUE(backtrace->NumFrames() != 0);
+ size_t first_frame_non_backtrace_lib = 0;
+ for (const auto& frame : *backtrace) {
+ if (BacktraceMap::IsValid(frame.map)) {
+ const std::string name = basename(frame.map.name.c_str());
+ bool found = false;
+ for (const auto& lib : kBacktraceLibs) {
+ if (name == lib) {
+ found = true;
+ break;
+ }
+ }
+ if (!found) {
+ first_frame_non_backtrace_lib = frame.num;
+ break;
+ }
+ }
+ }
+
+ ASSERT_NE(0U, first_frame_non_backtrace_lib) << "No frames found in backtrace libraries:\n"
+ << DumpFrames(backtrace.get());
+}
+
TEST(libbacktrace, local_trace) {
ASSERT_NE(test_level_one(1, 2, 3, 4, VerifyLevelBacktrace, nullptr), 0);
}
diff --git a/libbacktrace/include/backtrace/Backtrace.h b/libbacktrace/include/backtrace/Backtrace.h
index a088207..735a2f3 100644
--- a/libbacktrace/include/backtrace/Backtrace.h
+++ b/libbacktrace/include/backtrace/Backtrace.h
@@ -204,6 +204,9 @@
std::string GetErrorString(BacktraceUnwindError error);
+ // Set whether to skip frames in libbacktrace/libunwindstack when doing a local unwind.
+ void SetSkipFrames(bool skip_frames) { skip_frames_ = skip_frames; }
+
protected:
Backtrace(pid_t pid, pid_t tid, BacktraceMap* map);
@@ -223,6 +226,9 @@
std::vector<backtrace_frame_data_t> frames_;
+ // Skip frames in libbacktrace/libunwindstack when doing a local unwind.
+ bool skip_frames_ = true;
+
BacktraceUnwindError error_;
};
diff --git a/libcutils/include/cutils/trace.h b/libcutils/include/cutils/trace.h
index b2779b2..bbb150d 100644
--- a/libcutils/include/cutils/trace.h
+++ b/libcutils/include/cutils/trace.h
@@ -73,7 +73,8 @@
#define ATRACE_TAG_NETWORK (1<<21)
#define ATRACE_TAG_ADB (1<<22)
#define ATRACE_TAG_VIBRATOR (1<<23)
-#define ATRACE_TAG_LAST ATRACE_TAG_VIBRATOR
+#define ATRACE_TAG_AIDL (1<<24)
+#define ATRACE_TAG_LAST ATRACE_TAG_AIDL
// Reserved for initialization.
#define ATRACE_TAG_NOT_READY (1ULL<<63)
diff --git a/property_service/property_info_checker/Android.bp b/property_service/property_info_checker/Android.bp
index 6ee649a..7d66199 100644
--- a/property_service/property_info_checker/Android.bp
+++ b/property_service/property_info_checker/Android.bp
@@ -7,6 +7,7 @@
"libpropertyinfoserializer",
"libpropertyinfoparser",
"libbase",
+ "libsepol",
],
srcs: ["property_info_checker.cpp"],
}
diff --git a/property_service/property_info_checker/property_info_checker.cpp b/property_service/property_info_checker/property_info_checker.cpp
index e4f8264..52c4383 100644
--- a/property_service/property_info_checker/property_info_checker.cpp
+++ b/property_service/property_info_checker/property_info_checker.cpp
@@ -1,26 +1,150 @@
#include <iostream>
+#include <memory>
#include <string>
#include <vector>
#include <android-base/file.h>
-
+#include <property_info_parser/property_info_parser.h>
#include <property_info_serializer/property_info_serializer.h>
+#include <sepol/context.h>
+#include <sepol/context_record.h>
+#include <sepol/handle.h>
+#include <sepol/policydb.h>
+#include <sepol/policydb/policydb.h>
using android::base::ReadFileToString;
using android::properties::BuildTrie;
using android::properties::ParsePropertyInfoFile;
+using android::properties::PropertyInfoArea;
using android::properties::PropertyInfoEntry;
+class ContextChecker {
+ public:
+ ContextChecker()
+ : policy_file_(nullptr),
+ sepol_handle_(nullptr),
+ sepol_policy_file_(nullptr),
+ sepol_policy_db_(nullptr) {}
+
+ ~ContextChecker() {
+ if (sepol_policy_db_ != nullptr) {
+ sepol_policydb_free(sepol_policy_db_);
+ }
+
+ if (sepol_policy_file_ != nullptr) {
+ sepol_policy_file_free(sepol_policy_file_);
+ }
+
+ if (sepol_handle_ != nullptr) {
+ sepol_handle_destroy(sepol_handle_);
+ }
+
+ if (policy_file_ != nullptr) {
+ fclose(policy_file_);
+ }
+ }
+
+ bool Initialize(const char* policy_file) {
+ policy_file_ = fopen(policy_file, "re");
+ if (policy_file_ == nullptr) {
+ std::cerr << "Could not open policy file, " << policy_file << std::endl;
+ return false;
+ }
+
+ sepol_handle_ = sepol_handle_create();
+ if (sepol_handle_ == nullptr) {
+ std::cerr << "Could not create policy handle." << std::endl;
+ return false;
+ }
+
+ if (sepol_policy_file_create(&sepol_policy_file_) < 0) {
+ std::cerr << "Could not create policy file." << std::endl;
+ return false;
+ }
+
+ if (sepol_policydb_create(&sepol_policy_db_) < 0) {
+ std::cerr << "Could not create policy db." << std::endl;
+ return false;
+ }
+
+ sepol_policy_file_set_fp(sepol_policy_file_, policy_file_);
+ sepol_policy_file_set_handle(sepol_policy_file_, sepol_handle_);
+
+ if (sepol_policydb_read(sepol_policy_db_, sepol_policy_file_) < 0) {
+ std::cerr << "Could not read policy file into policy db." << std::endl;
+ return false;
+ }
+
+ auto* attr =
+ reinterpret_cast<type_datum*>(hashtab_search(policy_db_->p_types.table, "property_type"));
+ if (attr == nullptr || attr->flavor != TYPE_ATTRIB) {
+ std::cerr << "'property_type' is not defined correctly." << std::endl;
+ return false;
+ }
+
+ property_type_bit_ = attr->s.value - 1;
+
+ return true;
+ }
+
+ bool CheckContext(const char* context) {
+ sepol_context_t* sepol_context_raw;
+ if (sepol_context_from_string(sepol_handle_, context, &sepol_context_raw) < 0) {
+ std::cerr << "Could not allocate context for " << context << std::endl;
+ return false;
+ }
+ auto sepol_context = std::unique_ptr<sepol_context_t, decltype(&sepol_context_free)>{
+ sepol_context_raw, sepol_context_free};
+
+ if (sepol_context_check(sepol_handle_, sepol_policy_db_, sepol_context.get()) < 0) {
+ std::cerr << "Sepol context check failed for " << context << std::endl;
+ return false;
+ }
+
+ const char* context_type = sepol_context_get_type(sepol_context.get());
+
+ auto* type =
+ reinterpret_cast<type_datum*>(hashtab_search(policy_db_->p_types.table, context_type));
+ if (type == nullptr) {
+ std::cerr << "Could not find context '" << context << "' in policy database" << std::endl;
+ return false;
+ }
+
+ if (type->flavor != TYPE_TYPE) {
+ std::cerr << "Context '" << context << "' is not defined as a type in policy database"
+ << std::endl;
+ return false;
+ }
+
+ if (!ebitmap_get_bit(&policy_db_->type_attr_map[type->s.value - 1], property_type_bit_)) {
+ std::cerr << "Context '" << context << "' does not have property_type attribute" << std::endl;
+ return false;
+ }
+
+ return true;
+ }
+
+ private:
+ FILE* policy_file_;
+ sepol_handle_t* sepol_handle_;
+ sepol_policy_file_t* sepol_policy_file_;
+ union {
+ sepol_policydb_t* sepol_policy_db_;
+ policydb_t* policy_db_;
+ };
+ unsigned int property_type_bit_;
+};
+
int main(int argc, char** argv) {
- if (argc < 2) {
- std::cerr << "A list of property info files to be checked is expected on the command line"
- << std::endl;
+ if (argc < 3) {
+ std::cerr << "usage: " << argv[0]
+ << " COMPILED_SEPOLICY PROPERTY_INFO_FILE [PROPERTY_INFO_FILE]..." << std::endl;
return -1;
}
auto property_info_entries = std::vector<PropertyInfoEntry>{};
- for (int i = 1; i < argc; ++i) {
+ for (int i = 2; i < argc; ++i) {
auto filename = argv[i];
auto file_contents = std::string{};
if (!ReadFileToString(filename, &file_contents)) {
@@ -47,5 +171,17 @@
return -1;
}
+ auto checker = ContextChecker{};
+ if (!checker.Initialize(argv[1])) {
+ return -1;
+ }
+
+ auto property_info_area = reinterpret_cast<PropertyInfoArea*>(serialized_contexts.data());
+ for (size_t i = 0; i < property_info_area->num_contexts(); ++i) {
+ if (!checker.CheckContext(property_info_area->context(i))) {
+ return -1;
+ }
+ }
+
return 0;
}