summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--services/core/java/com/android/server/am/MemoryStatUtil.java23
-rw-r--r--services/tests/servicestests/src/com/android/server/am/MemoryStatUtilTest.java39
2 files changed, 59 insertions, 3 deletions
diff --git a/services/core/java/com/android/server/am/MemoryStatUtil.java b/services/core/java/com/android/server/am/MemoryStatUtil.java
index 90fe30c7c718..a58491472036 100644
--- a/services/core/java/com/android/server/am/MemoryStatUtil.java
+++ b/services/core/java/com/android/server/am/MemoryStatUtil.java
@@ -123,9 +123,8 @@ public final class MemoryStatUtil {
* if the file is not available.
*/
public static String readCmdlineFromProcfs(int pid) {
- String path = String.format(Locale.US, PROC_CMDLINE_FILE_FMT, pid);
- String cmdline = readFileContents(path);
- return cmdline != null ? cmdline : "";
+ final String path = String.format(Locale.US, PROC_CMDLINE_FILE_FMT, pid);
+ return parseCmdlineFromProcfs(readFileContents(path));
}
private static String readFileContents(String path) {
@@ -210,6 +209,24 @@ public final class MemoryStatUtil {
return m.find() ? Long.parseLong(m.group(1)) * BYTES_IN_KILOBYTE : 0;
}
+
+ /**
+ * Parses cmdline out of the contents of the /proc/pid/cmdline file in procfs.
+ *
+ * Parsing is required to strip anything after first null byte.
+ */
+ @VisibleForTesting
+ static String parseCmdlineFromProcfs(String cmdline) {
+ if (cmdline == null) {
+ return "";
+ }
+ int firstNullByte = cmdline.indexOf("\0");
+ if (firstNullByte == -1) {
+ return cmdline;
+ }
+ return cmdline.substring(0, firstNullByte);
+ }
+
/**
* Returns whether per-app memcg is available on device.
*/
diff --git a/services/tests/servicestests/src/com/android/server/am/MemoryStatUtilTest.java b/services/tests/servicestests/src/com/android/server/am/MemoryStatUtilTest.java
index 89c7b71e2cc1..93cac08f0033 100644
--- a/services/tests/servicestests/src/com/android/server/am/MemoryStatUtilTest.java
+++ b/services/tests/servicestests/src/com/android/server/am/MemoryStatUtilTest.java
@@ -20,6 +20,7 @@ import static com.android.server.am.MemoryStatUtil.BYTES_IN_KILOBYTE;
import static com.android.server.am.MemoryStatUtil.JIFFY_NANOS;
import static com.android.server.am.MemoryStatUtil.MemoryStat;
import static com.android.server.am.MemoryStatUtil.PAGE_SIZE;
+import static com.android.server.am.MemoryStatUtil.parseCmdlineFromProcfs;
import static com.android.server.am.MemoryStatUtil.parseMemoryStatFromMemcg;
import static com.android.server.am.MemoryStatUtil.parseMemoryStatFromProcfs;
import static com.android.server.am.MemoryStatUtil.parseVmHWMFromProcfs;
@@ -31,6 +32,7 @@ import androidx.test.filters.SmallTest;
import org.junit.Test;
+import java.io.ByteArrayOutputStream;
import java.util.Collections;
/**
@@ -232,4 +234,41 @@ public class MemoryStatUtilTest {
assertEquals(0, parseVmHWMFromProcfs(null));
}
+
+ @Test
+ public void testParseCmdlineFromProcfs_invalidValue() {
+ byte[] nothing = new byte[] {0x00, 0x74, 0x65, 0x73, 0x74}; // \0test
+
+ assertEquals("", parseCmdlineFromProcfs(bytesToString(nothing)));
+ }
+
+ @Test
+ public void testParseCmdlineFromProcfs_correctValue_noNullBytes() {
+ assertEquals("com.google.app", parseCmdlineFromProcfs("com.google.app"));
+ }
+
+ @Test
+ public void testParseCmdlineFromProcfs_correctValue_withNullBytes() {
+ byte[] trailing = new byte[] {0x74, 0x65, 0x73, 0x74, 0x00, 0x00, 0x00}; // test\0\0\0
+
+ assertEquals("test", parseCmdlineFromProcfs(bytesToString(trailing)));
+
+ // test\0\0test
+ byte[] inside = new byte[] {0x74, 0x65, 0x73, 0x74, 0x00, 0x00, 0x74, 0x65, 0x73, 0x74};
+
+ assertEquals("test", parseCmdlineFromProcfs(bytesToString(trailing)));
+ }
+
+ @Test
+ public void testParseCmdlineFromProcfs_emptyContents() {
+ assertEquals("", parseCmdlineFromProcfs(""));
+
+ assertEquals("", parseCmdlineFromProcfs(null));
+ }
+
+ private static String bytesToString(byte[] bytes) {
+ ByteArrayOutputStream output = new ByteArrayOutputStream();
+ output.write(bytes, 0, bytes.length);
+ return output.toString();
+ }
}