OSDN Git Service

HFP: Fix out of bound access in phone number processing
authorHansong Zhang <hsz@google.com>
Wed, 27 Jun 2018 21:21:40 +0000 (14:21 -0700)
committerandroid-build-team Robot <android-build-team-robot@google.com>
Fri, 27 Jul 2018 18:45:20 +0000 (18:45 +0000)
* Write at most sizeof(dialnum) chars into dialnum array in ClccResponse
  method
* Write at most sizeof(ag_res.str) - 5 chars into ag_res.str array in
  PhoneStateChange method

Bug: 79431031
Bug: 79266386
Test: make call with super long phone numbers
Change-Id: I98e7687ac4055800aa46626c6b1c866e52e474df
(cherry picked from commit 5c0888d42d9aa29dbecd77d3443fa066cdb4e13d)

btif/src/btif_hf.cc

index 5388986..37f9471 100644 (file)
@@ -1032,12 +1032,20 @@ bt_status_t HeadsetInterface::ClccResponse(
         dialnum[newidx++] = '+';
       }
       for (size_t i = 0; number[i] != 0; i++) {
+        if (newidx >= (sizeof(dialnum) - res_strlen - 1)) {
+          android_errorWriteLog(0x534e4554, "79266386");
+          break;
+        }
         if (utl_isdialchar(number[i])) {
           dialnum[newidx++] = number[i];
         }
       }
       dialnum[newidx] = 0;
-      snprintf(&ag_res.str[res_strlen], rem_bytes, ",\"%s\",%d", dialnum, type);
+      // Reserve 5 bytes for ["][,][3_digit_type]
+      snprintf(&ag_res.str[res_strlen], rem_bytes - 5, ",\"%s", dialnum);
+      std::stringstream remaining_string;
+      remaining_string << "\"," << type;
+      strncat(&ag_res.str[res_strlen], remaining_string.str().c_str(), 5);
     }
   }
   BTA_AgResult(btif_hf_cb[idx].handle, BTA_AG_CLCC_RES, ag_res);
@@ -1184,6 +1192,13 @@ bt_status_t HeadsetInterface::PhoneStateChange(
           else
             xx = snprintf(ag_res.str, sizeof(ag_res.str), "\"%s\"", number);
           ag_res.num = type;
+          // 5 = [,][3_digit_type][null_terminator]
+          if (xx > static_cast<int>(sizeof(ag_res.str) - 5)) {
+            android_errorWriteLog(0x534e4554, "79431031");
+            xx = sizeof(ag_res.str) - 5;
+            // Null terminating the string
+            memset(&ag_res.str[xx], 0, 5);
+          }
 
           if (res == BTA_AG_CALL_WAIT_RES)
             snprintf(&ag_res.str[xx], sizeof(ag_res.str) - xx, ",%d", type);