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

Commit 07c665d8 authored by Atneya Nair's avatar Atneya Nair
Browse files

Migrate audioflinger package validation

Migrate audioflinger to call new attribution source package validation
methods, which don't synchronously call up to system_server.

Test: Cts and smoke tests
Bug: 338089555
Flag: com.android.media.audio.audioserver_permissions
Change-Id: If6c2629bab59f17a44fee26dbf6ebfabf37a1714
parent b05f2f13
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -213,6 +213,7 @@ cc_library {
    ],

    static_libs: [
        "audiopermissioncontroller",
        "libcpustats",
        "libpermission",
    ],
+189 −86
Original line number Diff line number Diff line
@@ -39,13 +39,17 @@
#include <binder/IServiceManager.h>
#include <binder/Parcel.h>
#include <cutils/properties.h>
#include <com_android_media_audio.h>
#include <com_android_media_audioserver.h>
#include <media/AidlConversion.h>
#include <media/AudioParameter.h>
#include <media/AudioValidator.h>
#include <media/IMediaLogService.h>
#include <media/IPermissionProvider.h>
#include <media/MediaMetricsItem.h>
#include <media/NativePermissionController.h>
#include <media/TypeConverter.h>
#include <media/ValidatedAttributionSourceState.h>
#include <mediautils/BatteryNotifier.h>
#include <mediautils/MemoryLeakTrackUtil.h>
#include <mediautils/MethodStatistics.h>
@@ -81,12 +85,17 @@
namespace android {

using ::android::base::StringPrintf;
using aidl_utils::statusTFromBinderStatus;
using media::IEffectClient;
using media::audio::common::AudioMMapPolicyInfo;
using media::audio::common::AudioMMapPolicyType;
using media::audio::common::AudioMode;
using android::content::AttributionSourceState;
using android::detail::AudioHalVersionInfo;
using com::android::media::permission::INativePermissionController;
using com::android::media::permission::IPermissionProvider;
using com::android::media::permission::NativePermissionController;
using com::android::media::permission::ValidatedAttributionSourceState;

static const AudioHalVersionInfo kMaxAAudioPropertyDeviceHalVersion =
        AudioHalVersionInfo(AudioHalVersionInfo::Type::HIDL, 7, 1);
@@ -118,6 +127,36 @@ static void sMediaLogInit()
    }
}

static error::BinderResult<ValidatedAttributionSourceState>
validateAttributionFromContextOrTrustedCaller(AttributionSourceState attr,
        const IPermissionProvider& provider) {
    const auto callingUid = IPCThreadState::self()->getCallingUid();
    // We trust the following UIDs to appropriate validated identities above us
    if (isAudioServerOrMediaServerOrSystemServerOrRootUid(callingUid)) {
        // Legacy paths may not properly populate package name, so we attempt to handle.
        if (!attr.packageName.has_value() || attr.packageName.value() == "") {
            ALOGW("Trusted client %d provided attr with missing package name" , callingUid);
            attr.packageName = VALUE_OR_RETURN(provider.getPackagesForUid(callingUid))[0];
        }
        return ValidatedAttributionSourceState::createFromTrustedSource(std::move(attr));
    } else {
        return ValidatedAttributionSourceState::createFromBinderContext(std::move(attr), provider);
    }
}

#define VALUE_OR_RETURN_CONVERTED(exp)                                                \
    ({                                                                                \
        auto _tmp = (exp);                                                            \
        if (!_tmp.ok()) {                                                             \
            ALOGE("Function: %s Line: %d Failed result (%s)", __FUNCTION__, __LINE__, \
                  errorToString(_tmp.error()).c_str());                               \
            return statusTFromBinderStatus(_tmp.error());                             \
        }                                                                             \
        std::move(_tmp.value());                                                      \
    })



