Merge commit 'd014c98e0f3d61cbaaa55eca40eed3e893582278' into HEAD

Change-Id: I3e0b18eeb6afd2db539e24e86bf92279392b07b7
diff --git a/tests/tests/security/src/android/security/cts/ReadElf.java b/tests/src/android/os/cts/ReadElf.java
similarity index 90%
rename from tests/tests/security/src/android/security/cts/ReadElf.java
rename to tests/src/android/os/cts/ReadElf.java
index 2266b8b..b4041d2 100644
--- a/tests/tests/security/src/android/security/cts/ReadElf.java
+++ b/tests/src/android/os/cts/ReadElf.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package android.security.cts;
+package android.os.cts;
 
 import java.io.File;
 import java.io.IOException;
@@ -26,12 +26,19 @@
  * A poor man's implementation of the readelf command. This program is
  * designed to parse ELF (Executable and Linkable Format) files.
  */
-class ReadElf {
+public class ReadElf {
     /** The magic values for the ELF identification. */
     private static final byte[] ELF_IDENT = {
             (byte) 0x7F, (byte) 'E', (byte) 'L', (byte) 'F',
     };
 
+    private static final int EI_CLASS = 4;
+    private static final int EI_DATA = 5;
+
+    private static final int EM_386 = 3;
+    private static final int EM_MIPS = 8;
+    private static final int EM_ARM = 40;
+
     /** Size of the e_ident[] structure in the ELF header. */
     private static final int EI_NIDENT = 16;
 
@@ -179,9 +186,9 @@
         }
     };
 
+    private final String mPath;
     private final RandomAccessFile mFile;
     private final byte[] mBuffer = new byte[512];
-    private int mClass;
     private int mEndian;
     private boolean mIsDynamic;
     private boolean mIsPIE;
@@ -225,27 +232,31 @@
     /** Dynamic Symbol Table symbol names */
     private Map<String, Symbol> mDynamicSymbols;
 
