diff options
4 files changed, 69 insertions, 68 deletions
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index bd000e20fc64..0735648c1069 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -5755,6 +5755,18 @@ public class ActivityManagerService extends IActivityManager.Stub owningUid, exported); } + private void enforceDebuggable(ProcessRecord proc) { + if (!Build.IS_DEBUGGABLE && !proc.isDebuggable()) { + throw new SecurityException("Process not debuggable: " + proc.info.packageName); + } + } + + private void enforceDebuggable(ApplicationInfo info) { + if (!Build.IS_DEBUGGABLE && (info.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) { + throw new SecurityException("Process not debuggable: " + info.packageName); + } + } + /** * As the only public entry point for permissions checking, this method * can enforce the semantic that requesting a check on a null global @@ -6792,22 +6804,25 @@ public class ActivityManagerService extends IActivityManager.Stub } void setTrackAllocationApp(ApplicationInfo app, String processName) { - if (!Build.IS_DEBUGGABLE) { - if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) { - throw new SecurityException("Process not debuggable: " + app.packageName); - } - } + enforceDebuggable(app); synchronized (mProcLock) { mTrackAllocationApp = processName; } } - void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) { + void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo, + ApplicationInfo sdkSandboxClientApp) { synchronized (mAppProfiler.mProfilerLock) { if (!Build.IS_DEBUGGABLE) { boolean isAppDebuggable = (app.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0; boolean isAppProfileable = app.isProfileableByShell(); + + if (sdkSandboxClientApp != null) { + isAppDebuggable |= + (sdkSandboxClientApp.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0; + isAppProfileable |= sdkSandboxClientApp.isProfileableByShell(); + } if (!isAppDebuggable && !isAppProfileable) { throw new SecurityException("Process not debuggable, " + "and not profileable by shell: " + app.packageName); @@ -6818,11 +6833,7 @@ public class ActivityManagerService extends IActivityManager.Stub } void setNativeDebuggingAppLocked(ApplicationInfo app, String processName) { - if (!Build.IS_DEBUGGABLE) { - if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) { - throw new SecurityException("Process not debuggable: " + app.packageName); - } - } + enforceDebuggable(app); mNativeDebuggingApp = processName; } @@ -15568,12 +15579,7 @@ public class ActivityManagerService extends IActivityManager.Stub throw new IllegalArgumentException("Unknown process: " + process); } - boolean isDebuggable = Build.IS_DEBUGGABLE; - if (!isDebuggable) { - if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { - throw new SecurityException("Process not debuggable: " + proc); - } - } + enforceDebuggable(proc); mOomAdjuster.mCachedAppOptimizer.enableFreezer(false); @@ -15676,10 +15682,7 @@ public class ActivityManagerService extends IActivityManager.Stub throw new SecurityException("No process found for calling pid " + Binder.getCallingPid()); } - if (!Build.IS_DEBUGGABLE - && (proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { - throw new SecurityException("Not running a debuggable build"); - } + enforceDebuggable(proc); processName = proc.processName; uid = proc.uid; if (reportPackage != null && !proc.getPkgList().containsKey(reportPackage)) { @@ -15890,13 +15893,7 @@ public class ActivityManagerService extends IActivityManager.Stub return false; } - if (!Build.IS_DEBUGGABLE) { - if ((process.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { - return false; - } - } - - return true; + return Build.IS_DEBUGGABLE || process.isDebuggable(); } public boolean startBinderTracking() throws RemoteException { @@ -16850,7 +16847,7 @@ public class ActivityManagerService extends IActivityManager.Stub } if (profilerInfo != null) { - setProfileApp(aInfo.applicationInfo, aInfo.processName, profilerInfo); + setProfileApp(aInfo.applicationInfo, aInfo.processName, profilerInfo, null); } wmLock.notify(); } @@ -17638,11 +17635,7 @@ public class ActivityManagerService extends IActivityManager.Stub throw new IllegalArgumentException("Unknown process: " + process); } - if (!Build.IS_DEBUGGABLE) { - if ((proc.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) { - throw new SecurityException("Process not debuggable: " + proc); - } - } + enforceDebuggable(proc); thread.attachAgent(path); } diff --git a/services/core/java/com/android/server/am/AppProfiler.java b/services/core/java/com/android/server/am/AppProfiler.java index ac0e22032b65..16a728386bd6 100644 --- a/services/core/java/com/android/server/am/AppProfiler.java +++ b/services/core/java/com/android/server/am/AppProfiler.java @@ -58,7 +58,6 @@ import android.content.ComponentCallbacks2; import android.content.ContentResolver; import android.content.Context; import android.content.Intent; -import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager.NameNotFoundException; import android.net.Uri; import android.os.Binder; @@ -608,13 +607,7 @@ public class AppProfiler { if (check != null) { if ((pss * 1024) >= check && profile.getThread() != null && mMemWatchDumpProcName == null) { - boolean isDebuggable = Build.IS_DEBUGGABLE; - if (!isDebuggable) { - if ((proc.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) { - isDebuggable = true; - } - } - if (isDebuggable) { + if (Build.IS_DEBUGGABLE || proc.isDebuggable()) { Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check + "; reporting"); startHeapDumpLPf(profile, false); } else { @@ -1702,7 +1695,8 @@ public class AppProfiler { try { if (start) { stopProfilerLPf(null, 0); - mService.setProfileApp(proc.info, proc.processName, profilerInfo); + mService.setProfileApp(proc.info, proc.processName, profilerInfo, + proc.isSdkSandbox ? proc.getClientInfoForSdkSandbox() : null); mProfileData.setProfileProc(proc); mProfileType = profileType; ParcelFileDescriptor fd = profilerInfo.profileFd; @@ -2075,7 +2069,7 @@ public class AppProfiler { if (mAppAgentMap != null && mAppAgentMap.containsKey(processName)) { // We need to do a debuggable check here. See setAgentApp for why the check is // postponed to here. - if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) { + if (app.isDebuggable()) { String agent = mAppAgentMap.get(processName); // Do not overwrite already requested agent. if (profilerInfo == null) { @@ -2132,7 +2126,7 @@ public class AppProfiler { if (preBindAgent != null) { thread.attachAgent(preBindAgent); } - if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) { + if (app.isDebuggable()) { thread.attachStartupAgents(app.info.dataDir); } return profilerInfo; diff --git a/services/core/java/com/android/server/am/ProcessList.java b/services/core/java/com/android/server/am/ProcessList.java index 5bb946f3cd50..253686c2602d 100644 --- a/services/core/java/com/android/server/am/ProcessList.java +++ b/services/core/java/com/android/server/am/ProcessList.java @@ -1718,8 +1718,16 @@ public final class ProcessList { int runtimeFlags = 0; boolean debuggableFlag = (app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0; - if (!debuggableFlag && app.isSdkSandbox) { - debuggableFlag = isAppForSdkSandboxDebuggable(app); + boolean isProfileableByShell = app.info.isProfileableByShell(); + boolean isProfileable = app.info.isProfileable(); + + if (app.isSdkSandbox) { + ApplicationInfo clientInfo = app.getClientInfoForSdkSandbox(); + if (clientInfo != null) { + debuggableFlag |= (clientInfo.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0; + isProfileableByShell |= clientInfo.isProfileableByShell(); + isProfileable |= clientInfo.isProfileable(); + } } if (debuggableFlag) { @@ -1741,10 +1749,10 @@ public final class ProcessList { if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 || mService.mSafeMode) { runtimeFlags |= Zygote.DEBUG_ENABLE_SAFEMODE; } - if ((app.info.privateFlags & ApplicationInfo.PRIVATE_FLAG_PROFILEABLE_BY_SHELL) != 0) { + if (isProfileableByShell) { runtimeFlags |= Zygote.PROFILE_FROM_SHELL; } - if (app.info.isProfileable()) { + if (isProfileable) { runtimeFlags |= Zygote.PROFILEABLE; } if ("1".equals(SystemProperties.get("debug.checkjni"))) { @@ -1812,7 +1820,7 @@ public final class ProcessList { } String invokeWith = null; - if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) { + if (debuggableFlag) { // Debuggable apps may include a wrapper script with their library directory. String wrapperFileName = app.info.nativeLibraryDir + "/wrap.sh"; StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); @@ -1887,24 +1895,6 @@ public final class ProcessList { } } - /** Return true if the client app for the SDK sandbox process is debuggable. */ - private boolean isAppForSdkSandboxDebuggable(ProcessRecord sandboxProcess) { - // TODO (b/221004701) use client app process name - final int appUid = Process.getAppUidForSdkSandboxUid(sandboxProcess.uid); - IPackageManager pm = mService.getPackageManager(); - try { - String[] packages = pm.getPackagesForUid(appUid); - for (String aPackage : packages) { - ApplicationInfo i = pm.getApplicationInfo(aPackage, 0, sandboxProcess.userId); - if ((i.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) { - return true; - } - } - } catch (RemoteException e) { - // shouldn't happen - } - return false; - } @GuardedBy("mService") boolean startProcessLocked(HostingRecord hostingRecord, String entryPoint, ProcessRecord app, diff --git a/services/core/java/com/android/server/am/ProcessRecord.java b/services/core/java/com/android/server/am/ProcessRecord.java index 4908698a237f..b4ff8709a32f 100644 --- a/services/core/java/com/android/server/am/ProcessRecord.java +++ b/services/core/java/com/android/server/am/ProcessRecord.java @@ -27,6 +27,7 @@ import android.app.ApplicationExitInfo.Reason; import android.app.ApplicationExitInfo.SubReason; import android.app.IApplicationThread; import android.content.pm.ApplicationInfo; +import android.content.pm.PackageManagerInternal; import android.content.pm.ProcessInfo; import android.content.pm.VersionedPackage; import android.content.res.CompatibilityInfo; @@ -865,6 +866,29 @@ class ProcessRecord implements WindowProcessListener { return mDebugging; } + @Nullable + public ApplicationInfo getClientInfoForSdkSandbox() { + if (!isSdkSandbox || sdkSandboxClientAppPackage == null) { + throw new IllegalStateException( + "getClientInfoForSdkSandbox called for non-sandbox process" + ); + } + PackageManagerInternal pm = mService.getPackageManagerInternal(); + return pm.getApplicationInfo( + sdkSandboxClientAppPackage, /* flags */0, Process.SYSTEM_UID, userId); + } + + public boolean isDebuggable() { + if ((info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) { + return true; + } + if (isSdkSandbox) { + ApplicationInfo clientInfo = getClientInfoForSdkSandbox(); + return clientInfo != null && (clientInfo.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0; + } + return false; + } + @GuardedBy("mService") void setDebugging(boolean debugging) { mDebugging = debugging; |