1 /* 2 * Copyright (C) 2009 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.cts.appaccessdata; 18 19 import java.io.BufferedReader; 20 import java.io.DataInputStream; 21 import java.io.FileInputStream; 22 import java.io.FileNotFoundException; 23 import java.io.FileReader; 24 import java.io.IOException; 25 26 import android.test.AndroidTestCase; 27 28 /** 29 * Test that another app's private data cannot be accessed, while its public data can. 30 * 31 * Assumes that {@link APP_WITH_DATA_PKG} has already created the private and public data. 32 */ 33 public class AccessPrivateDataTest extends AndroidTestCase { 34 35 /** 36 * The Android package name of the application that owns the data 37 */ 38 private static final String APP_WITH_DATA_PKG = "com.android.cts.appwithdata"; 39 40 /** 41 * Name of private file to access. This must match the name of the file created by 42 * {@link APP_WITH_DATA_PKG}. 43 */ 44 private static final String PRIVATE_FILE_NAME = "private_file.txt"; 45 /** 46 * Name of public file to access. This must match the name of the file created by 47 * {@link APP_WITH_DATA_PKG}. 48 */ 49 private static final String PUBLIC_FILE_NAME = "public_file.txt"; 50 51 /** 52 * Tests that another app's private data cannot be accessed. It includes file 53 * and detailed traffic stats. 54 * @throws IOException 55 */ testAccessPrivateData()56 public void testAccessPrivateData() throws IOException { 57 try { 58 // construct the absolute file path to the app's private file 59 String privateFilePath = String.format("/data/data/%s/%s", APP_WITH_DATA_PKG, 60 PRIVATE_FILE_NAME); 61 FileInputStream inputStream = new FileInputStream(privateFilePath); 62 inputStream.read(); 63 inputStream.close(); 64 fail("Was able to access another app's private data"); 65 } catch (FileNotFoundException e) { 66 // expected 67 } catch (SecurityException e) { 68 // also valid 69 } 70 accessPrivateTrafficStats(); 71 } 72 73 /** 74 * Tests that another app's public file can be accessed 75 * @throws IOException 76 */ testAccessPublicData()77 public void testAccessPublicData() throws IOException { 78 try { 79 getOtherAppUid(); 80 } catch (FileNotFoundException e) { 81 fail("Was not able to access another app's public file: " + e); 82 } catch (SecurityException e) { 83 fail("Was not able to access another app's public file: " + e); 84 } 85 } 86 getOtherAppUid()87 private int getOtherAppUid() throws IOException, FileNotFoundException, SecurityException { 88 // construct the absolute file path to the other app's public file 89 String publicFilePath = String.format("/data/data/%s/files/%s", APP_WITH_DATA_PKG, 90 PUBLIC_FILE_NAME); 91 DataInputStream inputStream = new DataInputStream(new FileInputStream(publicFilePath)); 92 int otherAppUid = (int)inputStream.readInt(); 93 inputStream.close(); 94 return otherAppUid; 95 } 96 accessPrivateTrafficStats()97 private void accessPrivateTrafficStats() throws IOException { 98 int otherAppUid = -1; 99 try { 100 otherAppUid = getOtherAppUid(); 101 } catch (FileNotFoundException e) { 102 fail("Was not able to access another app's public file: " + e); 103 } catch (SecurityException e) { 104 fail("Was not able to access another app's public file: " + e); 105 } 106 107 boolean foundOtherStats = false; 108 try { 109 BufferedReader qtaguidReader = new BufferedReader(new FileReader("/proc/net/xt_qtaguid/stats")); 110 String line; 111 while ((line = qtaguidReader.readLine()) != null) { 112 String tokens[] = line.split(" "); 113 if (tokens.length > 3 && tokens[3].equals(String.valueOf(otherAppUid))) { 114 foundOtherStats = true; 115 if (!tokens[2].equals("0x0")) { 116 fail("Other apps detailed traffic stats leaked"); 117 } 118 } 119 } 120 qtaguidReader.close(); 121 } catch (FileNotFoundException e) { 122 fail("Was not able to access qtaguid/stats: " + e); 123 } 124 assertTrue("Was expecting to find other apps' traffic stats", foundOtherStats); 125 } 126 } 127