-    static ReadElf read(File file) throws IOException {
+    public static ReadElf read(File file) throws IOException {
         return new ReadElf(file);
     }
 
-    boolean isDynamic() {
+    public boolean isDynamic() {
         return mIsDynamic;
     }
 
-    int getType() {
+    public int getType() {
         return mType;
     }
 
-    boolean isPIE() {
+    public boolean isPIE() {
         return mIsPIE;
     }
 
     private ReadElf(File file) throws IOException {
+        mPath = file.getPath();
         mFile = new RandomAccessFile(file, "r");
 
-        readIdent();
+        if (mFile.length() < EI_NIDENT) {
+            throw new IllegalArgumentException("Too small to be an ELF file: " + file);
+        }
 
+        readIdent();
         readHeader();
     }
 
@@ -261,6 +272,10 @@
 
     private void readHeader() throws IOException {
         mType = readHalf(getHeaderOffset(OFFSET_TYPE));
+        int e_machine = readHalf(getHeaderOffset(OFFSET_MACHINE));
+        if (e_machine != EM_386 && e_machine != EM_MIPS && e_machine != EM_ARM) {
+            throw new IOException("Invalid ELF e_machine: " + e_machine + ": " + mPath);
+        }
 
         final long shOffset = readWord(getHeaderOffset(OFFSET_SHOFF));
         final int shNumber = readHalf(getHeaderOffset(OFFSET_SHNUM));
@@ -441,18 +456,26 @@
 
         if ((mBuffer[0] != ELF_IDENT[0]) || (mBuffer[1] != ELF_IDENT[1])
                 || (mBuffer[2] != ELF_IDENT[2]) || (mBuffer[3] != ELF_IDENT[3])) {
-            throw new IllegalArgumentException("Invalid ELF file");
+            throw new IllegalArgumentException("Invalid ELF file: " + mPath);
         }
 
-        mClass = mBuffer[4];
-        if (mClass == ELFCLASS32) {
+        int elfClass = mBuffer[EI_CLASS];
+        if (elfClass == ELFCLASS32) {
             mWordSize = 4;
             mHalfWordSize = 2;
+        } else if (elfClass == ELFCLASS64) {
+            throw new IOException("Unsupported ELFCLASS64 file: " + mPath);
         } else {
-            throw new IOException("Invalid executable type " + mClass + ": not ELFCLASS32!");
+            throw new IOException("Invalid ELF EI_CLASS: " + elfClass + ": " + mPath);
         }
 
-        mEndian = mBuffer[5];
+        mEndian = mBuffer[EI_DATA];
+        if (mEndian == ELFDATA2LSB) {
+        } else if (mEndian == ELFDATA2MSB) {
+            throw new IOException("Unsupported ELFDATA2MSB file: " + mPath);
+        } else {
+            throw new IOException("Invalid ELF EI_DATA: " + mEndian + ": " + mPath);
+        }
     }
 
     public Symbol getSymbol(String name) {
diff --git a/tests/tests/hardware/src/android/hardware/cts/CameraTest.java b/tests/tests/hardware/src/android/hardware/cts/CameraTest.java
index f877d8b..b198541 100644
--- a/tests/tests/hardware/src/android/hardware/cts/CameraTest.java
+++ b/tests/tests/hardware/src/android/hardware/cts/CameraTest.java
@@ -1571,20 +1571,9 @@
         PreviewCbForPreviewPictureSizesCombination callback =
             new PreviewCbForPreviewPictureSizesCombination();
 
-        // Test combination of preview sizes and picture sizes. Pick four of each to test.
-        // Do not test all combinations because it will timeout. Four is just a small number
-        // and the test will not timeout.
-        List<Size> previewSizes = parameters.getSupportedPreviewSizes();
-        List<Size> pictureSizes = parameters.getSupportedPictureSizes();
-        int previewSizeTestCount = Math.min(previewSizes.size(), 4);
-        int pictureSizeTestCount = Math.min(pictureSizes.size(), 4);
-        // Calculate the step so that the first one and the last one are always tested.
-        float previewSizeIndexStep = (float) (previewSizes.size() - 1) / (previewSizeTestCount - 1);
-        float pictureSizeIndexStep = (float) (pictureSizes.size() - 1) / (pictureSizeTestCount - 1);
-        for (int i = 0; i < previewSizeTestCount; i++) {
-            for (int j = 0; j < pictureSizeTestCount; j++) {
-                Size previewSize = previewSizes.get(Math.round(previewSizeIndexStep * i));
-                Size pictureSize = pictureSizes.get(Math.round(pictureSizeIndexStep * j));
+        // Test all combination of preview sizes and picture sizes.
+        for (Size previewSize: parameters.getSupportedPreviewSizes()) {
+            for (Size pictureSize: parameters.getSupportedPictureSizes()) {
                 Log.v(TAG, "Test previewSize=(" + previewSize.width + "," +
                         previewSize.height + ") pictureSize=(" +
                         pictureSize.width + "," + pictureSize.height + ")");
diff --git a/tests/tests/media/src/android/media/cts/DecoderTest.java b/tests/tests/media/src/android/media/cts/DecoderTest.java
index 65f16b1..f250c3d 100644
--- a/tests/tests/media/src/android/media/cts/DecoderTest.java
+++ b/tests/tests/media/src/android/media/cts/DecoderTest.java
@@ -981,7 +981,7 @@
         CRC32 crc = new CRC32();
         int pos = buf.position();
         buf.rewind();
-        for (int i = 0; i < buf.capacity(); i++) {
+        for (int i = 0; i < size; i++) {
             crc.update(buf.get());
         }
         buf.position(pos);
diff --git a/tests/tests/os/src/android/os/cts/AbiTest.java b/tests/tests/os/src/android/os/cts/AbiTest.java
new file mode 100644
index 0000000..69b314d
--- /dev/null
+++ b/tests/tests/os/src/android/os/cts/AbiTest.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.os.cts;
+
+import android.os.cts.ReadElf;
+
+import java.io.File;
+
+import junit.framework.TestCase;
+
+public class AbiTest extends TestCase {
+    public void testNo64() throws Exception {
+        for (String dir : new File("/").list()) {
+            if (!dir.equals("data") && !dir.equals("dev") && !dir.equals("proc") && !dir.equals("sys")) {
+                checkElfFilesInDirectory(new File("/" + dir));
+            }
+        }
+    }
+
+    private void checkElfFilesInDirectory(File dir) throws Exception {
+        if (!dir.isDirectory()) {
+            return;
+        }
+
+        if (isSymbolicLink(dir)) {
+            return;
+        }
+
+        File[] files = dir.listFiles();
+        if (files == null) {
+            return;
+        }
+
+        for (File f : files) {
+            if (f.isDirectory()) {
+                checkElfFilesInDirectory(f);
+            } else if (f.getName().endsWith(".so") || f.canExecute()) {
+                try {
+                    ReadElf.read(f);
+                } catch (IllegalArgumentException ignored) {
+                    // If it's not actually an ELF file, we don't care.
+                }
+            }
+        }
+    }
+
+    private static boolean isSymbolicLink(File f) throws Exception {
+        return !f.getAbsolutePath().equals(f.getCanonicalPath());
+    }
+}
diff --git a/tests/tests/security/src/android/security/cts/AslrTest.java b/tests/tests/security/src/android/security/cts/AslrTest.java
index a4c4f80..1e76d90 100644
--- a/tests/tests/security/src/android/security/cts/AslrTest.java
+++ b/tests/tests/security/src/android/security/cts/AslrTest.java
@@ -24,6 +24,8 @@
 import java.io.FileReader;
 import java.io.IOException;
 
+import android.os.cts.ReadElf;
+
 /**
  * Verify that ASLR is properly enabled on Android Compatible devices.
  */
diff --git a/tests/tests/security/src/android/security/cts/BannedFilesTest.java b/tests/tests/security/src/android/security/cts/BannedFilesTest.java
index 0b16380..0ea29c5 100644
--- a/tests/tests/security/src/android/security/cts/BannedFilesTest.java
+++ b/tests/tests/security/src/android/security/cts/BannedFilesTest.java
@@ -20,7 +20,11 @@
 
 import junit.framework.TestCase;
 
+import java.io.DataInputStream;
 import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
 
 public class BannedFilesTest extends TestCase {
 
@@ -60,6 +64,34 @@
         }
     }
 
+    public void testNoEnableRoot() throws UnsupportedEncodingException {
+        byte[] badPattern = "enable_root".getBytes("US-ASCII");
+        assertFileDoesNotContain("/system/bin/adb", badPattern);
+    }
+
+    private static void assertFileDoesNotContain(String filename, byte[] pattern) {
+        try {
+            File f = new File(filename);
+            byte[] fileData = new byte[(int) f.length()];
+            DataInputStream dis = new DataInputStream(new FileInputStream(f));
+            dis.readFully(fileData);
+            dis.close();
+
+            outer:
+            for (int i = 0; i < (fileData.length - pattern.length); i++) {
+                for (int j = 0; j < pattern.length; j++) {
+                    if (fileData[i+j] != pattern[j]) {
+                        continue outer;
+                    }
+                }
+                fail("Found banned pattern in " + filename);
+            }
+
+        } catch (IOException e) {
+            // ignore - no such file, or IO error. Assume OK.
+        }
+    }
+
     /**
      * setuid or setgid "ip" command can be used to modify the
      * routing tables of a device, potentially allowing a malicious