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

Commit 1e1d454e authored by Atneya Nair's avatar Atneya Nair Committed by Android (Google) Code Review
Browse files

Merge "Revert^2 "Migrate audioflinger package validation"" into main

parents c438c4a8 5997a651
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",
    ],
+198 −87
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,52 @@ 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];
        }
        // Behavior change: In the case of delegation, if pid is invalid,
        // filling it in with the callingPid will cause a mismatch between the
        // pid and the uid in the attribution, which is error-prone.
        // Instead, assert that the pid from a trusted source is valid
        if (attr.pid == -1) {
            if (callingUid != static_cast<uid_t>(attr.uid)) {
                return error::unexpectedExceptionCode(binder::Status::EX_ILLEGAL_ARGUMENT,
                        "validateAttribution: Invalid pid from delegating trusted source");
            } else {
                // Legacy handling for trusted clients which may not fill pid correctly
                attr.pid = IPCThreadState::self()->getCallingPid();
            }
        }
        return ValidatedAttributionSourceState::createFromTrustedSource(std::move(attr));
    } else {
        // Behavior change: Populate pid with callingPid unconditionally. Previously, we
        // allowed caller provided pid, if uid matched calling context, but this is error-prone
        // since it allows mismatching uid/pid
        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) \
@@ -519,19 +574,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) {
@@ -539,10 +597,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;
@@ -997,37 +1064,51 @@ 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 callingPid = IPCThreadState::self()->getCallingPid();
    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));
        pid_t 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();
        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();
    }

    audio_session_t sessionId = input.sessionId;
    if (sessionId == AUDIO_SESSION_ALLOCATE) {
        sessionId = (audio_session_t) newAudioUniqueId(AUDIO_UNIQUE_ID_USE_SESSION);
@@ -1079,7 +1160,7 @@ status_t AudioFlinger::createTrack(const media::CreateTrackRequest& _input,
            goto Exit;
        }

        client = registerPid(clientPid);
        client = registerPid(adjAttributionSource.pid);

        IAfPlaybackThread* effectThread = nullptr;
        sp<IAfEffectChain> effectChain = nullptr;
@@ -2199,6 +2280,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)
{
@@ -2308,8 +2395,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 = IPCThreadState::self()->getCallingPid();
    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(
@@ -2318,20 +2407,31 @@ 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();
        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();
    }

    // further format checks are performed by createRecordTrack_l()
    if (!audio_is_valid_format(input.config.format)) {
        ALOGE("createRecord() invalid format %#x", input.config.format);
@@ -4121,20 +4221,31 @@ 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 = IPCThreadState::self()->getCallingUid();
    pid_t currentPid;
    if (!com::android::media::audio::audioserver_permissions()) {
        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();
        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
@@ -407,6 +407,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
@@ -37,6 +37,10 @@

#include <optional>

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

namespace android {

class IAfDirectOutputThread;
@@ -122,6 +126,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;
@@ -10302,8 +10305,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;