Process: Fix communication with zygote.

Don't write partial requests, and don't return (or throw) early after
partially reading a response.

bug: 30143607
Change-Id: I5881fdd5e81023cd21fb4d23a471a5031987a1f1
diff --git a/core/java/android/os/Process.java b/core/java/android/os/Process.java
index 4ef882e..e1b7fda 100644
--- a/core/java/android/os/Process.java
+++ b/core/java/android/os/Process.java
@@ -567,6 +567,15 @@
             ZygoteState zygoteState, ArrayList<String> args)
             throws ZygoteStartFailedEx {
         try {
+            // Throw early if any of the arguments are malformed. This means we can
+            // avoid writing a partial response to the zygote.
+            int sz = args.size();
+            for (int i = 0; i < sz; i++) {
+                if (args.get(i).indexOf('\n') >= 0) {
+                    throw new ZygoteStartFailedEx("embedded newlines not allowed");
+                }
+            }
+
             /**
              * See com.android.internal.os.ZygoteInit.readArgumentList()
              * Presently the wire format to the zygote process is:
@@ -583,13 +592,8 @@
             writer.write(Integer.toString(args.size()));
             writer.newLine();
 
-            int sz = args.size();
             for (int i = 0; i < sz; i++) {
                 String arg = args.get(i);
-                if (arg.indexOf('\n') >= 0) {
-                    throw new ZygoteStartFailedEx(
-                            "embedded newlines not allowed");
-                }
                 writer.write(arg);
                 writer.newLine();
             }
@@ -598,11 +602,16 @@
 
             // Should there be a timeout on this?
             ProcessStartResult result = new ProcessStartResult();
+
+            // Always read the entire result from the input stream to avoid leaving
+            // bytes in the stream for future process starts to accidentally stumble
+            // upon.
             result.pid = inputStream.readInt();
+            result.usingWrapper = inputStream.readBoolean();
+
             if (result.pid < 0) {
                 throw new ZygoteStartFailedEx("fork() failed");
             }
-            result.usingWrapper = inputStream.readBoolean();
             return result;
         } catch (IOException ex) {
             zygoteState.close();