Implementing per-property access control
Test: unit tests provided, verified local build is not failing
Fix: b/33343558
Change-Id: I96d0160d1dde1e527eaba3982b0a48515e9bccd7
diff --git a/vehicle/2.0/default/Android.mk b/vehicle/2.0/default/Android.mk
index 46733e5..e61aaa3 100644
--- a/vehicle/2.0/default/Android.mk
+++ b/vehicle/2.0/default/Android.mk
@@ -22,6 +22,7 @@
include $(CLEAR_VARS)
LOCAL_MODULE := $(module_prefix)-manager-lib
LOCAL_SRC_FILES := \
+ vehicle_hal_manager/AccessControlConfigParser.cpp \
vehicle_hal_manager/SubscriptionManager.cpp \
vehicle_hal_manager/VehicleHalManager.cpp \
@@ -67,6 +68,7 @@
LOCAL_WHOLE_STATIC_LIBRARIES := $(module_prefix)-manager-lib
LOCAL_SRC_FILES:= \
+ tests/AccessControlConfigParser_test.cpp \
tests/VehicleObjectPool_test.cpp \
tests/VehiclePropConfigIndex_test.cpp \
tests/SubscriptionManager_test.cpp \
diff --git a/vehicle/2.0/default/tests/AccessControlConfigParser_test.cpp b/vehicle/2.0/default/tests/AccessControlConfigParser_test.cpp
new file mode 100644
index 0000000..92d7e39
--- /dev/null
+++ b/vehicle/2.0/default/tests/AccessControlConfigParser_test.cpp
@@ -0,0 +1,149 @@
+/*
+ * 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 <gtest/gtest.h>
+#include <memory>
+#include <fstream>
+#include <unordered_set>
+
+#include "vehicle_hal_manager/AccessControlConfigParser.h"
+
+namespace android {
+namespace hardware {
+namespace vehicle {
+namespace V2_0 {
+
+namespace {
+
+class AccessControlConfigParserTest : public ::testing::Test {
+protected:
+ void SetUp() override {
+ std::vector<VehicleProperty> supportedProperties {
+ VehicleProperty::HVAC_FAN_SPEED,
+ VehicleProperty::HVAC_FAN_DIRECTION,
+ };
+ parser.reset(new AccessControlConfigParser(supportedProperties));
+ }
+public:
+ PropertyAclMap aclMap;
+ std::unique_ptr<AccessControlConfigParser> parser;
+};
+
+TEST_F(AccessControlConfigParserTest, basicParsing) {
+ std::stringstream file;
+ file << "S:0x0500 1000 RW" << std::endl;
+
+ ASSERT_TRUE(parser->parseFromStream(&file, &aclMap));
+
+ ASSERT_EQ(1, aclMap.size());
+ auto it = aclMap.find(VehicleProperty::HVAC_FAN_SPEED);
+ ASSERT_NE(aclMap.end(), it);
+ ASSERT_EQ(VehiclePropertyAccess::READ_WRITE, it->second.access);
+ ASSERT_EQ(VehicleProperty::HVAC_FAN_SPEED, it->second.propId);
+ ASSERT_EQ(1000u, it->second.uid);
+}
+
+TEST_F(AccessControlConfigParserTest, multipleUids) {
+ std::stringstream file;
+ file << "Set AID_AUDIO 1004" << std::endl
+ << "Set AID_SYSTEM 1000" << std::endl
+ << "S:0x0500 AID_SYSTEM RW" << std::endl
+ << "S:0x0500 AID_AUDIO RW" << std::endl
+ << "S:0x0500 0xbeef R" << std::endl; // Read-only.
+
+ std::unordered_set<unsigned> expectedUids {1000, 1004, 0xbeef};
+
+ ASSERT_TRUE(parser->parseFromStream(&file, &aclMap));
+
+ auto range = aclMap.equal_range(VehicleProperty::HVAC_FAN_SPEED);
+ for (auto it = range.first; it != range.second; ++it) {
+ auto& acl = it->second;
+
+ ASSERT_EQ(1, expectedUids.count(acl.uid))
+ << " uid: " << std::hex << acl.uid;
+
+ if (acl.uid == 0xbeef) {
+ ASSERT_EQ(VehiclePropertyAccess::READ, acl.access);
+ } else {
+ ASSERT_EQ(VehiclePropertyAccess::READ_WRITE, acl.access);
+ }
+ }
+}
+
+TEST_F(AccessControlConfigParserTest, fileContainsJunk) {
+ std::stringstream file;
+ file << "This string will be ignored with warning in the log" << std::endl
+ << "# However comments are quit legitimate" << std::endl
+ << "S:0x0500 0xbeef R # YAY" << std::endl;
+
+ ASSERT_FALSE(parser->parseFromStream(&file, &aclMap));
+
+ ASSERT_EQ(1, aclMap.size());
+ auto it = aclMap.find(VehicleProperty::HVAC_FAN_SPEED);
+ ASSERT_NE(aclMap.end(), it);
+ ASSERT_EQ(VehiclePropertyAccess::READ, it->second.access);
+ ASSERT_EQ(VehicleProperty::HVAC_FAN_SPEED, it->second.propId);
+ ASSERT_EQ(0xbeef, it->second.uid);
+}
+
+TEST_F(AccessControlConfigParserTest, badIntegerFormat) {
+ std::stringstream file;
+ file << "S:0x0500 A12 RW " << std::endl;
+
+ ASSERT_FALSE(parser->parseFromStream(&file, &aclMap));
+ ASSERT_EQ(0, aclMap.size());
+}
+
+TEST_F(AccessControlConfigParserTest, ignoreNotSupportedProperties) {
+ std::stringstream file;
+ file << "S:0x0666 1000 RW " << std::endl;
+
+ ASSERT_FALSE(parser->parseFromStream(&file, &aclMap));
+ ASSERT_EQ(0, aclMap.size());
+}
+
+TEST_F(AccessControlConfigParserTest, multipleCalls) {
+ std::stringstream configFile;
+ configFile << "S:0x0500 1000 RW" << std::endl;
+
+ ASSERT_TRUE(parser->parseFromStream(&configFile, &aclMap));
+ ASSERT_EQ(1, aclMap.size());
+
+ std::stringstream configFile2;
+ configFile2 << "S:0x0501 1004 RW" << std::endl;
+ ASSERT_TRUE(parser->parseFromStream(&configFile2, &aclMap));
+ ASSERT_EQ(2, aclMap.size());
+
+ auto it = aclMap.find(VehicleProperty::HVAC_FAN_SPEED);
+ ASSERT_NE(aclMap.end(), it);
+ ASSERT_EQ(VehiclePropertyAccess::READ_WRITE, it->second.access);
+ ASSERT_EQ(VehicleProperty::HVAC_FAN_SPEED, it->second.propId);
+ ASSERT_EQ(1000u, it->second.uid);
+
+ it = aclMap.find(VehicleProperty::HVAC_FAN_DIRECTION);
+ ASSERT_NE(aclMap.end(), it);
+ ASSERT_EQ(VehiclePropertyAccess::READ_WRITE, it->second.access);
+ ASSERT_EQ(VehicleProperty::HVAC_FAN_DIRECTION, it->second.propId);
+ ASSERT_EQ(1004u, it->second.uid);
+}
+
+
+} // namespace anonymous
+
+} // namespace V2_0
+} // namespace vehicle
+} // namespace hardware
+} // namespace android
diff --git a/vehicle/2.0/default/vehicle_hal_manager/AccessControlConfigParser.cpp b/vehicle/2.0/default/vehicle_hal_manager/AccessControlConfigParser.cpp
new file mode 100644
index 0000000..1d436c5
--- /dev/null
+++ b/vehicle/2.0/default/vehicle_hal_manager/AccessControlConfigParser.cpp
@@ -0,0 +1,224 @@
+/*
+ * 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 "android.hardware.vehicle@2.0-impl"
+#include <android/log.h>
+
+#include <fstream>
+#include <sstream>
+#include <iostream>
+
+#include "AccessControlConfigParser.h"
+
+namespace android {
+namespace hardware {
+namespace vehicle {
+namespace V2_0 {
+
+AccessControlConfigParser::AccessControlConfigParser(
+ const std::vector<VehicleProperty>& properties) {
+ // Property Id in the config file doesn't include information about
+ // type and area. So we want to create a map from these kind of
+ // *stripped* properties to the whole VehicleProperty.
+ // We also want to filter out ACL to the properties that supported
+ // by concrete Vehicle HAL implementation.
+ for (VehicleProperty vehicleProperty : properties) {
+ auto numProp = static_cast<int>(vehicleProperty);
+ numProp &= ~static_cast<int>(VehiclePropertyType::MASK)
+ & ~static_cast<int>(VehicleArea::MASK);
+ mStrippedToVehiclePropertyMap.emplace(numProp, vehicleProperty);
+ }
+}
+
+bool AccessControlConfigParser::parseFromStream(
+ std::istream* stream, PropertyAclMap* propertyAclMap) {
+ std::list<std::string> tokens;
+ std::string line;
+ int lineNo = 0;
+ bool warnings = false;
+ for (;std::getline(*stream, line); lineNo++) {
+ split(line, &tokens);
+ if (!processTokens(&tokens, propertyAclMap)) {
+ warnings = true;
+ ALOGW("Failed to parse line %d : %s", lineNo, line.c_str());
+ }
+ }
+ return !warnings;
+}
+
+
+bool AccessControlConfigParser::processTokens(std::list<std::string>* tokens,
+ PropertyAclMap* propertyAclMap) {
+ std::string token = readNextToken(tokens);
+ if (token.empty() || token[0] == '#') { // Ignore comment.
+ return true;
+ }
+
+ if (token == "Set") {
+ std::string alias = readNextToken(tokens);
+ std::string strUid = readNextToken(tokens);
+ if (alias.empty() || strUid.empty()) {
+ ALOGW("Expected alias and UID must be specified");
+ return false;
+ }
+ int uid;
+ if (!parseInt(strUid.c_str(), &uid)) {
+ ALOGW("Invalid UID: %d", uid);
+ }
+ mUidMap.emplace(std::move(alias), uid);
+ } else if (token.size() > 2 && token[1] == ':') {
+ VehiclePropertyGroup propGroup;
+ if (!parsePropertyGroup(token[0], &propGroup)) {
+ return false;
+ }
+ std::string strUid = readNextToken(tokens);
+ std::string strAccess = readNextToken(tokens);
+ if (strUid.empty() || strAccess.empty()) {
+ ALOGW("Expected UID and access for property: %s",
+ token.c_str());
+ }
+
+
+ PropertyAcl acl;
+ if (parsePropertyId(token.substr(2), propGroup, &acl.propId)
+ && parseUid(strUid, &acl.uid)
+ && parseAccess(strAccess, &acl.access)) {
+ propertyAclMap->emplace(acl.propId, std::move(acl));
+ } else {
+ return false;
+ }
+ } else {
+ ALOGW("Unexpected token: %s", token.c_str());
+ return false;
+ }
+
+ return true;
+}
+
+bool AccessControlConfigParser::parsePropertyGroup(
+ char group, VehiclePropertyGroup* outPropertyGroup) const {
+ switch (group) {
+ case 'S': // Fall through.
+ case 's':
+ *outPropertyGroup = VehiclePropertyGroup::SYSTEM;
+ break;
+ case 'V': // Fall through.
+ case 'v':
+ *outPropertyGroup = VehiclePropertyGroup::VENDOR;
+ break;
+ default:
+ ALOGW("Unexpected group: %c", group);
+ return false;
+ }
+ return true;
+}
+
+bool AccessControlConfigParser::parsePropertyId(
+ const std::string& strPropId,
+ VehiclePropertyGroup propertyGroup,
+ VehicleProperty* outVehicleProperty) const {
+ int propId;
+ if (!parseInt(strPropId.c_str(), &propId)) {
+ ALOGW("Failed to convert property id to integer: %s",
+ strPropId.c_str());
+ return false;
+ }
+ propId |= static_cast<int>(propertyGroup);
+ auto it = mStrippedToVehiclePropertyMap.find(propId);
+ if (it == mStrippedToVehiclePropertyMap.end()) {
+ ALOGW("Property Id not found or not supported: 0x%x", propId);
+ return false;
+ }
+ *outVehicleProperty = it->second;
+ return true;
+}
+
+bool AccessControlConfigParser::parseInt(const char* strValue,
+ int* outIntValue) {
+ char* end;
+ long num = std::strtol(strValue, &end, 0 /* auto detect base */);
+ bool success = *end == 0 && errno != ERANGE;
+ if (success) {
+ *outIntValue = static_cast<int>(num);
+ }
+
+ return success;
+}
+
+bool AccessControlConfigParser::parseUid(const std::string& strUid,
+ unsigned* outUid) const {
+ auto element = mUidMap.find(strUid);
+ if (element != mUidMap.end()) {
+ *outUid = element->second;
+ } else {
+ int val;
+ if (!parseInt(strUid.c_str(), &val)) {
+ ALOGW("Failed to convert UID '%s' to integer", strUid.c_str());
+ return false;
+ }
+ *outUid = static_cast<unsigned>(val);
+ }
+ return true;
+}
+
+bool AccessControlConfigParser::parseAccess(
+ const std::string& strAccess, VehiclePropertyAccess* outAccess) const {
+ if (strAccess.size() == 0 || strAccess.size() > 2) {
+ ALOGW("Unknown access mode '%s'", strAccess.c_str());
+ return false;
+ }
+ int32_t access = static_cast<int32_t>(VehiclePropertyAccess::NONE);
+ for (char c : strAccess) {
+ if (c == 'R' || c == 'r') {
+ access |= VehiclePropertyAccess::READ;
+ } else if (c == 'W' || c == 'w') {
+ access |= VehiclePropertyAccess::WRITE;
+ } else {
+ ALOGW("Unknown access mode: %c", c);
+ return false;
+ }
+ }
+ *outAccess = static_cast<VehiclePropertyAccess>(access);
+ return true;
+}
+
+void AccessControlConfigParser::split(const std::string& line,
+ std::list<std::string>* outTokens) {
+ outTokens->clear();
+ std::istringstream iss(line);
+
+ while (!iss.eof()) {
+ std::string token;
+ iss >> token;
+ outTokens->push_back(std::move(token));
+ }
+}
+
+std::string AccessControlConfigParser::readNextToken(
+ std::list<std::string>* tokens) const {
+ if (tokens->empty()) {
+ return "";
+ }
+
+ std::string token = tokens->front();
+ tokens->pop_front();
+ return token;
+}
+
+} // namespace V2_0
+} // namespace vehicle
+} // namespace hardware
+} // namespace android
diff --git a/vehicle/2.0/default/vehicle_hal_manager/AccessControlConfigParser.h b/vehicle/2.0/default/vehicle_hal_manager/AccessControlConfigParser.h
new file mode 100644
index 0000000..17cbbd6
--- /dev/null
+++ b/vehicle/2.0/default/vehicle_hal_manager/AccessControlConfigParser.h
@@ -0,0 +1,110 @@
+/*
+ * 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 android_hardware_vehicle_V2_0_AccessControlConfigParser_H_
+#define android_hardware_vehicle_V2_0_AccessControlConfigParser_H_
+
+#include <string>
+#include <vector>
+#include <unordered_map>
+#include <list>
+#include <android/hardware/vehicle/2.0/types.h>
+
+namespace android {
+namespace hardware {
+namespace vehicle {
+namespace V2_0 {
+
+struct PropertyAcl {
+ VehicleProperty propId;
+ unsigned uid;
+ VehiclePropertyAccess access;
+};
+
+using PropertyAclMap = std::unordered_multimap<VehicleProperty, PropertyAcl>;
+
+/**
+ * Parser for per-property access control in vehicle HAL.
+ *
+ * It supports the following format:
+ * Set ALIAS_NAME UID
+ * {S,V}:0x0305 {ALIAS_NAME,UID} {R,W,RW}
+ *
+ * ALIAS_NAME is just an alias for UID
+ * S - for system properties (VehiclePropertyGroup::SYSTEM)
+ * V - for vendor properties (VehiclePropertyGroup::VENDOR)
+ *
+ * Example:
+ *
+ * Set AID_AUDIO 1004
+ * Set AID_MY_APP 10022
+ *
+ * S:0x0305 AID_AUDIO RW
+ * S:0x0305 10021 R
+ * V:0x0101 AID_MY_APP R
+ */
+class AccessControlConfigParser {
+public:
+ /**
+ * Creates an instance of AccessControlConfigParser
+ *
+ * @param properties - properties supported by HAL implementation
+ */
+ AccessControlConfigParser(const std::vector<VehicleProperty>& properties);
+
+ /**
+ * Parses config content from given stream and writes results to
+ * propertyAclMap.
+ */
+ bool parseFromStream(std::istream* stream, PropertyAclMap* propertyAclMap);
+
+private:
+ bool processTokens(std::list<std::string>* tokens,
+ PropertyAclMap* propertyAclMap);
+
+ bool parsePropertyGroup(char group,
+ VehiclePropertyGroup* outPropertyGroup) const;
+
+ bool parsePropertyId(const std::string& strPropId,
+ VehiclePropertyGroup propertyGroup,
+ VehicleProperty* outVehicleProperty) const;
+
+ bool parseUid(const std::string& strUid, unsigned* outUid) const;
+
+ bool parseAccess(const std::string& strAccess,
+ VehiclePropertyAccess* outAccess) const;
+
+
+ std::string readNextToken(std::list<std::string>* tokens) const;
+
+ static bool parseInt(const char* strValue, int* outIntValue);
+ static void split(const std::string& line,
+ std::list<std::string>* outTokens);
+
+private:
+ std::unordered_map<std::string, unsigned> mUidMap {}; // Contains UID
+ // aliases.
+
+ // Map property ids w/o TYPE and AREA to VehicleProperty.
+ std::unordered_map<int, VehicleProperty> mStrippedToVehiclePropertyMap;
+};
+
+} // namespace V2_0
+} // namespace vehicle
+} // namespace hardware
+} // namespace android
+
+#endif // android_hardware_vehicle_V2_0_AccessControlConfigParser_H_
diff --git a/vehicle/2.0/default/vehicle_hal_manager/VehicleHalManager.cpp b/vehicle/2.0/default/vehicle_hal_manager/VehicleHalManager.cpp
index 1260f20..267c515 100644
--- a/vehicle/2.0/default/vehicle_hal_manager/VehicleHalManager.cpp
+++ b/vehicle/2.0/default/vehicle_hal_manager/VehicleHalManager.cpp
@@ -22,6 +22,8 @@
#include <hidl/Status.h>
#include <future>
#include <bitset>
+#include <fstream>
+#include <private/android_filesystem_config.h>
#include "VehicleHalManager.h"
@@ -52,10 +54,8 @@
const_cast<VehiclePropConfig *>(halConfig.data()),
halConfig.size());
- ALOGI("getAllPropConfigs calling callback");
_hidl_cb(hidlConfigs);
- ALOGI("getAllPropConfigs done");
return Void();
}
@@ -88,7 +88,7 @@
return Void();
}
- if (!checkReadPermission(*config, getCallee())) {
+ if (!checkReadPermission(*config, getCaller())) {
_hidl_cb(StatusCode::INVALID_ARG, kEmptyValue);
return Void();
}
@@ -109,7 +109,7 @@
return StatusCode::INVALID_ARG;
}
- if (!checkWritePermission(*config, getCallee())) {
+ if (!checkWritePermission(*config, getCaller())) {
return StatusCode::INVALID_ARG;
}
@@ -194,7 +194,21 @@
_1, _2, _3));
// Initialize index with vehicle configurations received from VehicleHal.
- mConfigIndex.reset(new VehiclePropConfigIndex(mHal->listProperties()));
+ auto supportedPropConfigs = mHal->listProperties();
+ mConfigIndex.reset(new VehiclePropConfigIndex(supportedPropConfigs));
+
+ std::vector<VehicleProperty> supportedProperties(
+ supportedPropConfigs.size());
+ for (const auto& config : supportedPropConfigs) {
+ supportedProperties.push_back(config.prop);
+ }
+
+ AccessControlConfigParser aclParser(supportedProperties);
+ const char* configs[] = { "/system/etc/vehicle_access.conf",
+ "/vendor/etc/vehicle_access.conf" };
+ for (const char* filename : configs) {
+ readAndParseAclConfig(filename, &aclParser, &mPropertyAclMap);
+ }
}
VehicleHalManager::~VehicleHalManager() {
@@ -292,24 +306,43 @@
return true;
}
+bool checkAcl(const PropertyAclMap& aclMap,
+ uid_t callerUid,
+ VehicleProperty propertyId,
+ VehiclePropertyAccess requiredAccess) {
+ if (callerUid == AID_SYSTEM && isSystemProperty(propertyId)) {
+ return true;
+ }
+
+ auto range = aclMap.equal_range(propertyId);
+ for (auto it = range.first; it != range.second; ++it) {
+ auto& acl = it->second;
+ if (acl.uid == callerUid && (acl.access & requiredAccess)) {
+ return true;
+ }
+ }
+ return false;
+}
+
bool VehicleHalManager::checkWritePermission(const VehiclePropConfig &config,
- const Callee& callee) {
+ const Caller& caller) const {
if (!(config.access & VehiclePropertyAccess::WRITE)) {
ALOGW("Property 0%x has no write access", config.prop);
return false;
}
- //TODO(pavelm): check pid/uid has write access
- return true;
+ return checkAcl(mPropertyAclMap, caller.uid, config.prop,
+ VehiclePropertyAccess::WRITE);
}
bool VehicleHalManager::checkReadPermission(const VehiclePropConfig &config,
- const Callee& callee) {
+ const Caller& caller) const {
if (!(config.access & VehiclePropertyAccess::READ)) {
ALOGW("Property 0%x has no read access", config.prop);
return false;
}
- //TODO(pavelm): check pid/uid has read access
- return true;
+
+ return checkAcl(mPropertyAclMap, caller.uid, config.prop,
+ VehiclePropertyAccess::READ);
}
void VehicleHalManager::handlePropertySetEvent(const VehiclePropValue& value) {
@@ -326,13 +359,24 @@
? &mConfigIndex->getConfig(prop) : nullptr;
}
-Callee VehicleHalManager::getCallee() {
- Callee callee;
+Caller VehicleHalManager::getCaller() {
+ Caller caller;
IPCThreadState* self = IPCThreadState::self();
- callee.pid = self->getCallingPid();
- callee.uid = self->getCallingUid();
+ caller.pid = self->getCallingPid();
+ caller.uid = self->getCallingUid();
- return callee;
+ return caller;
+}
+
+void VehicleHalManager::readAndParseAclConfig(const char* filename,
+ AccessControlConfigParser* parser,
+ PropertyAclMap* outAclMap) {
+ std::ifstream file(filename);
+ if (file.is_open()) {
+ ALOGI("Parsing file: %s", filename);
+ parser->parseFromStream(&file, outAclMap);
+ file.close();
+ }
}
} // namespace V2_0
diff --git a/vehicle/2.0/default/vehicle_hal_manager/VehicleHalManager.h b/vehicle/2.0/default/vehicle_hal_manager/VehicleHalManager.h
index 8353679..cb846c9 100644
--- a/vehicle/2.0/default/vehicle_hal_manager/VehicleHalManager.h
+++ b/vehicle/2.0/default/vehicle_hal_manager/VehicleHalManager.h
@@ -29,10 +29,11 @@
#include <android/hardware/vehicle/2.0/IVehicle.h>
-#include "VehicleHal.h"
-#include "VehiclePropConfigIndex.h"
+#include "AccessControlConfigParser.h"
#include "ConcurrentQueue.h"
#include "SubscriptionManager.h"
+#include "VehicleHal.h"
+#include "VehiclePropConfigIndex.h"
#include "VehicleObjectPool.h"
namespace android {
@@ -40,7 +41,7 @@
namespace vehicle {
namespace V2_0 {
-struct Callee {
+struct Caller {
pid_t pid;
uid_t uid;
};
@@ -95,17 +96,21 @@
const VehiclePropConfig* getPropConfigOrNull(VehicleProperty prop) const;
+ bool checkWritePermission(const VehiclePropConfig &config,
+ const Caller& callee) const;
+ bool checkReadPermission(const VehiclePropConfig &config,
+ const Caller& caller) const;
+
static bool isSubscribable(const VehiclePropConfig& config,
SubscribeFlags flags);
static bool isSampleRateFixed(VehiclePropertyChangeMode mode);
static float checkSampleRate(const VehiclePropConfig& config,
float sampleRate);
- static bool checkWritePermission(const VehiclePropConfig &config,
- const Callee& callee);
- static bool checkReadPermission(const VehiclePropConfig &config,
- const Callee& callee);
+ static void readAndParseAclConfig(const char* filename,
+ AccessControlConfigParser* parser,
+ PropertyAclMap* outAclMap);
- static Callee getCallee();
+ static Caller getCaller();
private:
VehicleHal* mHal;
@@ -117,6 +122,7 @@
ConcurrentQueue<VehiclePropValuePtr> mEventQueue;
BatchingConsumer<VehiclePropValuePtr> mBatchingConsumer;
VehiclePropValuePool mValueObjectPool;
+ PropertyAclMap mPropertyAclMap;
};
} // namespace V2_0
diff --git a/vehicle/2.0/types.hal b/vehicle/2.0/types.hal
index 0e0e3ea..72fa554 100644
--- a/vehicle/2.0/types.hal
+++ b/vehicle/2.0/types.hal
@@ -2136,6 +2136,8 @@
* the expected output.
*/
enum VehiclePropertyAccess : int32_t {
+ NONE = 0x00,
+
READ = 0x01,
WRITE = 0x02,
READ_WRITE = 0x03,