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

Commit 026484a7 authored by Treehugger Robot's avatar Treehugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Audioflinger permission migration" into main

parents 38ce803a 3f78993f
Loading
Loading
Loading
Loading
+102 −25
Original line number Diff line number Diff line
@@ -95,9 +95,12 @@ using media::audio::common::AudioMMapPolicyType;
using media::audio::common::AudioMode;
using android::content::AttributionSourceState;
using android::detail::AudioHalVersionInfo;
using com::android::media::audio::audioserver_permissions;
using com::android::media::permission::INativePermissionController;
using com::android::media::permission::IPermissionProvider;
using com::android::media::permission::NativePermissionController;
using com::android::media::permission::PermissionEnum;
using com::android::media::permission::PermissionEnum::MODIFY_AUDIO_SETTINGS;
using com::android::media::permission::ValidatedAttributionSourceState;

static const AudioHalVersionInfo kMaxAAudioPropertyDeviceHalVersion =
@@ -580,7 +583,7 @@ status_t AudioFlinger::openMmapStream(MmapStreamInterface::stream_direction_t di

    // TODO b/182392553: refactor or make clearer
    AttributionSourceState adjAttributionSource;
    if (!com::android::media::audio::audioserver_permissions()) {
    if (!audioserver_permissions()) {
        pid_t clientPid =
            VALUE_OR_RETURN_STATUS(aidl2legacy_int32_t_pid_t(client.attributionSource.pid));
        bool updatePid = (clientPid == (pid_t)-1);
@@ -750,6 +753,20 @@ AudioHwDevice* AudioFlinger::findSuitableHwDev_l(
    return NULL;
}

error::BinderResult<std::monostate> AudioFlinger::enforceCallingPermission(PermissionEnum perm) {
    const uid_t uid = IPCThreadState::self()->getCallingUid();
    // Due to a complicated start-up sequence, we could get a call from ourselves before APS
    // populates the permission provider (done immediately following its construction). So,
    // bail before calling into the permission provider, even though it also does this check.
    if (uid == getuid()) return {};
    const bool hasPerm = VALUE_OR_RETURN(getPermissionProvider().checkPermission(perm, uid));
    if (hasPerm) {
        return {};
    } else {
        return error::unexpectedExceptionCode(EX_SECURITY, "");
    }
}

void AudioFlinger::dumpClients_ll(int fd, bool dumpAllocators) {
    String8 result;

@@ -1129,7 +1146,7 @@ status_t AudioFlinger::createTrack(const media::CreateTrackRequest& _input,

    AttributionSourceState adjAttributionSource;
    pid_t callingPid = IPCThreadState::self()->getCallingPid();
    if (!com::android::media::audio::audioserver_permissions()) {
    if (!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(
@@ -1410,9 +1427,13 @@ status_t AudioFlinger::setMasterVolume(float value)
    }

    // check calling permissions
    if (audioserver_permissions()) {
        VALUE_OR_RETURN_CONVERTED(enforceCallingPermission(MODIFY_AUDIO_SETTINGS));
    } else {
        if (!settingsAllowed()) {
            return PERMISSION_DENIED;
        }
    }

    audio_utils::lock_guard _l(mutex());
    mMasterVolume = value;
@@ -1452,9 +1473,13 @@ status_t AudioFlinger::setMasterBalance(float balance)
    }

    // check calling permissions
    if (audioserver_permissions()) {
        VALUE_OR_RETURN_CONVERTED(enforceCallingPermission(MODIFY_AUDIO_SETTINGS));
    } else {
        if (!settingsAllowed()) {
            return PERMISSION_DENIED;
        }
    }

    // check range
    if (isnan(balance) || fabs(balance) > 1.f) {
@@ -1486,9 +1511,13 @@ status_t AudioFlinger::setMode(audio_mode_t mode)
    }

    // check calling permissions
    if (audioserver_permissions()) {
        VALUE_OR_RETURN_CONVERTED(enforceCallingPermission(MODIFY_AUDIO_SETTINGS));
    } else {
        if (!settingsAllowed()) {
            return PERMISSION_DENIED;
        }
    }
    if (uint32_t(mode) >= AUDIO_MODE_CNT) {
        ALOGW("Illegal value: setMode(%d)", mode);
        return BAD_VALUE;
@@ -1528,9 +1557,13 @@ status_t AudioFlinger::setMicMute(bool state)
    }

    // check calling permissions
     if (audioserver_permissions()) {
         VALUE_OR_RETURN_CONVERTED(enforceCallingPermission(MODIFY_AUDIO_SETTINGS));
    } else {
        if (!settingsAllowed()) {
            return PERMISSION_DENIED;
        }
    }

    audio_utils::lock_guard lock(hardwareMutex());
    if (mPrimaryHardwareDev == nullptr) {
@@ -1598,9 +1631,13 @@ status_t AudioFlinger::setMasterMute(bool muted)
    }

    // check calling permissions
    if (audioserver_permissions()) {
        VALUE_OR_RETURN_CONVERTED(enforceCallingPermission(MODIFY_AUDIO_SETTINGS));
    } else {
        if (!settingsAllowed()) {
            return PERMISSION_DENIED;
        }
    }

    audio_utils::lock_guard _l(mutex());
    mMasterMute = muted;
@@ -1685,9 +1722,13 @@ status_t AudioFlinger::setStreamVolume(audio_stream_type_t stream, float value,
        bool muted, audio_io_handle_t output)
{
    // check calling permissions
    if (audioserver_permissions()) {
        VALUE_OR_RETURN_CONVERTED(enforceCallingPermission(MODIFY_AUDIO_SETTINGS));
    } else {
        if (!settingsAllowed()) {
            return PERMISSION_DENIED;
        }
    }

    status_t status = checkStreamType(stream);
    if (status != NO_ERROR) {
@@ -1813,9 +1854,13 @@ status_t AudioFlinger::getSoundDoseInterface(const sp<media::ISoundDoseCallback>
status_t AudioFlinger::setStreamMute(audio_stream_type_t stream, bool muted)
{
    // check calling permissions
    if (audioserver_permissions()) {
        VALUE_OR_RETURN_CONVERTED(enforceCallingPermission(MODIFY_AUDIO_SETTINGS));
    } else {
        if (!settingsAllowed()) {
            return PERMISSION_DENIED;
        }
    }

    status_t status = checkStreamType(stream);
    if (status != NO_ERROR) {
@@ -1946,9 +1991,13 @@ status_t AudioFlinger::setParameters(audio_io_handle_t ioHandle, const String8&
            IPCThreadState::self()->getCallingPid(), IPCThreadState::self()->getCallingUid());

    // check calling permissions
    if (audioserver_permissions()) {
        VALUE_OR_RETURN_CONVERTED(enforceCallingPermission(MODIFY_AUDIO_SETTINGS));
    } else {
        if (!settingsAllowed()) {
            return PERMISSION_DENIED;
        }
    }

    String8 filteredKeyValuePairs = keyValuePairs;
    filterReservedParameters(filteredKeyValuePairs, IPCThreadState::self()->getCallingUid());
@@ -2188,9 +2237,13 @@ status_t AudioFlinger::setVoiceVolume(float value)
    }

    // check calling permissions
    if (audioserver_permissions()) {
        VALUE_OR_RETURN_CONVERTED(enforceCallingPermission(MODIFY_AUDIO_SETTINGS));
    } else {
        if (!settingsAllowed()) {
            return PERMISSION_DENIED;
        }
    }

    audio_utils::lock_guard lock(hardwareMutex());
    if (mPrimaryHardwareDev == nullptr) {
@@ -2458,7 +2511,7 @@ status_t AudioFlinger::createRecord(const media::CreateRecordRequest& _input,

    AttributionSourceState adjAttributionSource;
    pid_t callingPid = IPCThreadState::self()->getCallingPid();
    if (!com::android::media::audio::audioserver_permissions()) {
    if (!audioserver_permissions()) {
        adjAttributionSource = input.clientInfo.attributionSource;
        bool updatePid = (adjAttributionSource.pid == -1);
        const uid_t callingUid = IPCThreadState::self()->getCallingUid();
@@ -2689,9 +2742,19 @@ audio_module_handle_t AudioFlinger::loadHwModule(const char *name)
    if (name == NULL) {
        return AUDIO_MODULE_HANDLE_NONE;
    }
    if (audioserver_permissions()) {
        const auto res = enforceCallingPermission(MODIFY_AUDIO_SETTINGS);
        if (!res.ok()) {
            ALOGE("Function: %s perm check result (%s)", __FUNCTION__,
                  errorToString(res.error()).c_str());
            return AUDIO_MODULE_HANDLE_NONE;
        }
    } else {
        if (!settingsAllowed()) {
            return AUDIO_MODULE_HANDLE_NONE;
        }
    }

    audio_utils::lock_guard _l(mutex());
    audio_utils::lock_guard lock(hardwareMutex());
    AudioHwDevice* module = loadHwModule_ll(name);
@@ -4297,7 +4360,7 @@ status_t AudioFlinger::createEffect(const media::CreateEffectRequest& request,
    status_t lStatus = NO_ERROR;
    uid_t callingUid = IPCThreadState::self()->getCallingUid();
    pid_t currentPid;
    if (!com::android::media::audio::audioserver_permissions()) {
    if (!audioserver_permissions()) {
        adjAttributionSource.uid = VALUE_OR_RETURN_STATUS(legacy2aidl_uid_t_int32_t(callingUid));
        currentPid = VALUE_OR_RETURN_STATUS(aidl2legacy_int32_t_pid_t(adjAttributionSource.pid));
        if (currentPid == -1 || !isAudioServerOrMediaServerOrSystemServerOrRootUid(callingUid)) {
@@ -4331,9 +4394,23 @@ status_t AudioFlinger::createEffect(const media::CreateEffectRequest& request,
        goto Exit;
    }

    bool isSettingsAllowed;
    if (audioserver_permissions()) {
        const auto res = getPermissionProvider().checkPermission(
                MODIFY_AUDIO_SETTINGS,
                IPCThreadState::self()->getCallingUid());
        if (!res.ok()) {
            lStatus = statusTFromBinderStatus(res.error());
            goto Exit;
        }
        isSettingsAllowed = res.value();
    } else {
        isSettingsAllowed = settingsAllowed();
    }

    // check audio settings permission for global effects
    if (sessionId == AUDIO_SESSION_OUTPUT_MIX) {
        if (!settingsAllowed()) {
        if (!isSettingsAllowed) {
            ALOGE("%s: no permission for AUDIO_SESSION_OUTPUT_MIX", __func__);
            lStatus = PERMISSION_DENIED;
            goto Exit;
+5 −0
Original line number Diff line number Diff line
@@ -33,6 +33,7 @@
#include <audio_utils/mutex.h>
#include <audio_utils/FdToString.h>
#include <audio_utils/SimpleLog.h>
#include <com/android/media/permission/PermissionEnum.h>
#include <media/IAudioFlinger.h>
#include <media/IAudioPolicyServiceLocal.h>
#include <media/MediaMetricsItem.h>
@@ -49,6 +50,7 @@
#include <map>
#include <optional>
#include <set>
#include <variant>

namespace android {

@@ -475,6 +477,9 @@ private:
    AudioHwDevice*          findSuitableHwDev_l(audio_module_handle_t module,
            audio_devices_t deviceType) REQUIRES(mutex());

    error::BinderResult<std::monostate> enforceCallingPermission(
                    com::android::media::permission::PermissionEnum perm);

    // incremented by 2 when screen state changes, bit 0 == 1 means "off"
    // AudioFlinger::setParameters() updates with mutex().
    std::atomic_uint32_t mScreenState{};
+23 −4
Original line number Diff line number Diff line
@@ -124,6 +124,8 @@ static inline T min(const T& a, const T& b)
    return a < b ? a : b;
}

using com::android::media::audio::audioserver_permissions;
using com::android::media::permission::PermissionEnum::CAPTURE_AUDIO_HOTWORD;
using com::android::media::permission::ValidatedAttributionSourceState;
namespace audioserver_flags = com::android::media::audioserver;

@@ -9125,10 +9127,23 @@ sp<IAfRecordTrack> RecordThread::createRecordTrack_l(
    }

    if (maxSharedAudioHistoryMs != 0) {
        if (audioserver_permissions()) {
            const auto res = mAfThreadCallback->getPermissionProvider().checkPermission(
                    CAPTURE_AUDIO_HOTWORD,
                    attributionSource.uid);
            if (!res.ok()) {
                lStatus = aidl_utils::statusTFromBinderStatus(res.error());
            }
            if (!res.value()) {
                lStatus = PERMISSION_DENIED;
                goto Exit;
            }
        } else {
            if (!captureHotwordAllowed(attributionSource)) {
                lStatus = PERMISSION_DENIED;
                goto Exit;
            }
        }
        if (maxSharedAudioHistoryMs < 0
                || maxSharedAudioHistoryMs > kMaxSharedAudioHistoryMs) {
            lStatus = BAD_VALUE;
@@ -9248,7 +9263,11 @@ sp<IAfRecordTrack> RecordThread::createRecordTrack_l(
        if (!mSharedAudioPackageName.empty()
                && mSharedAudioPackageName == attributionSource.packageName
                && mSharedAudioSessionId == sessionId
                && captureHotwordAllowed(attributionSource)) {
                && (audioserver_permissions() ?
                      mAfThreadCallback->getPermissionProvider().checkPermission(
                          CAPTURE_AUDIO_HOTWORD,
                          attributionSource.uid).value_or(false)
                    : captureHotwordAllowed(attributionSource))) {
            startFrames = mSharedAudioStartFrames;
        }

+20 −3
Original line number Diff line number Diff line
@@ -30,7 +30,9 @@

#include <audio_utils/StringUtils.h>
#include <audio_utils/minifloat.h>
#include <com_android_media_audio.h>
#include <media/AudioValidator.h>
#include <media/IPermissionProvider.h>
#include <media/RecordBufferConverter.h>
#include <media/nbaio/Pipe.h>
#include <media/nbaio/PipeReader.h>
@@ -71,8 +73,11 @@ namespace android {

using ::android::aidl_utils::binderStatusFromStatusT;
using binder::Status;
using com::android::media::audio::audioserver_permissions;
using com::android::media::permission::PermissionEnum::CAPTURE_AUDIO_HOTWORD;
using content::AttributionSourceState;
using media::VolumeShaper;

// ----------------------------------------------------------------------------
//      TrackBase
// ----------------------------------------------------------------------------
@@ -3281,11 +3286,23 @@ status_t RecordTrack::shareAudioHistory(
    attributionSource.uid = VALUE_OR_RETURN_STATUS(legacy2aidl_uid_t_int32_t(callingUid));
    attributionSource.pid = VALUE_OR_RETURN_STATUS(legacy2aidl_uid_t_int32_t(callingPid));
    attributionSource.token = sp<BBinder>::make();
    const sp<IAfThreadBase> thread = mThread.promote();
    if (audioserver_permissions()) {
        const auto res = thread->afThreadCallback()->getPermissionProvider().checkPermission(
                    CAPTURE_AUDIO_HOTWORD,
                    attributionSource.uid);
            if (!res.ok()) {
                return aidl_utils::statusTFromBinderStatus(res.error());
            }
            if (!res.value()) {
                return PERMISSION_DENIED;
            }
    } else {
        if (!captureHotwordAllowed(attributionSource)) {
            return PERMISSION_DENIED;
        }
    }

    const sp<IAfThreadBase> thread = mThread.promote();
    if (thread != 0) {
        auto* const recordThread = thread->asIAfRecordThread().get();
        status_t status = recordThread->shareAudioHistory(