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

Commit e16e891f authored by Adam Bookatz's avatar Adam Bookatz
Browse files

Revert "Prepare AttributionSource to expose to native - native"

Revert submission 14225527-bug-158792096-04/16/21-1

Reason for revert: b/186467053
Reverted Changes:
I16740cc2d:Prepare AttributionSource to expose to native - na...
I4e050e78b:Prepare AttributionSource to expose to native

Change-Id: I4cef850e28057a5e6624424dfd7575db7cc02aa8
parent 39c07530
Loading
Loading
Loading
Loading
+1 −26
Original line number Diff line number Diff line
@@ -7,42 +7,17 @@ package {
    default_applicable_licenses: ["frameworks_native_license"],
}

aidl_interface {
    name: "framework-permission-aidl",
    unstable: true,
    local_include_dir: "aidl",
    backend: {
        ndk: {
            enabled: false
        }
    },
    srcs: [
        "aidl/android/content/AttributionSourceState.aidl",
        "aidl/android/permission/IPermissionChecker.aidl",
    ],
}

cc_library_shared {
    name: "libpermission",
    cflags: [
        "-Wall",
        "-Wextra",
        "-Werror",
    ],
    srcs: [
        "AppOpsManager.cpp",
        "IAppOpsCallback.cpp",
        "IAppOpsService.cpp",
        "android/permission/PermissionChecker.cpp",
    ],
    export_include_dirs: ["include"],
    shared_libs: [
        "libutils",
        "libbinder",
        "libcutils",
        "liblog",
    ],
    static_libs: [
        "framework-permission-aidl-cpp",
        "libutils",
    ],
}
+0 −40
Original line number Diff line number Diff line
/*
 * Copyright (C) 2021 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.
 */

package android.content;

/**
 * Payload for the {@link AttributionSource} class needed to interoperate
 * with different languages.
 *
 * {@hide}
 */
parcelable AttributionSourceState {
    /** The UID that is accessing the permission protected data. */
    int uid;
    /** The package that is accessing the permission protected data. */
    @nullable @utf8InCpp String packageName;
    /** The attribution tag of the app accessing the permission protected data. */
    @nullable @utf8InCpp String attributionTag;
    /** Unique token for that source. */
    @nullable IBinder token;
    /** Permissions that should be considered revoked regardless if granted. */
    @nullable @utf8InCpp String[] renouncedPermissions;
    /** The next app to receive the permission protected data. */
    // TODO: We use an array as a workaround - the C++ backend doesn't
    // support referring to the parcelable as it expects ctor/dtor
    @nullable AttributionSourceState[] next;
}
+0 −37
Original line number Diff line number Diff line
/*
 * Copyright (C) 2021 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.
 */

package android.permission;

import android.content.AttributionSourceState;

/**
 * Interface to communicate directly with the permission checker service.
 */
interface IPermissionChecker {
    const int PERMISSION_GRANTED = 0;
    const int PERMISSION_SOFT_DENIED = 1;
    const int PERMISSION_HARD_DENIED = 2;

    int checkPermission(String permission, in AttributionSourceState attributionSource,
            @nullable String message, boolean forDataDelivery, boolean startDataDelivery,
            boolean fromDatasource);

    void finishDataDelivery(String op, in AttributionSourceState attributionSource);

    int checkOp(int op, in AttributionSourceState attributionSource,
            String message, boolean forDataDelivery, boolean startDataDelivery);
}
+0 −114
Original line number Diff line number Diff line
/*
 * Copyright (C) 2021 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 <mutex>
#include <include/android/permission/PermissionChecker.h>
#include <binder/Binder.h>
#include <binder/IServiceManager.h>

#include <utils/SystemClock.h>

#include <sys/types.h>
#include <private/android_filesystem_config.h>

#ifdef LOG_TAG
#undef LOG_TAG
#endif
#define LOG_TAG "PermissionChecker"

namespace android {

using android::content::AttributionSourceState;

PermissionChecker::PermissionChecker()
{
}

sp<IPermissionChecker> PermissionChecker::getService()
{
    static String16 permission_checker("permission_checker");

    std::lock_guard<Mutex> scoped_lock(mLock);
    int64_t startTime = 0;
    sp<IPermissionChecker> service = mService;
    while (service == nullptr || !IInterface::asBinder(service)->isBinderAlive()) {
        sp<IBinder> binder = defaultServiceManager()->checkService(permission_checker);
        if (binder == nullptr) {
            // Wait for the permission checker service to come back...
            if (startTime == 0) {
                startTime = uptimeMillis();
                ALOGW("Waiting for permission checker service");
            } else if ((uptimeMillis() - startTime) > 10000) {
                ALOGE("Waiting too long for permission checker service, giving up");
                service = nullptr;
                break;
            }
            sleep(1);
        } else {
            mService = interface_cast<IPermissionChecker>(binder);
        }
    }
    return mService;
}

PermissionChecker::PermissionResult
    PermissionChecker::checkPermissionForDataDeliveryFromDatasource(
        const String16& permission, AttributionSourceState& attributionSource,
        const String16& message)
{
    return static_cast<PermissionResult>(checkPermission(permission, attributionSource, message,
            /*forDataDelivery*/ true, /*startDataDelivery*/ false,/*fromDatasource*/ true));
}

