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

Commit 5fca5007 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "attribute REMOTE_SUBMIX recording to RECORD_AUDIO_OUTPUT"

parents b7c71956 e69cada3
Loading
Loading
Loading
Loading
+23 −14
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@
#include <binder/IServiceManager.h>
#include <binder/PermissionCache.h>
#include "mediautils/ServiceUtilities.h"
#include <system/audio-hal-enums.h>

#include <iterator>
#include <algorithm>
@@ -61,8 +62,20 @@ static String16 resolveCallingPackage(PermissionController& permissionController
    return packages[0];
}

static int32_t getOpForSource(audio_source_t source) {
  switch (source) {
    case AUDIO_SOURCE_HOTWORD:
      return AppOpsManager::OP_RECORD_AUDIO_HOTWORD;
    case AUDIO_SOURCE_REMOTE_SUBMIX:
      return AppOpsManager::OP_RECORD_AUDIO_OUTPUT;
    case AUDIO_SOURCE_DEFAULT:
    default:
      return AppOpsManager::OP_RECORD_AUDIO;
  }
}

static bool checkRecordingInternal(const String16& opPackageName, pid_t pid,
        uid_t uid, bool start, bool isHotwordSource) {
        uid_t uid, bool start, audio_source_t source) {
    // Okay to not track in app ops as audio server or media server is us and if
    // device is rooted security model is considered compromised.
    // system_server loses its RECORD_AUDIO permission when a secondary
@@ -87,11 +100,8 @@ static bool checkRecordingInternal(const String16& opPackageName, pid_t pid,
    }

    AppOpsManager appOps;
    const int32_t opRecordAudio = appOps.permissionToOpCode(sAndroidPermissionRecordAudio);

    const int32_t op = getOpForSource(source);
    if (start) {
        const int32_t op = isHotwordSource ?
                AppOpsManager::OP_RECORD_AUDIO_HOTWORD : opRecordAudio;
        if (int32_t mode = appOps.startOpNoThrow(
                        op, uid, resolvedOpPackageName, /*startIfModeDefault*/ false);
                mode != AppOpsManager::MODE_ALLOWED) {
@@ -101,10 +111,10 @@ static bool checkRecordingInternal(const String16& opPackageName, pid_t pid,
        }
    } else {
        // Always use OP_RECORD_AUDIO for checks at creation time.
        if (int32_t mode = appOps.checkOp(opRecordAudio, uid, resolvedOpPackageName);
        if (int32_t mode = appOps.checkOp(op, uid, resolvedOpPackageName);
                mode != AppOpsManager::MODE_ALLOWED) {
            ALOGE("Request check for \"%s\" (uid %d) denied by app op: %d, mode: %d",
                    String8(resolvedOpPackageName).c_str(), uid, opRecordAudio, mode);
                    String8(resolvedOpPackageName).c_str(), uid, op, mode);
            return false;
        }
    }
@@ -113,15 +123,14 @@ static bool checkRecordingInternal(const String16& opPackageName, pid_t pid,
}

bool recordingAllowed(const String16& opPackageName, pid_t pid, uid_t uid) {
    return checkRecordingInternal(opPackageName, pid, uid, /*start*/ false,
            /*is_hotword_source*/ false);
    return checkRecordingInternal(opPackageName, pid, uid, /*start*/ false, AUDIO_SOURCE_DEFAULT);
}

bool startRecording(const String16& opPackageName, pid_t pid, uid_t uid, bool isHotwordSource) {
     return checkRecordingInternal(opPackageName, pid, uid, /*start*/ true, isHotwordSource);
bool startRecording(const String16& opPackageName, pid_t pid, uid_t uid, audio_source_t source) {
     return checkRecordingInternal(opPackageName, pid, uid, /*start*/ true, source);
}

void finishRecording(const String16& opPackageName, uid_t uid, bool isHotwordSource) {
void finishRecording(const String16& opPackageName, uid_t uid, audio_source_t source) {
    // Okay to not track in app ops as audio server is us and if
    // device is rooted security model is considered compromised.
    if (isAudioServerOrRootUid(uid)) return;
@@ -134,8 +143,8 @@ void finishRecording(const String16& opPackageName, uid_t uid, bool isHotwordSou
    }

    AppOpsManager appOps;
    const int32_t op = isHotwordSource ? AppOpsManager::OP_RECORD_AUDIO_HOTWORD
            : appOps.permissionToOpCode(sAndroidPermissionRecordAudio);

    const int32_t op = getOpForSource(source);
    appOps.finishOp(op, uid, resolvedOpPackageName);
}

+5 −3
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
#include <fcntl.h>

#include <functional>
#include  <type_traits>

#include "fuzzer/FuzzedDataProvider.h"
#include "mediautils/ServiceUtilities.h"
@@ -44,7 +45,8 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
    FuzzedDataProvider data_provider(data, size);
    uid_t uid = data_provider.ConsumeIntegral<uid_t>();
    pid_t pid = data_provider.ConsumeIntegral<pid_t>();
    bool isHotword = data_provider.ConsumeBool();
    audio_source_t source = static_cast<audio_source_t>(data_provider
        .ConsumeIntegral<std::underlying_type_t<audio_source_t>>());

    // There is not state here, and order is not significant,
    // so we can simply call all of the target functions
@@ -55,8 +57,8 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
    std::string packageNameStr = data_provider.ConsumeRandomLengthString(kMaxStringLen);
    android::String16 opPackageName(packageNameStr.c_str());
    android::recordingAllowed(opPackageName, pid, uid);
    android::startRecording(opPackageName, pid, uid, isHotword);
    android::finishRecording(opPackageName, uid, isHotword);
    android::startRecording(opPackageName, pid, uid, source);
    android::finishRecording(opPackageName, uid, source);
    android::captureAudioOutputAllowed(pid, uid);
    android::captureMediaOutputAllowed(pid, uid);
    android::captureHotwordAllowed(opPackageName, pid, uid);
+3 −2
Original line number Diff line number Diff line
@@ -24,6 +24,7 @@
#include <binder/PermissionController.h>
#include <cutils/multiuser.h>
#include <private/android_filesystem_config.h>
#include <system/audio-hal-enums.h>

#include <map>
#include <optional>
@@ -79,8 +80,8 @@ static inline bool isAudioServerOrMediaServerUid(uid_t uid) {
}

bool recordingAllowed(const String16& opPackageName, pid_t pid, uid_t uid);
bool startRecording(const String16& opPackageName, pid_t pid, uid_t uid, bool isHotwordSource);
void finishRecording(const String16& opPackageName, uid_t uid, bool isHotwordSource);
bool startRecording(const String16& opPackageName, pid_t pid, uid_t uid, audio_source_t source);
void finishRecording(const String16& opPackageName, uid_t uid, audio_source_t source);
bool captureAudioOutputAllowed(pid_t pid, uid_t uid);
bool captureMediaOutputAllowed(pid_t pid, uid_t uid);
bool captureVoiceCommunicationOutputAllowed(pid_t pid, uid_t uid);
+3 −3
Original line number Diff line number Diff line
@@ -574,7 +574,7 @@ status_t AudioPolicyService::startInput(audio_port_handle_t portId)

    // check calling permissions
    if (!(startRecording(client->opPackageName, client->pid, client->uid,
            client->attributes.source == AUDIO_SOURCE_HOTWORD)
            client->attributes.source)
            || client->attributes.source == AUDIO_SOURCE_FM_TUNER)) {
        ALOGE("%s permission denied: recording not allowed for uid %d pid %d",
                __func__, client->uid, client->pid);
@@ -663,7 +663,7 @@ status_t AudioPolicyService::startInput(audio_port_handle_t portId)
        client->startTimeNs = 0;
        updateUidStates_l();
        finishRecording(client->opPackageName, client->uid,
                        client->attributes.source == AUDIO_SOURCE_HOTWORD);
                        client->attributes.source);
    }

    return status;
@@ -690,7 +690,7 @@ status_t AudioPolicyService::stopInput(audio_port_handle_t portId)

    // finish the recording app op
    finishRecording(client->opPackageName, client->uid,
                    client->attributes.source == AUDIO_SOURCE_HOTWORD);
                    client->attributes.source);
    AutoCallerClear acc;
    return mAudioPolicyManager->stopInput(portId);
}