Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 72aebeb3 authored by Pavel Maltsev's avatar Pavel Maltsev
Browse files

Remove dependency to libbinder in VHAL

Also, removed per property ACL as it was based on client UID

Test: mm -j ; verified Car Service works

Bug: b/36649684
Change-Id: I7625a013dda8e3ebce5b86a253a8c1befe267c11
parent 8b624737
Loading
Loading
Loading
Loading
+0 −6
Original line number Diff line number Diff line
@@ -22,7 +22,6 @@ vhal_v2_0 = android.hardware.automotive.vehicle@2.0
include $(CLEAR_VARS)
LOCAL_MODULE := $(vhal_v2_0)-manager-lib
LOCAL_SRC_FILES := \
    common/src/AccessControlConfigParser.cpp \
    common/src/SubscriptionManager.cpp \
    common/src/VehicleHalManager.cpp \
    common/src/VehicleObjectPool.cpp \
@@ -35,7 +34,6 @@ LOCAL_EXPORT_C_INCLUDE_DIRS := \
    $(LOCAL_PATH)/common/include

LOCAL_SHARED_LIBRARIES := \
    libbinder \
    libhidlbase \
    libhidltransport \
    libhwbinder \
@@ -89,7 +87,6 @@ LOCAL_WHOLE_STATIC_LIBRARIES := \

LOCAL_SHARED_LIBRARIES := \
    libbase \
    libbinder \
    libhidlbase \
    libhidltransport \
    libhwbinder \
@@ -117,7 +114,6 @@ LOCAL_WHOLE_STATIC_LIBRARIES := \
    $(vhal_v2_0)-manager-lib \

LOCAL_SRC_FILES:= \
    tests/AccessControlConfigParser_test.cpp \
    tests/RecurrentTimer_test.cpp \
    tests/SubscriptionManager_test.cpp \
    tests/VehicleHalManager_test.cpp \
@@ -125,7 +121,6 @@ LOCAL_SRC_FILES:= \
    tests/VehiclePropConfigIndex_test.cpp \

LOCAL_SHARED_LIBRARIES := \
    libbinder \
    libhidlbase \
    libhidltransport \
    libhwbinder \
@@ -153,7 +148,6 @@ LOCAL_SRC_FILES := \

LOCAL_SHARED_LIBRARIES := \
    libbase \
    libbinder \
    libhidlbase \
    libhidltransport \
    libhwbinder \
+0 −113
Original line number Diff line number Diff line
/*
 * 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_automotive_vehicle_V2_0_AccessControlConfigParser_H_
#define android_hardware_automotive_vehicle_V2_0_AccessControlConfigParser_H_

#include <string>
#include <vector>
#include <unordered_map>
#include <list>

#include <android/hardware/automotive/vehicle/2.0/types.h>

namespace android {
namespace hardware {
namespace automotive {
namespace vehicle {
namespace V2_0 {

struct PropertyAcl {
    int32_t propId;
    unsigned uid;
    VehiclePropertyAccess access;
};

using PropertyAclMap = std::unordered_multimap<int32_t, 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<int32_t>& 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,
                                int32_t* 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<int32_t, int32_t> mStrippedToVehiclePropertyMap;
};

}  // namespace V2_0
}  // namespace vehicle
}  // namespace automotive
}  // namespace hardware
}  // namespace android

#endif // android_hardware_automotive_vehicle_V2_0_AccessControlConfigParser_H_
+3 −7
Original line number Diff line number Diff line
@@ -24,7 +24,7 @@

#include <android/log.h>
#include <hidl/HidlSupport.h>
#include <hwbinder/IPCThreadState.h>
#include <utils/SortedVector.h>

#include <android/hardware/automotive/vehicle/2.0/IVehicle.h>

@@ -39,10 +39,8 @@ namespace V2_0 {

class HalClient : public android::RefBase {
public:
    HalClient(const sp<IVehicleCallback> &callback,
              int32_t pid,
              int32_t uid)
        : mCallback(callback), mPid(pid), mUid(uid) {}
    HalClient(const sp<IVehicleCallback> &callback)
        : mCallback(callback) {}

    virtual ~HalClient() {}
public:
@@ -56,8 +54,6 @@ public:

private:
    const sp<IVehicleCallback> mCallback;
    const int32_t mPid;
    const int32_t mUid;

    std::map<int32_t, SubscribeOptions> mSubscriptions;
};
+2 −22
Original line number Diff line number Diff line
@@ -27,9 +27,7 @@
#include <set>

#include <android/hardware/automotive/vehicle/2.0/IVehicle.h>
#include <hwbinder/IPCThreadState.h>

#include "AccessControlConfigParser.h"
#include "ConcurrentQueue.h"
#include "SubscriptionManager.h"
#include "VehicleHal.h"
@@ -42,11 +40,6 @@ namespace automotive {
namespace vehicle {
namespace V2_0 {

struct Caller {
    pid_t pid;
    uid_t uid;
};

/**
 * This class is a thick proxy between IVehicle HIDL interface and vendor's implementation.
 *
@@ -99,14 +92,8 @@ private:

    const VehiclePropConfig* getPropConfigOrNull(int32_t prop) const;

    bool checkWritePermission(const VehiclePropConfig &config,
                              const Caller& callee) const;
    bool checkReadPermission(const VehiclePropConfig &config,
                             const Caller& caller) const;
    bool checkAcl(uid_t callerUid,
                  int32_t propertyId,
                  VehiclePropertyAccess requiredAccess) const;

    bool checkWritePermission(const VehiclePropConfig &config) const;
    bool checkReadPermission(const VehiclePropConfig &config) const;
    void onAllClientsUnsubscribed(int32_t propertyId);

    static bool isSubscribable(const VehiclePropConfig& config,
@@ -114,12 +101,6 @@ private:
    static bool isSampleRateFixed(VehiclePropertyChangeMode mode);
    static float checkSampleRate(const VehiclePropConfig& config,
                                 float sampleRate);
    static void readAndParseAclConfig(const char* filename,
                                      AccessControlConfigParser* parser,
                                      PropertyAclMap* outAclMap);

    static Caller getCaller();

private:
    VehicleHal* mHal;
    std::unique_ptr<VehiclePropConfigIndex> mConfigIndex;
@@ -130,7 +111,6 @@ private:
    ConcurrentQueue<VehiclePropValuePtr> mEventQueue;
    BatchingConsumer<VehiclePropValuePtr> mBatchingConsumer;
    VehiclePropValuePool mValueObjectPool;
    PropertyAclMap mPropertyAclMap;
};

}  // namespace V2_0
+0 −228
Original line number Diff line number Diff line
/*
 * 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 "automotive.vehicle@2.0-impl"

#include "AccessControlConfigParser.h"
#include "VehicleUtils.h"

#include <fstream>
#include <iostream>
#include <sstream>

#include <log/log.h>

namespace android {
namespace hardware {
namespace automotive {
namespace vehicle {
namespace V2_0 {

AccessControlConfigParser::AccessControlConfigParser(
        const std::vector<int32_t>& 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 (auto prop : properties) {
        auto strippedProp = prop
                            & ~toInt(VehiclePropertyType::MASK)
                            & ~toInt(VehicleArea::MASK);
        mStrippedToVehiclePropertyMap.emplace(strippedProp, prop);
    }
}

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,
        int32_t* outVehicleProperty) const {
    int32_t 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 automotive
}  // namespace hardware
}  // namespace android
Loading