PermissionChecker::PermissionResult
    PermissionChecker::checkPermissionForStartDataDeliveryFromDatasource(
        const String16& permission, AttributionSourceState& attributionSource,
        const String16& message)
{
    return static_cast<PermissionResult>(checkPermission(permission, attributionSource, message,
            /*forDataDelivery*/ true, /*startDataDelivery*/ true, /*fromDatasource*/ true));
}

void PermissionChecker::finishDataDelivery(const String16& op,
        AttributionSourceState& attributionSource)
{
    sp<IPermissionChecker> service = getService();
    if (service != nullptr) {
        binder::Status status = service->finishDataDelivery(op, attributionSource);
        if (!status.isOk()) {
            ALOGE("finishDataDelivery failed: %s", status.exceptionMessage().c_str());
        }
    }
}

int32_t PermissionChecker::checkPermission(const String16& permission,
        AttributionSourceState& attributionSource, const String16& message,
        bool forDataDelivery, bool startDataDelivery, bool fromDatasource)
{
    sp<IPermissionChecker> service = getService();
    if (service != nullptr) {
        int32_t result;
        binder::Status status = service->checkPermission(permission, attributionSource, message,
                forDataDelivery, startDataDelivery, fromDatasource, &result);
        if (status.isOk()) {
            return result;
        }
        ALOGE("checkPermission failed: %s", status.exceptionMessage().c_str());
    }
    return PERMISSION_DENIED;
}

} // namespace android
+0 −136
Original line number Diff line number Diff line
/*
 * Copyright (C) 2021 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/content/AttributionSourceState.h>
#include <android/permission/IPermissionChecker.h>

#include <utils/threads.h>

#include <optional>

#ifdef __ANDROID_VNDK__
#error "This header is not visible to vendors"
#endif

// ---------------------------------------------------------------------------
namespace android {

using android::content::AttributionSourceState;
using android::permission::IPermissionChecker;

class PermissionChecker
{
public:

    enum PermissionResult {

        /**
         * The permission is granted.
         */
        PERMISSION_GRANTED = IPermissionChecker::PERMISSION_GRANTED,

        /**
         * The permission is denied. Applicable only to runtime and app op permissions.
         *
         * Returned when:
         *   - the runtime permission is granted, but the corresponding app op is denied
         *       for runtime permissions.
         *   - the app ops is ignored for app op permissions.
         *
         */
        PERMISSION_SOFT_DENIED = IPermissionChecker::PERMISSION_SOFT_DENIED,

        /**
         * The permission is denied.
         *
         * Returned when:
         *  - the permission is denied for non app op permissions.
         *  - the app op is denied or app op is AppOpsManager#MODE_DEFAULT and permission is denied.
         */
        PERMISSION_HARD_DENIED = IPermissionChecker::PERMISSION_HARD_DENIED
    };

    PermissionChecker();

    /**
     * Checks whether a given data access chain described by the given attribution source
     * has a given permission and whether the app op that corresponds to this permission
     * is allowed. Call this method if you are the datasource which would not blame you for
     * access to the data since you are the data. Note that the attribution source chain
     *
     * NOTE: The attribution source should be for yourself with its next attribution
     * source being the app that would receive the data from you.
     *
     * NOTE: Use this method only for permission checks at the point where you will deliver
     * the permission protected data to clients.
     *
     * @param permission The permission to check.
     * @param attributionSource The attribution chain to check.
     * @param message A message describing the reason the permission was checked.
     * @return The permission check result which is either PERMISSION_GRANTED,
     *     or PERMISSION_SOFT_DENIED or PERMISSION_HARD_DENIED.
     */
    PermissionChecker::PermissionResult checkPermissionForDataDeliveryFromDatasource(
            const String16& permission, AttributionSourceState& attributionSource,
            const String16& message);

   /**
     * Checks whether a given data access chain described by the given attribution source
     * has a given permission and whether the app op that corresponds to this permission
     * is allowed. The app ops are also marked as started. This is useful for long running
     * permissions like camera and microphone.
     *
     * NOTE: The attribution source should be for yourself with its next attribution
     * source being the app that would receive the data from you.
     *
     * NOTE: Use this method only for permission checks at the point where you will deliver
     * the permission protected data to clients.
     *
     * @param permission The permission to check.
     * @param attributionSource The attribution chain to check.
     * @param message A message describing the reason the permission was checked.
     * @return The permission check result which is either PERMISSION_GRANTED,
     *     or PERMISSION_SOFT_DENIED or PERMISSION_HARD_DENIED.
     */
    PermissionResult checkPermissionForStartDataDeliveryFromDatasource(
            const String16& permission, AttributionSourceState& attributionSource,
            const String16& message);

    /**
     * Finishes an ongoing op for data access chain described by the given
     * attribution source.
     *
     * @param op The op to finish.
     * @param attributionSource The attribution chain for which to finish data delivery.
     */
    void finishDataDelivery(const String16& op, AttributionSourceState& attributionSource);

private:
    Mutex mLock;
    sp<IPermissionChecker> mService;
    sp<IPermissionChecker> getService();

    int32_t checkPermission(const String16& permission, AttributionSourceState& attributionSource,
            const String16& message, bool forDataDelivery, bool startDataDelivery,
            bool fromDatasource);
};


} // namespace android

// ---------------------------------------------------------------------------