FPII-2438 : Vulnerabilities in Qualcomm components CVE-2016-6691 QC-CR#978452

Wifi gbk2utf module used weak logic to check if SSID is GBK encoded, it has chance that SSID wrongly converted and truncated, which in turn caused framework crash due to unhandled Exception. 
This change is to add isGkbString() to check if SSID is GBK encoded, which makes sure only SSID with GBK encoded will be converted.

Change-Id: Ib38fc0512d1cfb48fa2500bbcb18552e70dd5ac4
diff --git a/service/jni/com_android_server_wifi_Gbk2Utf.cpp b/service/jni/com_android_server_wifi_Gbk2Utf.cpp
index df96603..b2a6718 100755
--- a/service/jni/com_android_server_wifi_Gbk2Utf.cpp
+++ b/service/jni/com_android_server_wifi_Gbk2Utf.cpp
@@ -239,7 +239,7 @@
 }
 
 /* check if the SSID string is UTF coded */
-static bool isUTF8String(const char* str, long length)
+static bool isUTF8String(const char* str, int length)
 {
     unsigned int nBytes = 0;
     unsigned char chr;
@@ -280,6 +280,51 @@
     return true;
 }
 
+/*
+ * https://en.wikipedia.org/wiki/GBK
+ *
+ * GBK character is encoded as 1 or 2 bytes.
+ * - A single byte with range 0x00-0x7f is ASCII.
+ * - A byte with the high bit set indicates that it is
+ *   the first of 2 bytes.
+ *   byte1: (0x81-0xFE)
+ *   byte2: (0x40-0xFE) except 0x7F
+ *
+ * This function only returns true only it is GBK string
+ * but not all character is ASCII.
+ */
+static bool isGBKString(const char *str, int length) {
+    unsigned char byte1;
+    unsigned char byte2;
+    bool isAllASCII = true;
+
+    for (int i = 0; i < length; i ++) {
+        byte1 = *(str+i);
+
+        if (byte1 >= 0x81 && byte1 < 0xFF && (i+1) < length) {
+            byte2 = *(str+i+1);
+            if (byte2 >= 0x40 && byte2 < 0xFF && byte2 != 0x7F) {
+                // GBK
+                isAllASCII = false;
+                i ++;
+                continue;
+            } else {
+                return false;
+            }
+        } else if (byte1 < 0x80){
+            // ASCII
+            continue;
+        } else {
+            return false;
+        }
+    }
+
+    if (isAllASCII)
+        return false;
+
+    return true;
+}
+
 static void createFromHex(char *buf, int maxlen, const char *str)
 {
     const char *pos = str;
@@ -325,7 +370,6 @@
 {
     unsigned int lineBeg = 0, lineEnd = 0;
     size_t  replyLen = strlen(reply);
-    char    *pos = NULL;
     char    ssid[BUF_SIZE] = {0};
     char    ssid_utf8[BUF_SIZE] = {0};
     char    ssid_txt[BUF_SIZE] = {0};
@@ -351,13 +395,7 @@
                 sscanf(line.string() + 5, "%[^\n]", ssid);
                 ssid_decode(buf,BUF_SIZE,ssid);
                 isUTF8 = isUTF8String(buf,sizeof(buf));
-                isCh = false;
-                for (pos = buf; '\0' != *pos; pos++) {
-                    if (0x80 == (*pos & 0x80)) {
-                        isCh = true;
-                        break;
-                    }
-                }
+                isCh = isGBKString(buf, sizeof(buf));
                 if (DBG)
                     ALOGD("%s, ssid = %s, buf = %s,isUTF8= %d, isCh = %d",
                         __FUNCTION__, ssid, buf ,isUTF8, isCh);
@@ -406,7 +444,6 @@
     char    ssid[BUF_SIZE] = {0};
     char    buf[BUF_SIZE] = {0};
     char    ssid_txt[BUF_SIZE] ={0};
-    char    *pos = NULL;
     bool    isUTF8 = false, isCh = false;
 
     char    dest[CONVERT_LINE_LEN] = {0};
@@ -422,13 +459,7 @@
         ALOGD("%s, ssid = %s", __FUNCTION__, ssid);
     createFromHex(buf, BUF_SIZE, ssid);
     isUTF8 = isUTF8String(buf, sizeof(buf));
-    isCh = false;
-    for (pos = buf; '\0' != *pos; pos++) {
-        if (0x80 == (*pos & 0x80)) {
-            isCh = true;
-            break;
-        }
-    }
+    isCh = isGBKString(buf, sizeof(buf));
     if (!isUTF8 && isCh) {
         ucnv_toAlgorithmic(conType, pConverter, dest, CONVERT_LINE_LEN,
                             buf, strlen(buf), &err);
@@ -520,7 +551,6 @@
 
 void constructEventSsid(char *eventstr)
 {
-     char *pos = NULL;
      char *tmp = NULL;
      char ssid[BUF_SIZE] = {0};
      char ssid_txt[BUF_SIZE] = {0};
@@ -546,13 +576,7 @@
              ALOGD("%s, SSID = %s", __FUNCTION__, ssid);
          ssid_decode(buf,BUF_SIZE,ssid);
          isUTF8 = isUTF8String(buf,sizeof(buf));
-         isCh = false;
-         for (pos = buf; '\0' != *pos; pos++) {
-             if (0x80 == (*pos & 0x80)) {
-                 isCh = true;
-                 break;
-             }
-         }
+         isCh = isGBKString(buf, sizeof(buf));
          if (!isUTF8 && isCh) {
              ucnv_toAlgorithmic(conType, pConverter, dest, CONVERT_LINE_LEN,
                              buf, strlen(buf), &err);