diff options
| -rw-r--r-- | services/core/java/com/android/server/audio/AudioService.java | 61 | ||||
| -rw-r--r-- | services/core/java/com/android/server/audio/HardeningEnforcer.java | 62 |
2 files changed, 87 insertions, 36 deletions
diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java index 6b16b131ce0d..54b33c3f6c69 100644 --- a/services/core/java/com/android/server/audio/AudioService.java +++ b/services/core/java/com/android/server/audio/AudioService.java @@ -844,23 +844,6 @@ public class AudioService extends IAudioService.Stub "media_audio.value_audio_playback_hardening_partial_restriction"; static final String METRIC_COUNTERS_PLAYBACK_STRICT = "media_audio.value_audio_playback_hardening_strict_would_restrict"; - - String getPackNameForUid(int uid) { - final long token = Binder.clearCallingIdentity(); - try { - final String[] names = AudioService.this.mContext. - getPackageManager().getPackagesForUid(uid); - if (names == null - || names.length == 0 - || TextUtils.isEmpty(names[0])) { - return "[" + uid + "]"; - } - return names[0]; - } finally { - Binder.restoreCallingIdentity(token); - } - } - // oneway @Override public void playbackHardeningEvent(int uid, byte type, boolean bypassed) { @@ -878,7 +861,7 @@ public class AudioService extends IAudioService.Stub String msg = "AudioHardening background playback " + (bypassed ? "would be " : "") + "muted for " - + getPackNameForUid(uid) + " (" + uid + "), " + + getPackageNameForUid(uid) + " (" + uid + "), " + "level: " + (type == HardeningType.PARTIAL ? "partial" : "full"); AudioService.this.mHardeningLogger.enqueueAndSlog(msg, @@ -1604,7 +1587,9 @@ public class AudioService extends IAudioService.Stub mMusicFxHelper = new MusicFxHelper(mContext, mAudioHandler); - mHardeningEnforcer = new HardeningEnforcer(mContext, isPlatformAutomotive(), mAppOps, + mHardeningEnforcer = new HardeningEnforcer(mContext, isPlatformAutomotive(), + mShouldEnableAllHardening, + mAppOps, context.getPackageManager(), mHardeningLogger); } @@ -3898,7 +3883,9 @@ public class AudioService extends IAudioService.Stub public void adjustStreamVolumeWithAttribution(int streamType, int direction, int flags, String callingPackage, String attributionTag) { if (mHardeningEnforcer.blockVolumeMethod( - HardeningEnforcer.METHOD_AUDIO_MANAGER_ADJUST_STREAM_VOLUME)) { + HardeningEnforcer.METHOD_AUDIO_MANAGER_ADJUST_STREAM_VOLUME, + callingPackage, + Binder.getCallingUid())) { return; } if ((streamType == AudioManager.STREAM_ACCESSIBILITY) && !canChangeAccessibilityVolume()) { @@ -4659,7 +4646,9 @@ public class AudioService extends IAudioService.Stub public void setStreamVolumeWithAttribution(int streamType, int index, int flags, String callingPackage, String attributionTag) { if (mHardeningEnforcer.blockVolumeMethod( - HardeningEnforcer.METHOD_AUDIO_MANAGER_SET_STREAM_VOLUME)) { + HardeningEnforcer.METHOD_AUDIO_MANAGER_SET_STREAM_VOLUME, + callingPackage, + Binder.getCallingUid())) { return; } setStreamVolumeWithAttributionInt(streamType, index, flags, /*device*/ null, @@ -6106,7 +6095,9 @@ public class AudioService extends IAudioService.Stub public void setRingerModeExternal(int ringerMode, String caller) { if (mHardeningEnforcer.blockVolumeMethod( - HardeningEnforcer.METHOD_AUDIO_MANAGER_SET_RINGER_MODE)) { + HardeningEnforcer.METHOD_AUDIO_MANAGER_SET_RINGER_MODE, + getPackageNameForUid(Binder.getCallingUid()), + Binder.getCallingUid())) { return; } if (isAndroidNPlus(caller) && wouldToggleZenMode(ringerMode) @@ -6875,7 +6866,9 @@ public class AudioService extends IAudioService.Stub @Override public void adjustVolume(int direction, int flags) { if (mHardeningEnforcer.blockVolumeMethod( - HardeningEnforcer.METHOD_AUDIO_MANAGER_ADJUST_VOLUME)) { + HardeningEnforcer.METHOD_AUDIO_MANAGER_ADJUST_VOLUME, + getPackageNameForUid(Binder.getCallingUid()), + Binder.getCallingUid())) { return; } getMediaSessionManager().dispatchAdjustVolume(AudioManager.USE_DEFAULT_STREAM_TYPE, @@ -6890,7 +6883,9 @@ public class AudioService extends IAudioService.Stub @Override public void adjustSuggestedStreamVolume(int direction, int suggestedStreamType, int flags) { if (mHardeningEnforcer.blockVolumeMethod( - HardeningEnforcer.METHOD_AUDIO_MANAGER_ADJUST_SUGGESTED_STREAM_VOLUME)) { + HardeningEnforcer.METHOD_AUDIO_MANAGER_ADJUST_SUGGESTED_STREAM_VOLUME, + getPackageNameForUid(Binder.getCallingUid()), + Binder.getCallingUid())) { return; } getMediaSessionManager().dispatchAdjustVolume(suggestedStreamType, direction, flags); @@ -15448,4 +15443,22 @@ public class AudioService extends IAudioService.Stub } return true; } + + private String getPackageNameForUid(int uid) { + final long token = Binder.clearCallingIdentity(); + try { + final String[] names = AudioService.this.mContext. + getPackageManager().getPackagesForUid(uid); + if (names == null + || names.length == 0 + || TextUtils.isEmpty(names[0])) { + return "[" + uid + "]"; + } + return names[0]; + } finally { + Binder.restoreCallingIdentity(token); + } + } + + } diff --git a/services/core/java/com/android/server/audio/HardeningEnforcer.java b/services/core/java/com/android/server/audio/HardeningEnforcer.java index f69a810b314f..9bb5160f108a 100644 --- a/services/core/java/com/android/server/audio/HardeningEnforcer.java +++ b/services/core/java/com/android/server/audio/HardeningEnforcer.java @@ -37,6 +37,7 @@ import com.android.modules.expresslog.Counter; import com.android.server.utils.EventLogger; import java.io.PrintWriter; +import java.util.concurrent.atomic.AtomicBoolean; /** * Class to encapsulate all audio API hardening operations @@ -49,6 +50,7 @@ public class HardeningEnforcer { final Context mContext; final AppOpsManager mAppOps; + final AtomicBoolean mShouldEnableAllHardening; final boolean mIsAutomotive; final ActivityManager mActivityManager; @@ -106,10 +108,16 @@ public class HardeningEnforcer { */ public static final int METHOD_AUDIO_MANAGER_REQUEST_AUDIO_FOCUS = 300; - public HardeningEnforcer(Context ctxt, boolean isAutomotive, AppOpsManager appOps, - PackageManager pm, EventLogger logger) { + private static final int ALLOWED = 0; + private static final int DENIED_IF_PARTIAL = 1; + private static final int DENIED_IF_FULL = 2; + + public HardeningEnforcer(Context ctxt, boolean isAutomotive, + AtomicBoolean shouldEnableHardening, AppOpsManager appOps, PackageManager pm, + EventLogger logger) { mContext = ctxt; mIsAutomotive = isAutomotive; + mShouldEnableAllHardening = shouldEnableHardening; mAppOps = appOps; mActivityManager = ctxt.getSystemService(ActivityManager.class); mPackageManager = pm; @@ -121,29 +129,59 @@ public class HardeningEnforcer { * @param volumeMethod name of the method to check, for logging purposes * @return false if the method call is allowed, true if it should be a no-op */ - protected boolean blockVolumeMethod(int volumeMethod) { + protected boolean blockVolumeMethod(int volumeMethod, String packageName, int uid) { + // Regardless of flag state, always permit callers with MODIFY_AUDIO_SETTINGS_PRIVILEGED + // Prevent them from showing up in metrics as well + if (mContext.checkCallingOrSelfPermission( + Manifest.permission.MODIFY_AUDIO_SETTINGS_PRIVILEGED) + == PackageManager.PERMISSION_GRANTED) { + return false; + } // for Auto, volume methods require MODIFY_AUDIO_SETTINGS_PRIVILEGED if (mIsAutomotive) { if (!autoPublicVolumeApiHardening()) { // automotive hardening flag disabled, no blocking on auto return false; } - if (mContext.checkCallingOrSelfPermission( - Manifest.permission.MODIFY_AUDIO_SETTINGS_PRIVILEGED) - == PackageManager.PERMISSION_GRANTED) { - return false; - } - if (Binder.getCallingUid() < UserHandle.AID_APP_START) { + if (uid < UserHandle.AID_APP_START) { return false; } // TODO metrics? // TODO log for audio dumpsys? Slog.e(TAG, "Preventing volume method " + volumeMethod + " for " - + getPackNameForUid(Binder.getCallingUid())); + + packageName); return true; + } else { + int allowed; + // No flags controlling restriction yet + boolean enforced = mShouldEnableAllHardening.get(); + if (!noteOp(AppOpsManager.OP_CONTROL_AUDIO_PARTIAL, uid, packageName, null)) { + // blocked by partial + Counter.logIncrementWithUid( + "media_audio.value_audio_volume_hardening_partial_restriction", uid); + allowed = DENIED_IF_PARTIAL; + } else if (!noteOp(AppOpsManager.OP_CONTROL_AUDIO, uid, packageName, null)) { + // blocked by full, permitted by partial + Counter.logIncrementWithUid( + "media_audio.value_audio_volume_hardening_strict_restriction", uid); + allowed = DENIED_IF_FULL; + } else { + // permitted with strict hardening, log anyway for API metrics + Counter.logIncrementWithUid( + "media_audio.value_audio_volume_hardening_allowed", uid); + allowed = ALLOWED; + } + if (allowed != ALLOWED) { + String msg = "AudioHardening volume control for api " + + volumeMethod + + (!enforced ? " would be " : " ") + + "ignored for " + + getPackNameForUid(uid) + " (" + uid + "), " + + "level: " + (allowed == DENIED_IF_PARTIAL ? "partial" : "full"); + mEventLogger.enqueueAndSlog(msg, EventLogger.Event.ALOGW, TAG); + } + return enforced && allowed != ALLOWED; } - // not blocking - return false; } /** |