aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJake Hamby <jhamby@google.com>2013-12-03 13:21:40 -0800
committerJake Hamby <jhamby@google.com>2013-12-03 23:24:38 +0000
commit023346cf9050c146a36eedd14886d0e9a679dc49 (patch)
treed902aafb8b004af19288b8f82afd5a74c9751a3a
parent449cbf85380bd1d6716b7ab002da1efb9493bb02 (diff)
downloadtelephony-023346cf9050c146a36eedd14886d0e9a679dc49.tar.gz
Fix OOBE crash/DoS after receiving 0-byte WAP push.android-sdk-4.4.2_r1.0.1android-sdk-4.4.2_r1
Add a try/catch block around the code in WapPushOverSms.dispatchWapPdu(), so we don't get into a reboot trap on receiving weirdly formed messages. Only catch ArrayIndexOutOfBoundsException, which is difficult to prevent inside dispatchWapPdu() for 0-byte PDUs or other unusual contents. The caller should probably catch any unhandled exceptions of other types and log them with stack traces. Bug: 11967705 Change-Id: Iabfec68d2564dd438d45c80cdba877bf19fa0397
-rwxr-xr-xsrc/java/com/android/internal/telephony/WapPushOverSms.java293
1 files changed, 150 insertions, 143 deletions
diff --git a/src/java/com/android/internal/telephony/WapPushOverSms.java b/src/java/com/android/internal/telephony/WapPushOverSms.java
index 87b38109a8..2f22794cbf 100755
--- a/src/java/com/android/internal/telephony/WapPushOverSms.java
+++ b/src/java/com/android/internal/telephony/WapPushOverSms.java
@@ -90,168 +90,175 @@ public class WapPushOverSms implements ServiceConnection {
if (DBG) Rlog.d(TAG, "Rx: " + IccUtils.bytesToHexString(pdu));
- int index = 0;
- int transactionId = pdu[index++] & 0xFF;
- int pduType = pdu[index++] & 0xFF;
-
- if ((pduType != WspTypeDecoder.PDU_TYPE_PUSH) &&
- (pduType != WspTypeDecoder.PDU_TYPE_CONFIRMED_PUSH)) {
- index = mContext.getResources().getInteger(
- com.android.internal.R.integer.config_valid_wappush_index);
- if(index != -1) {
- transactionId = pdu[index++] & 0xff;
- pduType = pdu[index++] & 0xff;
- if (DBG)
- Rlog.d(TAG, "index = " + index + " PDU Type = " + pduType +
- " transactionID = " + transactionId);
-
- // recheck wap push pduType
- if ((pduType != WspTypeDecoder.PDU_TYPE_PUSH)
- && (pduType != WspTypeDecoder.PDU_TYPE_CONFIRMED_PUSH)) {
+ try {
+ int index = 0;
+ int transactionId = pdu[index++] & 0xFF;
+ int pduType = pdu[index++] & 0xFF;
+
+ if ((pduType != WspTypeDecoder.PDU_TYPE_PUSH) &&
+ (pduType != WspTypeDecoder.PDU_TYPE_CONFIRMED_PUSH)) {
+ index = mContext.getResources().getInteger(
+ com.android.internal.R.integer.config_valid_wappush_index);
+ if (index != -1) {
+ transactionId = pdu[index++] & 0xff;
+ pduType = pdu[index++] & 0xff;
+ if (DBG)
+ Rlog.d(TAG, "index = " + index + " PDU Type = " + pduType +
+ " transactionID = " + transactionId);
+
+ // recheck wap push pduType
+ if ((pduType != WspTypeDecoder.PDU_TYPE_PUSH)
+ && (pduType != WspTypeDecoder.PDU_TYPE_CONFIRMED_PUSH)) {
+ if (DBG) Rlog.w(TAG, "Received non-PUSH WAP PDU. Type = " + pduType);
+ return Intents.RESULT_SMS_HANDLED;
+ }
+ } else {
if (DBG) Rlog.w(TAG, "Received non-PUSH WAP PDU. Type = " + pduType);
return Intents.RESULT_SMS_HANDLED;
}
- } else {
- if (DBG) Rlog.w(TAG, "Received non-PUSH WAP PDU. Type = " + pduType);
- return Intents.RESULT_SMS_HANDLED;
}
- }
-
- WspTypeDecoder pduDecoder = new WspTypeDecoder(pdu);
- /**
- * Parse HeaderLen(unsigned integer).
- * From wap-230-wsp-20010705-a section 8.1.2
- * The maximum size of a uintvar is 32 bits.
- * So it will be encoded in no more than 5 octets.
- */
- if (pduDecoder.decodeUintvarInteger(index) == false) {
- if (DBG) Rlog.w(TAG, "Received PDU. Header Length error.");
- return Intents.RESULT_SMS_GENERIC_ERROR;
- }
- int headerLength = (int) pduDecoder.getValue32();
- index += pduDecoder.getDecodedDataLength();
-
- int headerStartIndex = index;
-
- /**
- * Parse Content-Type.
- * From wap-230-wsp-20010705-a section 8.4.2.24
- *
- * Content-type-value = Constrained-media | Content-general-form
- * Content-general-form = Value-length Media-type
- * Media-type = (Well-known-media | Extension-Media) *(Parameter)
- * Value-length = Short-length | (Length-quote Length)
- * Short-length = <Any octet 0-30> (octet <= WAP_PDU_SHORT_LENGTH_MAX)
- * Length-quote = <Octet 31> (WAP_PDU_LENGTH_QUOTE)
- * Length = Uintvar-integer
- */
- if (pduDecoder.decodeContentType(index) == false) {
- if (DBG) Rlog.w(TAG, "Received PDU. Header Content-Type error.");
- return Intents.RESULT_SMS_GENERIC_ERROR;
- }
-
- String mimeType = pduDecoder.getValueString();
- long binaryContentType = pduDecoder.getValue32();
- index += pduDecoder.getDecodedDataLength();
+ WspTypeDecoder pduDecoder = new WspTypeDecoder(pdu);
+
+ /**
+ * Parse HeaderLen(unsigned integer).
+ * From wap-230-wsp-20010705-a section 8.1.2
+ * The maximum size of a uintvar is 32 bits.
+ * So it will be encoded in no more than 5 octets.
+ */
+ if (pduDecoder.decodeUintvarInteger(index) == false) {
+ if (DBG) Rlog.w(TAG, "Received PDU. Header Length error.");
+ return Intents.RESULT_SMS_GENERIC_ERROR;
+ }
+ int headerLength = (int) pduDecoder.getValue32();
+ index += pduDecoder.getDecodedDataLength();
+
+ int headerStartIndex = index;
+
+ /**
+ * Parse Content-Type.
+ * From wap-230-wsp-20010705-a section 8.4.2.24
+ *
+ * Content-type-value = Constrained-media | Content-general-form
+ * Content-general-form = Value-length Media-type
+ * Media-type = (Well-known-media | Extension-Media) *(Parameter)
+ * Value-length = Short-length | (Length-quote Length)
+ * Short-length = <Any octet 0-30> (octet <= WAP_PDU_SHORT_LENGTH_MAX)
+ * Length-quote = <Octet 31> (WAP_PDU_LENGTH_QUOTE)
+ * Length = Uintvar-integer
+ */
+ if (pduDecoder.decodeContentType(index) == false) {
+ if (DBG) Rlog.w(TAG, "Received PDU. Header Content-Type error.");
+ return Intents.RESULT_SMS_GENERIC_ERROR;
+ }
- byte[] header = new byte[headerLength];
- System.arraycopy(pdu, headerStartIndex, header, 0, header.length);
+ String mimeType = pduDecoder.getValueString();
+ long binaryContentType = pduDecoder.getValue32();
+ index += pduDecoder.getDecodedDataLength();
- byte[] intentData;
+ byte[] header = new byte[headerLength];
+ System.arraycopy(pdu, headerStartIndex, header, 0, header.length);
- if (mimeType != null && mimeType.equals(WspTypeDecoder.CONTENT_TYPE_B_PUSH_CO)) {
- intentData = pdu;
- } else {
- int dataIndex = headerStartIndex + headerLength;
- intentData = new byte[pdu.length - dataIndex];
- System.arraycopy(pdu, dataIndex, intentData, 0, intentData.length);
- }
+ byte[] intentData;
- /**
- * Seek for application ID field in WSP header.
- * If application ID is found, WapPushManager substitute the message
- * processing. Since WapPushManager is optional module, if WapPushManager
- * is not found, legacy message processing will be continued.
- */
- if (pduDecoder.seekXWapApplicationId(index, index + headerLength - 1)) {
- index = (int) pduDecoder.getValue32();
- pduDecoder.decodeXWapApplicationId(index);
- String wapAppId = pduDecoder.getValueString();
- if (wapAppId == null) {
- wapAppId = Integer.toString((int) pduDecoder.getValue32());
+ if (mimeType != null && mimeType.equals(WspTypeDecoder.CONTENT_TYPE_B_PUSH_CO)) {
+ intentData = pdu;
+ } else {
+ int dataIndex = headerStartIndex + headerLength;
+ intentData = new byte[pdu.length - dataIndex];
+ System.arraycopy(pdu, dataIndex, intentData, 0, intentData.length);
}
- String contentType = ((mimeType == null) ?
- Long.toString(binaryContentType) : mimeType);
- if (DBG) Rlog.v(TAG, "appid found: " + wapAppId + ":" + contentType);
-
- try {
- boolean processFurther = true;
- IWapPushManager wapPushMan = mWapPushManager;
+ /**
+ * Seek for application ID field in WSP header.
+ * If application ID is found, WapPushManager substitute the message
+ * processing. Since WapPushManager is optional module, if WapPushManager
+ * is not found, legacy message processing will be continued.
+ */
+ if (pduDecoder.seekXWapApplicationId(index, index + headerLength - 1)) {
+ index = (int) pduDecoder.getValue32();
+ pduDecoder.decodeXWapApplicationId(index);
+ String wapAppId = pduDecoder.getValueString();
+ if (wapAppId == null) {
+ wapAppId = Integer.toString((int) pduDecoder.getValue32());
+ }
- if (wapPushMan == null) {
- if (DBG) Rlog.w(TAG, "wap push manager not found!");
- } else {
- Intent intent = new Intent();
- intent.putExtra("transactionId", transactionId);
- intent.putExtra("pduType", pduType);
- intent.putExtra("header", header);
- intent.putExtra("data", intentData);
- intent.putExtra("contentTypeParameters",
- pduDecoder.getContentParameters());
-
- int procRet = wapPushMan.processMessage(wapAppId, contentType, intent);
- if (DBG) Rlog.v(TAG, "procRet:" + procRet);
- if ((procRet & WapPushManagerParams.MESSAGE_HANDLED) > 0
- && (procRet & WapPushManagerParams.FURTHER_PROCESSING) == 0) {
- processFurther = false;
+ String contentType = ((mimeType == null) ?
+ Long.toString(binaryContentType) : mimeType);
+ if (DBG) Rlog.v(TAG, "appid found: " + wapAppId + ":" + contentType);
+
+ try {
+ boolean processFurther = true;
+ IWapPushManager wapPushMan = mWapPushManager;
+
+ if (wapPushMan == null) {
+ if (DBG) Rlog.w(TAG, "wap push manager not found!");
+ } else {
+ Intent intent = new Intent();
+ intent.putExtra("transactionId", transactionId);
+ intent.putExtra("pduType", pduType);
+ intent.putExtra("header", header);
+ intent.putExtra("data", intentData);
+ intent.putExtra("contentTypeParameters",
+ pduDecoder.getContentParameters());
+
+ int procRet = wapPushMan.processMessage(wapAppId, contentType, intent);
+ if (DBG) Rlog.v(TAG, "procRet:" + procRet);
+ if ((procRet & WapPushManagerParams.MESSAGE_HANDLED) > 0
+ && (procRet & WapPushManagerParams.FURTHER_PROCESSING) == 0) {
+ processFurther = false;
+ }
}
+ if (!processFurther) {
+ return Intents.RESULT_SMS_HANDLED;
+ }
+ } catch (RemoteException e) {
+ if (DBG) Rlog.w(TAG, "remote func failed...");
}
- if (!processFurther) {
- return Intents.RESULT_SMS_HANDLED;
- }
- } catch (RemoteException e) {
- if (DBG) Rlog.w(TAG, "remote func failed...");
}
- }
- if (DBG) Rlog.v(TAG, "fall back to existing handler");
+ if (DBG) Rlog.v(TAG, "fall back to existing handler");
- if (mimeType == null) {
- if (DBG) Rlog.w(TAG, "Header Content-Type error.");
- return Intents.RESULT_SMS_GENERIC_ERROR;
- }
+ if (mimeType == null) {
+ if (DBG) Rlog.w(TAG, "Header Content-Type error.");
+ return Intents.RESULT_SMS_GENERIC_ERROR;
+ }
- String permission;
- int appOp;
+ String permission;
+ int appOp;
- if (mimeType.equals(WspTypeDecoder.CONTENT_TYPE_B_MMS)) {
- permission = android.Manifest.permission.RECEIVE_MMS;
- appOp = AppOpsManager.OP_RECEIVE_MMS;
- } else {
- permission = android.Manifest.permission.RECEIVE_WAP_PUSH;
- appOp = AppOpsManager.OP_RECEIVE_WAP_PUSH;
- }
+ if (mimeType.equals(WspTypeDecoder.CONTENT_TYPE_B_MMS)) {
+ permission = android.Manifest.permission.RECEIVE_MMS;
+ appOp = AppOpsManager.OP_RECEIVE_MMS;
+ } else {
+ permission = android.Manifest.permission.RECEIVE_WAP_PUSH;
+ appOp = AppOpsManager.OP_RECEIVE_WAP_PUSH;
+ }
- Intent intent = new Intent(Intents.WAP_PUSH_DELIVER_ACTION);
- intent.setType(mimeType);
- intent.putExtra("transactionId", transactionId);
- intent.putExtra("pduType", pduType);
- intent.putExtra("header", header);
- intent.putExtra("data", intentData);
- intent.putExtra("contentTypeParameters", pduDecoder.getContentParameters());
-
- // Direct the intent to only the default MMS app. If we can't find a default MMS app
- // then sent it to all broadcast receivers.
- ComponentName componentName = SmsApplication.getDefaultMmsApplication(mContext, true);
- if (componentName != null) {
- // Deliver MMS message only to this receiver
- intent.setComponent(componentName);
- if (DBG) Rlog.v(TAG, "Delivering MMS to: " + componentName.getPackageName() +
- " " + componentName.getClassName());
- }
+ Intent intent = new Intent(Intents.WAP_PUSH_DELIVER_ACTION);
+ intent.setType(mimeType);
+ intent.putExtra("transactionId", transactionId);
+ intent.putExtra("pduType", pduType);
+ intent.putExtra("header", header);
+ intent.putExtra("data", intentData);
+ intent.putExtra("contentTypeParameters", pduDecoder.getContentParameters());
+
+ // Direct the intent to only the default MMS app. If we can't find a default MMS app
+ // then sent it to all broadcast receivers.
+ ComponentName componentName = SmsApplication.getDefaultMmsApplication(mContext, true);
+ if (componentName != null) {
+ // Deliver MMS message only to this receiver
+ intent.setComponent(componentName);
+ if (DBG) Rlog.v(TAG, "Delivering MMS to: " + componentName.getPackageName() +
+ " " + componentName.getClassName());
+ }
- handler.dispatchIntent(intent, permission, appOp, receiver);
- return Activity.RESULT_OK;
+ handler.dispatchIntent(intent, permission, appOp, receiver);
+ return Activity.RESULT_OK;
+ } catch (ArrayIndexOutOfBoundsException aie) {
+ // 0-byte WAP PDU or other unexpected WAP PDU contents can easily throw this;
+ // log exception string without stack trace and return false.
+ Rlog.e(TAG, "ignoring dispatchWapPdu() array index exception: " + aie);
+ return Intents.RESULT_SMS_GENERIC_ERROR;
+ }
}
}