From 9c8dd55a9d829c29a3feee9469d8c2f27a9f5516 Mon Sep 17 00:00:00 2001 From: Dianne Hackborn Date: Tue, 23 Jun 2009 19:22:52 -0700 Subject: Fix bug 1829561 ("am profile" with bad filename kills process). The am command is now the one that takes care of opening the target file, handling the opened file descriptor to the process that will be profiled. This allows you to send profile data to anywhere the shell can access, and avoids any problems coming up from the target process trying to open the file. --- .../android/server/am/ActivityManagerService.java | 90 ++++++++++++---------- 1 file changed, 51 insertions(+), 39 deletions(-) (limited to 'services') diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java index 62b4d5e..0d9d2b0 100644 --- a/services/java/com/android/server/am/ActivityManagerService.java +++ b/services/java/com/android/server/am/ActivityManagerService.java @@ -12601,51 +12601,63 @@ public final class ActivityManagerService extends ActivityManagerNative implemen } public boolean profileControl(String process, boolean start, - String path) throws RemoteException { + String path, ParcelFileDescriptor fd) throws RemoteException { - synchronized (this) { - // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to - // its own permission. - if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) - != PackageManager.PERMISSION_GRANTED) { - throw new SecurityException("Requires permission " - + android.Manifest.permission.SET_ACTIVITY_WATCHER); - } - - ProcessRecord proc = null; - try { - int pid = Integer.parseInt(process); - synchronized (mPidsSelfLocked) { - proc = mPidsSelfLocked.get(pid); + try { + synchronized (this) { + // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to + // its own permission. + if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) + != PackageManager.PERMISSION_GRANTED) { + throw new SecurityException("Requires permission " + + android.Manifest.permission.SET_ACTIVITY_WATCHER); } - } catch (NumberFormatException e) { - } - - if (proc == null) { - HashMap> all - = mProcessNames.getMap(); - SparseArray procs = all.get(process); - if (procs != null && procs.size() > 0) { - proc = procs.valueAt(0); + + if (start && fd == null) { + throw new IllegalArgumentException("null fd"); } - } - - if (proc == null || proc.thread == null) { - throw new IllegalArgumentException("Unknown process: " + process); - } - - boolean isSecure = "1".equals(SystemProperties.get(SYSTEM_SECURE, "0")); - if (isSecure) { - if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { - throw new SecurityException("Process not debuggable: " + proc); + + ProcessRecord proc = null; + try { + int pid = Integer.parseInt(process); + synchronized (mPidsSelfLocked) { + proc = mPidsSelfLocked.get(pid); + } + } catch (NumberFormatException e) { + } + + if (proc == null) { + HashMap> all + = mProcessNames.getMap(); + SparseArray procs = all.get(process); + if (procs != null && procs.size() > 0) { + proc = procs.valueAt(0); + } + } + + if (proc == null || proc.thread == null) { + throw new IllegalArgumentException("Unknown process: " + process); + } + + boolean isSecure = "1".equals(SystemProperties.get(SYSTEM_SECURE, "0")); + if (isSecure) { + if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { + throw new SecurityException("Process not debuggable: " + proc); + } } - } - try { - proc.thread.profilerControl(start, path); + proc.thread.profilerControl(start, path, fd); + fd = null; return true; - } catch (RemoteException e) { - throw new IllegalStateException("Process disappeared"); + } + } catch (RemoteException e) { + throw new IllegalStateException("Process disappeared"); + } finally { + if (fd != null) { + try { + fd.close(); + } catch (IOException e) { + } } } } -- cgit v1.1