diff options
8 files changed, 75 insertions, 15 deletions
diff --git a/jni/com_android_bluetooth_gatt.cpp b/jni/com_android_bluetooth_gatt.cpp index 1ffac4e08..a4e5322d6 100644 --- a/jni/com_android_bluetooth_gatt.cpp +++ b/jni/com_android_bluetooth_gatt.cpp @@ -1241,7 +1241,13 @@ static void gattServerSendResponseNative (JNIEnv *env, jobject object, if (val != NULL) { - response.attr_value.len = (uint16_t) env->GetArrayLength(val); + if (env->GetArrayLength(val) < BTGATT_MAX_ATTR_LEN) { + response.attr_value.len = (uint16_t)env->GetArrayLength(val); + } else { + android_errorWriteLog(0x534e4554, "78787521"); + response.attr_value.len = BTGATT_MAX_ATTR_LEN; + } + jbyte* array = env->GetByteArrayElements(val, 0); for (int i = 0; i != response.attr_value.len; ++i) diff --git a/src/com/android/bluetooth/btservice/AdapterService.java b/src/com/android/bluetooth/btservice/AdapterService.java index 8e7decc2a..a6d0b1cb2 100644 --- a/src/com/android/bluetooth/btservice/AdapterService.java +++ b/src/com/android/bluetooth/btservice/AdapterService.java @@ -1474,8 +1474,8 @@ public class AdapterService extends Service { } boolean setPairingConfirmation(BluetoothDevice device, boolean accept) { - enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM, - "Need BLUETOOTH ADMIN permission"); + enforceCallingOrSelfPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED, + "Need BLUETOOTH PRIVILEGED permission"); DeviceProperties deviceProp = mRemoteDevices.getDeviceProperties(device); if (deviceProp == null || deviceProp.getBondState() != BluetoothDevice.BOND_BONDING) { return false; diff --git a/src/com/android/bluetooth/opp/BluetoothOppHandoverReceiver.java b/src/com/android/bluetooth/opp/BluetoothOppHandoverReceiver.java index c2cd172d0..5b3777bb7 100644 --- a/src/com/android/bluetooth/opp/BluetoothOppHandoverReceiver.java +++ b/src/com/android/bluetooth/opp/BluetoothOppHandoverReceiver.java @@ -50,7 +50,7 @@ public class BluetoothOppHandoverReceiver extends BroadcastReceiver { // Save type/stream, will be used when adding transfer // session to DB. BluetoothOppManager.getInstance(context).saveSendingFileInfo(type, - stream.toString(), true); + stream.toString(), true, false); } else { if (D) Log.d(TAG, "No mimeType or stream attached to handover request"); } @@ -60,7 +60,7 @@ public class BluetoothOppHandoverReceiver extends BroadcastReceiver { uris = intent.getParcelableArrayListExtra(Intent.EXTRA_STREAM); if (mimeType != null && uris != null) { BluetoothOppManager.getInstance(context).saveSendingFileInfo(mimeType, - uris, true); + uris, true /* isHandover */, true /* fromExternal */); } else { if (D) Log.d(TAG, "No mimeType or stream attached to handover request"); return; diff --git a/src/com/android/bluetooth/opp/BluetoothOppLauncherActivity.java b/src/com/android/bluetooth/opp/BluetoothOppLauncherActivity.java index 39116a0d3..b0ff6d9e6 100644 --- a/src/com/android/bluetooth/opp/BluetoothOppLauncherActivity.java +++ b/src/com/android/bluetooth/opp/BluetoothOppLauncherActivity.java @@ -112,7 +112,8 @@ public class BluetoothOppLauncherActivity extends Activity { Thread t = new Thread(new Runnable() { public void run() { BluetoothOppManager.getInstance(BluetoothOppLauncherActivity.this) - .saveSendingFileInfo(type,stream.toString(), false); + .saveSendingFileInfo(type,stream.toString(), + false /* isHandover */, true /* fromExternal */); //Done getting file info..Launch device picker and finish this activity launchDevicePicker(); finish(); @@ -128,7 +129,8 @@ public class BluetoothOppLauncherActivity extends Activity { Thread t = new Thread(new Runnable() { public void run() { BluetoothOppManager.getInstance(BluetoothOppLauncherActivity.this) - .saveSendingFileInfo(type,fileUri.toString(), false); + .saveSendingFileInfo(type,fileUri.toString(), + false /* isHandover */, false /* fromExternal */); //Done getting file info..Launch device picker //and finish this activity launchDevicePicker(); @@ -156,7 +158,8 @@ public class BluetoothOppLauncherActivity extends Activity { Thread t = new Thread(new Runnable() { public void run() { BluetoothOppManager.getInstance(BluetoothOppLauncherActivity.this) - .saveSendingFileInfo(mimeType,uris, false); + .saveSendingFileInfo(mimeType,uris, + false /* isHandover */, true /* fromExternal */); //Done getting file info..Launch device picker //and finish this activity launchDevicePicker(); diff --git a/src/com/android/bluetooth/opp/BluetoothOppManager.java b/src/com/android/bluetooth/opp/BluetoothOppManager.java index b9c0a8a60..407552a1c 100644 --- a/src/com/android/bluetooth/opp/BluetoothOppManager.java +++ b/src/com/android/bluetooth/opp/BluetoothOppManager.java @@ -251,14 +251,15 @@ public class BluetoothOppManager { if (V) Log.v(TAG, "Application data stored to SharedPreference! "); } - public void saveSendingFileInfo(String mimeType, String uriString, boolean isHandover) { + public void saveSendingFileInfo(String mimeType, String uriString, boolean isHandover, + boolean fromExternal) { synchronized (BluetoothOppManager.this) { mMultipleFlag = false; mMimeTypeOfSendingFile = mimeType; mIsHandoverInitiated = isHandover; Uri uri = Uri.parse(uriString); BluetoothOppSendFileInfo sendFileInfo = - BluetoothOppSendFileInfo.generateFileInfo(mContext, uri, mimeType); + BluetoothOppSendFileInfo.generateFileInfo(mContext, uri, mimeType, fromExternal); uri = BluetoothOppUtility.generateUri(uri, sendFileInfo); BluetoothOppUtility.putSendFileInfo(uri, sendFileInfo); mUriOfSendingFile = uri.toString(); @@ -267,7 +268,8 @@ public class BluetoothOppManager { } } - public void saveSendingFileInfo(String mimeType, ArrayList<Uri> uris, boolean isHandover) { + public void saveSendingFileInfo(String mimeType, ArrayList<Uri> uris, boolean isHandover, + boolean fromExternal) { synchronized (BluetoothOppManager.this) { mMultipleFlag = true; mMimeTypeOfSendingFiles = mimeType; @@ -275,7 +277,7 @@ public class BluetoothOppManager { mIsHandoverInitiated = isHandover; for (Uri uri : uris) { BluetoothOppSendFileInfo sendFileInfo = - BluetoothOppSendFileInfo.generateFileInfo(mContext, uri, mimeType); + BluetoothOppSendFileInfo.generateFileInfo(mContext, uri, mimeType, fromExternal); uri = BluetoothOppUtility.generateUri(uri, sendFileInfo); mUrisOfSendingFiles.add(uri); BluetoothOppUtility.putSendFileInfo(uri, sendFileInfo); diff --git a/src/com/android/bluetooth/opp/BluetoothOppSendFileInfo.java b/src/com/android/bluetooth/opp/BluetoothOppSendFileInfo.java index 7c75d950f..724d75b5a 100644 --- a/src/com/android/bluetooth/opp/BluetoothOppSendFileInfo.java +++ b/src/com/android/bluetooth/opp/BluetoothOppSendFileInfo.java @@ -41,6 +41,7 @@ import android.database.CursorWindowAllocationException; import android.database.sqlite.SQLiteException; import android.net.Uri; import android.provider.OpenableColumns; +import android.util.EventLog; import android.util.Log; import java.io.File; @@ -99,8 +100,8 @@ public class BluetoothOppSendFileInfo { mStatus = status; } - public static BluetoothOppSendFileInfo generateFileInfo(Context context, Uri uri, - String type) { + public static BluetoothOppSendFileInfo generateFileInfo( + Context context, Uri uri, String type, boolean fromExternal) { ContentResolver contentResolver = context.getContentResolver(); String scheme = uri.getScheme(); String fileName = null; @@ -143,6 +144,16 @@ public class BluetoothOppSendFileInfo { fileName = uri.getLastPathSegment(); } } else if ("file".equals(scheme)) { + if (uri.getPath() == null) { + Log.e(TAG, "Invalid URI path: " + uri); + return SEND_FILE_INFO_ERROR; + } + if (fromExternal && !BluetoothOppUtility.isInExternalStorageDir(uri)) { + EventLog.writeEvent(0x534e4554, "35310991", -1, uri.getPath()); + Log.e(TAG, + "File based URI not in Environment.getExternalStorageDirectory() is not allowed."); + return SEND_FILE_INFO_ERROR; + } fileName = uri.getLastPathSegment(); contentType = type; File f = new File(uri.getPath()); diff --git a/src/com/android/bluetooth/opp/BluetoothOppTransferActivity.java b/src/com/android/bluetooth/opp/BluetoothOppTransferActivity.java index 78f75ed58..2020d967e 100644 --- a/src/com/android/bluetooth/opp/BluetoothOppTransferActivity.java +++ b/src/com/android/bluetooth/opp/BluetoothOppTransferActivity.java @@ -373,7 +373,7 @@ public class BluetoothOppTransferActivity extends AlertActivity implements // retry the failed transfer Uri uri = BluetoothOppUtility.originalUri(Uri.parse(mTransInfo.mFileUri)); BluetoothOppSendFileInfo sendFileInfo = - BluetoothOppSendFileInfo.generateFileInfo(this, uri, mTransInfo.mFileType); + BluetoothOppSendFileInfo.generateFileInfo(this, uri, mTransInfo.mFileType, false); uri = BluetoothOppUtility.generateUri(uri, sendFileInfo); BluetoothOppUtility.putSendFileInfo(uri, sendFileInfo); mTransInfo.mFileUri = uri.toString(); diff --git a/src/com/android/bluetooth/opp/BluetoothOppUtility.java b/src/com/android/bluetooth/opp/BluetoothOppUtility.java index f50b0fd15..4ccc3ca12 100644 --- a/src/com/android/bluetooth/opp/BluetoothOppUtility.java +++ b/src/com/android/bluetooth/opp/BluetoothOppUtility.java @@ -39,6 +39,7 @@ import com.google.android.collect.Lists; import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothDevice; import android.net.Uri; +import android.content.ContentResolver; import android.content.ContentValues; import android.content.Context; import android.content.ActivityNotFoundException; @@ -46,6 +47,7 @@ import android.content.Intent; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; import android.database.Cursor; +import android.os.Environment; import android.database.CursorWindowAllocationException; import android.database.sqlite.SQLiteException; import android.util.Log; @@ -377,4 +379,40 @@ public class BluetoothOppUtility { } } } + + /** + * Checks if the URI is in Environment.getExternalStorageDirectory() as it + * is the only directory that is possibly readable by both the sender and + * the Bluetooth process. + */ + static boolean isInExternalStorageDir(Uri uri) { + if (!ContentResolver.SCHEME_FILE.equals(uri.getScheme())) { + Log.e(TAG, "Not a file URI: " + uri); + return false; + } + final File file = new File(uri.getCanonicalUri().getPath()); + return isSameOrSubDirectory(Environment.getExternalStorageDirectory(), file); + } + + /** + * Checks, whether the child directory is the same as, or a sub-directory of the base + * directory. Neither base nor child should be null. + */ + static boolean isSameOrSubDirectory(File base, File child) { + try { + base = base.getCanonicalFile(); + child = child.getCanonicalFile(); + File parentFile = child; + while (parentFile != null) { + if (base.equals(parentFile)) { + return true; + } + parentFile = parentFile.getParentFile(); + } + return false; + } catch (IOException ex) { + Log.e(TAG, "Error while accessing file", ex); + return false; + } + } } |