diff options
author | Alex Buynytskyy <alexbuy@google.com> | 2020-04-02 20:03:47 -0700 |
---|---|---|
committer | Alex Buynytskyy <alexbuy@google.com> | 2020-04-03 18:44:43 -0700 |
commit | 96e350b30d0c86ab6a3c283a796910c633249606 (patch) | |
tree | e225391b6b31c6797f5e12972cb19ca934973f5a /services/incremental/IncrementalServiceValidation.h | |
parent | b131e1b7463553f9c8147a9637c57b838542bb2a (diff) |
Disallow read logs collection if user changes their mind.
Bug: b/152633648
Test: atest PackageManagerShellCommandTest PackageManagerShellCommandIncrementalTest IncrementalServiceTest
Test: adb shell appops set 1000 GET_USAGE_STATS deny
Change-Id: I7fc8356f84fe30669483470579eedf546f81f297
Diffstat (limited to 'services/incremental/IncrementalServiceValidation.h')
-rw-r--r-- | services/incremental/IncrementalServiceValidation.h | 75 |
1 files changed, 75 insertions, 0 deletions
diff --git a/services/incremental/IncrementalServiceValidation.h b/services/incremental/IncrementalServiceValidation.h new file mode 100644 index 000000000000..24f9f7f94dfd --- /dev/null +++ b/services/incremental/IncrementalServiceValidation.h @@ -0,0 +1,75 @@ +/* + * Copyright (C) 2020 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. + */ + +#pragma once + +#include <android-base/stringprintf.h> +#include <binder/IPCThreadState.h> +#include <binder/PermissionCache.h> +#include <binder/PermissionController.h> +#include <binder/Status.h> + +namespace android::incremental { + +inline binder::Status Ok() { + return binder::Status::ok(); +} + +inline binder::Status Exception(uint32_t code, const std::string& msg) { + return binder::Status::fromExceptionCode(code, String8(msg.c_str())); +} + +inline int fromBinderStatus(const binder::Status& status) { + return status.exceptionCode() == binder::Status::EX_SERVICE_SPECIFIC + ? status.serviceSpecificErrorCode() > 0 ? -status.serviceSpecificErrorCode() + : status.serviceSpecificErrorCode() == 0 + ? -EFAULT + : status.serviceSpecificErrorCode() + : -EIO; +} + +inline binder::Status CheckPermissionForDataDelivery(const char* permission, const char* operation) { + using android::base::StringPrintf; + + int32_t pid; + int32_t uid; + + if (!PermissionCache::checkCallingPermission(String16(permission), &pid, &uid)) { + return Exception(binder::Status::EX_SECURITY, + StringPrintf("UID %d / PID %d lacks permission %s", uid, pid, permission)); + } + + // Caller must also have op granted. + PermissionController pc; + // Package is a required parameter. Need to obtain one. + Vector<String16> packages; + pc.getPackagesForUid(uid, packages); + if (packages.empty()) { + return Exception(binder::Status::EX_SECURITY, + StringPrintf("UID %d / PID %d has no packages", uid, pid)); + } + switch (auto result = pc.noteOp(String16(operation), uid, packages[0]); result) { + case PermissionController::MODE_ALLOWED: + case PermissionController::MODE_DEFAULT: + return binder::Status::ok(); + default: + return Exception(binder::Status::EX_SECURITY, + StringPrintf("UID %d / PID %d lacks app-op %s, error %d", uid, pid, + operation, result)); + } +} + +} // namespace android::incremental |