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.File;
21 import java.io.FileInputStream;
22 import java.io.FileNotFoundException;
23 import java.io.FileReader;
24 import java.io.IOException;
25 
26 import android.content.pm.ApplicationInfo;
27 import android.content.pm.PackageManager;
28 import android.content.pm.PackageManager.NameNotFoundException;
29 import android.test.AndroidTestCase;
30 
31 /**
32  * Test that another app's private data cannot be accessed, while its public data can.
33  *
34  * Assumes that {@link #APP_WITH_DATA_PKG} has already created the private and public data.
35  */
36 public class AccessPrivateDataTest extends AndroidTestCase {
37 
38     /**
39      * The Android package name of the application that owns the data
40      */
41     private static final String APP_WITH_DATA_PKG = "com.android.cts.appwithdata";
42 
43     /**
44      * Name of private file to access. This must match the name of the file created by
45      * {@link #APP_WITH_DATA_PKG}.
46      */
47     private static final String PRIVATE_FILE_NAME = "private_file.txt";
48     /**
49      * Name of public file to access. This must match the name of the file created by
50      * {@link #APP_WITH_DATA_PKG}.
51      */
52     private static final String PUBLIC_FILE_NAME = "public_file.txt";
53 
54     /**
55      * Tests that another app's private data cannot be accessed. It includes file
56      * and detailed traffic stats.
57      * @throws IOException
58      */
testAccessPrivateData()59     public void testAccessPrivateData() throws IOException {
60         try {
61             // construct the absolute file path to the app's private file
62             ApplicationInfo applicationInfo = getApplicationInfo(APP_WITH_DATA_PKG);
63             File privateFile = new File(applicationInfo.dataDir, "files/" + PRIVATE_FILE_NAME);
64             FileInputStream inputStream = new FileInputStream(privateFile);
65             inputStream.read();
66             inputStream.close();
67             fail("Was able to access another app's private data");
68         } catch (FileNotFoundException | SecurityException e) {
69             // expected
70         }
71         accessPrivateTrafficStats();
72     }
73 
getApplicationInfo(String packageName)74     private ApplicationInfo getApplicationInfo(String packageName) {
75         try {
76             return mContext.getPackageManager().getApplicationInfo(packageName, 0);
77         } catch (PackageManager.NameNotFoundException e) {
78             throw new IllegalStateException("Expected package not found: " + e);
79         }
80     }
81 
82     /**
83      * Tests that another app's public file can be accessed
84      * @throws IOException
85      */
testAccessPublicData()86     public void testAccessPublicData() throws IOException {
87         try {
88             // construct the absolute file path to the other app's public file
89             ApplicationInfo applicationInfo = getApplicationInfo(APP_WITH_DATA_PKG);
90             File publicFile = new File(applicationInfo.dataDir, "files/" + PUBLIC_FILE_NAME);
91             FileInputStream inputStream = new FileInputStream(publicFile);
92             inputStream.read();
93             inputStream.close();
94             fail("Was able to access another app's public file");
95         } catch (FileNotFoundException | SecurityException e) {
96             // expected
97         }
98     }
99 
accessPrivateTrafficStats()100     private void accessPrivateTrafficStats() throws IOException {
101         int otherAppUid = -1;
102         try {
103             otherAppUid = getContext()
104                     .createPackageContext(APP_WITH_DATA_PKG, 0 /*flags*/)
105                     .getApplicationInfo().uid;
106         } catch (NameNotFoundException e) {
107             fail("Was not able to find other app");
108         }
109         try {
110             BufferedReader qtaguidReader = new BufferedReader(new FileReader("/proc/net/xt_qtaguid/stats"));
111             String line;
112             while ((line = qtaguidReader.readLine()) != null) {
113                 String tokens[] = line.split(" ");
114                 if (tokens.length > 3 && tokens[3].equals(String.valueOf(otherAppUid))) {
115                     // CreatePrivateDataTest:testCreatePrivateData ensures we can access our own stats data
116                     fail("Other apps detailed traffic stats leaked");
117                 }
118             }
119             qtaguidReader.close();
120         } catch (FileNotFoundException e) {
121             fail("Was not able to access qtaguid/stats: " + e);
122         }
123     }
124 }
125