Merge "storaged: fix divide-by-zero when updating history"
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 536d64e..6b01aae 100644
--- a/fastboot/fastboot.cpp
+++ b/fastboot/fastboot.cpp
@@ -123,6 +123,7 @@
{ 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 },
+ { "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/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;
}
diff --git a/rootdir/init.usb.configfs.rc b/rootdir/init.usb.configfs.rc
index de1aab3..3a33c94 100644
--- a/rootdir/init.usb.configfs.rc
+++ b/rootdir/init.usb.configfs.rc
@@ -2,7 +2,6 @@
write /config/usb_gadget/g1/UDC "none"
stop adbd
setprop sys.usb.ffs.ready 0
- setprop sys.usb.ffs.mtp.ready 0
write /config/usb_gadget/g1/bDeviceClass 0
write /config/usb_gadget/g1/bDeviceSubClass 0
write /config/usb_gadget/g1/bDeviceProtocol 0
@@ -24,7 +23,7 @@
write /config/usb_gadget/g1/UDC ${sys.usb.controller}
setprop sys.usb.state ${sys.usb.config}
-on property:sys.usb.ffs.mtp.ready=1 && property:sys.usb.config=mtp && property:sys.usb.configfs=1
+on property:sys.usb.config=mtp && property:sys.usb.configfs=1
write /config/usb_gadget/g1/configs/b.1/strings/0x409/configuration "mtp"
symlink /config/usb_gadget/g1/functions/mtp.gs0 /config/usb_gadget/g1/configs/b.1/f1
write /config/usb_gadget/g1/UDC ${sys.usb.controller}
@@ -33,15 +32,14 @@
on property:sys.usb.config=mtp,adb && property:sys.usb.configfs=1
start adbd
-on property:sys.usb.ffs.ready=1 && property:sys.usb.ffs.mtp.ready=1 && \
-property:sys.usb.config=mtp,adb && property:sys.usb.configfs=1
+on property:sys.usb.ffs.ready=1 && property:sys.usb.config=mtp,adb && property:sys.usb.configfs=1
write /config/usb_gadget/g1/configs/b.1/strings/0x409/configuration "mtp_adb"
symlink /config/usb_gadget/g1/functions/mtp.gs0 /config/usb_gadget/g1/configs/b.1/f1
symlink /config/usb_gadget/g1/functions/ffs.adb /config/usb_gadget/g1/configs/b.1/f2
write /config/usb_gadget/g1/UDC ${sys.usb.controller}
setprop sys.usb.state ${sys.usb.config}
-on property:sys.usb.ffs.mtp.ready=1 && property:sys.usb.config=ptp && property:sys.usb.configfs=1
+on property:sys.usb.config=ptp && property:sys.usb.configfs=1
write /config/usb_gadget/g1/configs/b.1/strings/0x409/configuration "ptp"
symlink /config/usb_gadget/g1/functions/ptp.gs1 /config/usb_gadget/g1/configs/b.1/f1
write /config/usb_gadget/g1/UDC ${sys.usb.controller}
@@ -50,8 +48,7 @@
on property:sys.usb.config=ptp,adb && property:sys.usb.configfs=1
start adbd
-on property:sys.usb.ffs.ready=1 && property:sys.usb.ffs.mtp.ready=1 && \
-property:sys.usb.config=ptp,adb && property:sys.usb.configfs=1
+on property:sys.usb.ffs.ready=1 && property:sys.usb.config=ptp,adb && property:sys.usb.configfs=1
write /config/usb_gadget/g1/configs/b.1/strings/0x409/configuration "ptp_adb"
symlink /config/usb_gadget/g1/functions/ptp.gs1 /config/usb_gadget/g1/configs/b.1/f1
symlink /config/usb_gadget/g1/functions/ffs.adb /config/usb_gadget/g1/configs/b.1/f2