// Creates association between Binder code to name for IAudioFlinger.
#define IAUDIOFLINGER_BINDER_METHOD_MACRO_LIST \
BINDER_METHOD_ENTRY(createTrack) \
@@ -516,19 +555,22 @@ status_t AudioFlinger::openMmapStream(MmapStreamInterface::stream_direction_t di
    audio_attributes_t localAttr = *attr;

    // TODO b/182392553: refactor or make clearer
    AttributionSourceState adjAttributionSource;
    if (!com::android::media::audio::audioserver_permissions()) {
        pid_t clientPid =
            VALUE_OR_RETURN_STATUS(aidl2legacy_int32_t_pid_t(client.attributionSource.pid));
        bool updatePid = (clientPid == (pid_t)-1);
        const uid_t callingUid = IPCThreadState::self()->getCallingUid();

    AttributionSourceState adjAttributionSource = client.attributionSource;
        adjAttributionSource = client.attributionSource;
        if (!isAudioServerOrMediaServerOrSystemServerOrRootUid(callingUid)) {
            uid_t clientUid =
                VALUE_OR_RETURN_STATUS(aidl2legacy_int32_t_uid_t(client.attributionSource.uid));
            ALOGW_IF(clientUid != callingUid,
                    "%s uid %d tried to pass itself off as %d",
                    __FUNCTION__, callingUid, clientUid);
        adjAttributionSource.uid = VALUE_OR_RETURN_STATUS(legacy2aidl_uid_t_int32_t(callingUid));
            adjAttributionSource.uid = VALUE_OR_RETURN_STATUS(
                    legacy2aidl_uid_t_int32_t(callingUid));
            updatePid = true;
        }
        if (updatePid) {
@@ -536,10 +578,19 @@ status_t AudioFlinger::openMmapStream(MmapStreamInterface::stream_direction_t di
            ALOGW_IF(clientPid != (pid_t)-1 && clientPid != callingPid,
                     "%s uid %d pid %d tried to pass itself off as pid %d",
                     __func__, callingUid, callingPid, clientPid);
        adjAttributionSource.pid = VALUE_OR_RETURN_STATUS(legacy2aidl_pid_t_int32_t(callingPid));
            adjAttributionSource.pid = VALUE_OR_RETURN_STATUS(
                    legacy2aidl_pid_t_int32_t(callingPid));
        }
        adjAttributionSource = afutils::checkAttributionSourcePackage(
            adjAttributionSource);
    } else {
        auto validatedAttrSource = VALUE_OR_RETURN_CONVERTED(
                validateAttributionFromContextOrTrustedCaller(client.attributionSource,
                getPermissionProvider()
                ));
        // TODO pass wrapped object around
        adjAttributionSource = std::move(validatedAttrSource).unwrapInto();
    }

    if (direction == MmapStreamInterface::DIRECTION_OUTPUT) {
        audio_config_t fullConfig = AUDIO_CONFIG_INITIALIZER;
@@ -994,37 +1045,55 @@ status_t AudioFlinger::createTrack(const media::CreateTrackRequest& _input,
    bool isSpatialized = false;
    bool isBitPerfect = false;

    // TODO b/182392553: refactor or make clearer
    pid_t clientPid =
        VALUE_OR_RETURN_STATUS(aidl2legacy_int32_t_pid_t(input.clientInfo.attributionSource.pid));
    bool updatePid = (clientPid == (pid_t)-1);
    const uid_t callingUid = IPCThreadState::self()->getCallingUid();
    uid_t clientUid =
        VALUE_OR_RETURN_STATUS(aidl2legacy_int32_t_uid_t(input.clientInfo.attributionSource.uid));
    audio_io_handle_t effectThreadId = AUDIO_IO_HANDLE_NONE;
    std::vector<int> effectIds;
    audio_attributes_t localAttr = input.attr;

    AttributionSourceState adjAttributionSource = input.clientInfo.attributionSource;
    AttributionSourceState adjAttributionSource;
    pid_t clientPid;
    pid_t callingPid;
    if (!com::android::media::audio::audioserver_permissions()) {
        adjAttributionSource = input.clientInfo.attributionSource;
        const uid_t callingUid = IPCThreadState::self()->getCallingUid();
        uid_t clientUid = VALUE_OR_RETURN_STATUS(aidl2legacy_int32_t_uid_t(
                        input.clientInfo.attributionSource.uid));
        clientPid =
            VALUE_OR_RETURN_STATUS(aidl2legacy_int32_t_pid_t(
                        input.clientInfo.attributionSource.pid));
        bool updatePid = (clientPid == (pid_t)-1);

        if (!isAudioServerOrMediaServerOrSystemServerOrRootUid(callingUid)) {
            ALOGW_IF(clientUid != callingUid,
                    "%s uid %d tried to pass itself off as %d",
                    __FUNCTION__, callingUid, clientUid);
        adjAttributionSource.uid = VALUE_OR_RETURN_STATUS(legacy2aidl_uid_t_int32_t(callingUid));
            adjAttributionSource.uid = VALUE_OR_RETURN_STATUS(
                    legacy2aidl_uid_t_int32_t(callingUid));
            clientUid = callingUid;
            updatePid = true;
        }
    const pid_t callingPid = IPCThreadState::self()->getCallingPid();
        callingPid = IPCThreadState::self()->getCallingPid();
        if (updatePid) {
            ALOGW_IF(clientPid != (pid_t)-1 && clientPid != callingPid,
                     "%s uid %d pid %d tried to pass itself off as pid %d",
                     __func__, callingUid, callingPid, clientPid);
            clientPid = callingPid;
        adjAttributionSource.pid = VALUE_OR_RETURN_STATUS(legacy2aidl_pid_t_int32_t(callingPid));
            adjAttributionSource.pid = VALUE_OR_RETURN_STATUS(
                    legacy2aidl_pid_t_int32_t(callingPid));
        }
        adjAttributionSource = afutils::checkAttributionSourcePackage(
                adjAttributionSource);

    } else {
        auto validatedAttrSource = VALUE_OR_RETURN_CONVERTED(
                validateAttributionFromContextOrTrustedCaller(input.clientInfo.attributionSource,
                getPermissionProvider()
                ));
        // TODO pass wrapped object around
        adjAttributionSource = std::move(validatedAttrSource).unwrapInto();
        clientPid = adjAttributionSource.pid;
        callingPid = adjAttributionSource.pid;
    }

    audio_session_t sessionId = input.sessionId;
    if (sessionId == AUDIO_SESSION_ALLOCATE) {
        sessionId = (audio_session_t) newAudioUniqueId(AUDIO_UNIQUE_ID_USE_SESSION);
@@ -2196,6 +2265,12 @@ void AudioFlinger::onHardError(std::set<audio_port_handle_t>& trackPortIds) {
    }
}

const IPermissionProvider& AudioFlinger::getPermissionProvider() {
    // This is inited as part of service construction, prior to binder registration,
    // so it should always be non-null.
    return mAudioPolicyServiceLocal.load()->getPermissionProvider();
}

// removeClient_l() must be called with AudioFlinger::clientMutex() held
void AudioFlinger::removeClient_l(pid_t pid)
{
@@ -2305,8 +2380,10 @@ status_t AudioFlinger::createRecord(const media::CreateRecordRequest& _input,
    output.buffers.clear();
    output.inputId = AUDIO_IO_HANDLE_NONE;

    // TODO b/182392553: refactor or clean up
    AttributionSourceState adjAttributionSource = input.clientInfo.attributionSource;
    AttributionSourceState adjAttributionSource;
    pid_t callingPid;
    if (!com::android::media::audio::audioserver_permissions()) {
        adjAttributionSource = input.clientInfo.attributionSource;
        bool updatePid = (adjAttributionSource.pid == -1);
        const uid_t callingUid = IPCThreadState::self()->getCallingUid();
        const uid_t currentUid = VALUE_OR_RETURN_STATUS(legacy2aidl_uid_t_int32_t(
@@ -2315,20 +2392,33 @@ status_t AudioFlinger::createRecord(const media::CreateRecordRequest& _input,
            ALOGW_IF(currentUid != callingUid,
                    "%s uid %d tried to pass itself off as %d",
                    __FUNCTION__, callingUid, currentUid);
        adjAttributionSource.uid = VALUE_OR_RETURN_STATUS(legacy2aidl_uid_t_int32_t(callingUid));
            adjAttributionSource.uid = VALUE_OR_RETURN_STATUS(
                    legacy2aidl_uid_t_int32_t(callingUid));
            updatePid = true;
        }
    const pid_t callingPid = IPCThreadState::self()->getCallingPid();
        callingPid = IPCThreadState::self()->getCallingPid();
        const pid_t currentPid = VALUE_OR_RETURN_STATUS(aidl2legacy_int32_t_pid_t(
                adjAttributionSource.pid));
        if (updatePid) {
            ALOGW_IF(currentPid != (pid_t)-1 && currentPid != callingPid,
                     "%s uid %d pid %d tried to pass itself off as pid %d",
                     __func__, callingUid, callingPid, currentPid);
        adjAttributionSource.pid = VALUE_OR_RETURN_STATUS(legacy2aidl_pid_t_int32_t(callingPid));
            adjAttributionSource.pid = VALUE_OR_RETURN_STATUS(
                    legacy2aidl_pid_t_int32_t(callingPid));
        }
        adjAttributionSource = afutils::checkAttributionSourcePackage(
                adjAttributionSource);
    } else {
        auto validatedAttrSource = VALUE_OR_RETURN_CONVERTED(
                validateAttributionFromContextOrTrustedCaller(
                    input.clientInfo.attributionSource,
                    getPermissionProvider()
                    ));
        // TODO pass wrapped object around
        adjAttributionSource = std::move(validatedAttrSource).unwrapInto();
        callingPid = adjAttributionSource.pid;
    }

    // further format checks are performed by createRecordTrack_l()
    if (!audio_is_valid_format(input.config.format)) {
        ALOGE("createRecord() invalid format %#x", input.config.format);
@@ -4113,20 +4203,33 @@ status_t AudioFlinger::createEffect(const media::CreateEffectRequest& request,
    int idOut = -1;

    status_t lStatus = NO_ERROR;

    // TODO b/182392553: refactor or make clearer
    const uid_t callingUid = IPCThreadState::self()->getCallingUid();
    uid_t callingUid;
    pid_t currentPid;
    if (!com::android::media::audio::audioserver_permissions()) {
        callingUid = IPCThreadState::self()->getCallingUid();
        adjAttributionSource.uid = VALUE_OR_RETURN_STATUS(legacy2aidl_uid_t_int32_t(callingUid));
    pid_t currentPid = VALUE_OR_RETURN_STATUS(aidl2legacy_int32_t_pid_t(adjAttributionSource.pid));
        currentPid = VALUE_OR_RETURN_STATUS(aidl2legacy_int32_t_pid_t(adjAttributionSource.pid));
        if (currentPid == -1 || !isAudioServerOrMediaServerOrSystemServerOrRootUid(callingUid)) {
            const pid_t callingPid = IPCThreadState::self()->getCallingPid();
            ALOGW_IF(currentPid != -1 && currentPid != callingPid,
                     "%s uid %d pid %d tried to pass itself off as pid %d",
                     __func__, callingUid, callingPid, currentPid);
        adjAttributionSource.pid = VALUE_OR_RETURN_STATUS(legacy2aidl_pid_t_int32_t(callingPid));
            adjAttributionSource.pid = VALUE_OR_RETURN_STATUS(
                    legacy2aidl_pid_t_int32_t(callingPid));
            currentPid = callingPid;
        }
        adjAttributionSource = afutils::checkAttributionSourcePackage(adjAttributionSource);
    } else {
        auto validatedAttrSource = VALUE_OR_RETURN_CONVERTED(
                validateAttributionFromContextOrTrustedCaller(request.attributionSource,
                getPermissionProvider()
                ));
        // TODO pass wrapped object around
        adjAttributionSource = std::move(validatedAttrSource).unwrapInto();
        callingUid = adjAttributionSource.uid;
        currentPid = adjAttributionSource.pid;
    }


    ALOGV("createEffect pid %d, effectClient %p, priority %d, sessionId %d, io %d, factory %p",
          adjAttributionSource.pid, effectClient.get(), priority, sessionId, io,
+2 −0
Original line number Diff line number Diff line
@@ -405,6 +405,8 @@ private:
    void onHardError(std::set<audio_port_handle_t>& trackPortIds) final
            EXCLUDES_AudioFlinger_ClientMutex;

    const ::com::android::media::permission::IPermissionProvider& getPermissionProvider() final;

    // ---- end of IAfThreadCallback interface

    /* List available audio ports and their attributes */
+7 −0
Original line number Diff line number Diff line
@@ -36,6 +36,10 @@

#include <optional>

namespace com::android::media::permission {
    class IPermissionProvider;
}

namespace android {

class IAfDirectOutputThread;
@@ -121,6 +125,9 @@ public:
            EXCLUDES_AudioFlinger_ClientMutex = 0;

    virtual void onHardError(std::set<audio_port_handle_t>& trackPortIds) = 0;

    virtual const ::com::android::media::permission::IPermissionProvider&
            getPermissionProvider() = 0;
};

class IAfThreadBase : public virtual RefBase {
+20 −2
Original line number Diff line number Diff line
@@ -72,6 +72,7 @@
#include <media/nbaio/Pipe.h>
#include <media/nbaio/PipeReader.h>
#include <media/nbaio/SourceAudioBufferProvider.h>
#include <media/ValidatedAttributionSourceState.h>
#include <mediautils/BatteryNotifier.h>
#include <mediautils/Process.h>
#include <mediautils/SchedulingPolicyService.h>
@@ -120,6 +121,8 @@ static inline T min(const T& a, const T& b)
    return a < b ? a : b;
}

using com::android::media::permission::ValidatedAttributionSourceState;

namespace android {

using audioflinger::SyncEvent;
@@ -10291,8 +10294,23 @@ status_t MmapThread::start(const AudioClient& client,
    audio_port_handle_t portId = AUDIO_PORT_HANDLE_NONE;

    audio_io_handle_t io = mId;
    const AttributionSourceState adjAttributionSource = afutils::checkAttributionSourcePackage(
    AttributionSourceState adjAttributionSource;
    if (!com::android::media::audio::audioserver_permissions()) {
        adjAttributionSource = afutils::checkAttributionSourcePackage(
                client.attributionSource);
    } else {
        // TODO(b/342475009) validate in oboeservice, and plumb downwards
        auto validatedRes = ValidatedAttributionSourceState::createFromTrustedUidNoPackage(
                    client.attributionSource,
                    mAfThreadCallback->getPermissionProvider()
                );
        if (!validatedRes.has_value()) {
            ALOGE("MMAP client package validation fail: %s",
                    validatedRes.error().toString8().c_str());
            return aidl_utils::statusTFromBinderStatus(validatedRes.error());
        }
        adjAttributionSource = std::move(validatedRes.value()).unwrapInto();
    }

    const auto localSessionId = mSessionId;
    auto localAttr = mAttr;