am 466d8411: am 8d54a6e0: resolved conflicts for merge of b8fb609b to jb-mr1-dev
* commit '466d84110ef8f03b91561dd7a778558570e32abb':
Do not allow updates to the _data column.
diff --git a/src/com/android/providers/contacts/debug/DataExporter.java b/src/com/android/providers/contacts/debug/DataExporter.java
index 84dc072..c7c7dea 100644
--- a/src/com/android/providers/contacts/debug/DataExporter.java
+++ b/src/com/android/providers/contacts/debug/DataExporter.java
@@ -46,6 +46,7 @@
public static final String DUMP_FILE_DIRECTORY_NAME = "dumpedfiles";
public static final String OUT_FILE_SUFFIX = "-contacts-db.zip";
+ public static final String VALID_FILE_NAME_REGEX = "[0-9A-Fa-f]+-contacts-db\\.zip";
/**
* Compress all files under the app data dir into a single zip file, and return the content://
@@ -81,6 +82,20 @@
return Hex.encodeHex(random, true);
}
+ public static void ensureValidFileName(String fileName) {
+ // Do not allow queries to use relative paths to leave the root directory. Otherwise they
+ // can gain access to other files such as the contacts database.
+ if (fileName.contains("..")) {
+ throw new IllegalArgumentException(".. path specifier not allowed. Bad file name: " +
+ fileName);
+ }
+ // White list dump files.
+ if (!fileName.matches(VALID_FILE_NAME_REGEX)) {
+ throw new IllegalArgumentException("Only " + VALID_FILE_NAME_REGEX +
+ " files are supported. Bad file name: " + fileName);
+ }
+ }
+
private static File getOutputDirectory(Context context) {
return new File(context.getCacheDir(), DUMP_FILE_DIRECTORY_NAME);
}
diff --git a/src/com/android/providers/contacts/debug/DumpFileProvider.java b/src/com/android/providers/contacts/debug/DumpFileProvider.java
index f349dd2..b294573 100644
--- a/src/com/android/providers/contacts/debug/DumpFileProvider.java
+++ b/src/com/android/providers/contacts/debug/DumpFileProvider.java
@@ -76,7 +76,10 @@
if (!"r".equals(mode)) {
throw new UnsupportedOperationException();
}
- final File file = DataExporter.getOutputFile(getContext(), extractFileName(uri));
+
+ final String fileName = extractFileName(uri);
+ DataExporter.ensureValidFileName(fileName);
+ final File file = DataExporter.getOutputFile(getContext(), fileName);
return ParcelFileDescriptor.open(file, ParcelFileDescriptor.MODE_READ_ONLY);
}
@@ -87,6 +90,9 @@
@Override
public Cursor query(Uri uri, String[] inProjection, String selection, String[] selectionArgs,
String sortOrder) {
+ final String fileName = extractFileName(uri);
+ DataExporter.ensureValidFileName(fileName);
+
final String[] projection = (inProjection != null) ? inProjection
: new String[] {OpenableColumns.DISPLAY_NAME, OpenableColumns.SIZE};
@@ -100,9 +106,9 @@
if (OpenableColumns.DISPLAY_NAME.equals(column)) {
// Just return the requested path as the display name. We don't care if the file
// really exists.
- b.add(extractFileName(uri));
+ b.add(fileName);
} else if (OpenableColumns.SIZE.equals(column)) {
- final File file = DataExporter.getOutputFile(getContext(), extractFileName(uri));
+ final File file = DataExporter.getOutputFile(getContext(), fileName);
if (file.exists()) {
b.add(file.length());
@@ -117,4 +123,5 @@
return c;
}
+
}