OSDN Git Service

DO NOT MERGE Fix OOB read in process_l2cap_cmd
authorHansong Zhang <hsz@google.com>
Thu, 12 Apr 2018 22:50:28 +0000 (15:50 -0700)
committerMSe <mse1969@posteo.de>
Thu, 7 Jun 2018 21:13:45 +0000 (23:13 +0200)
Bug: 74202041
Bug: 74196706
Bug: 74201143
Test: manual
Change-Id: Ic25f7f3777d0375f76cc91e4d129b1636f1c388d
(cherry picked from commit ff15adf5150527db1012b9f7777066522835e2db)
CVE-2018-9359, CVE-2018-9360, CVE-2018-9361

stack/l2cap/l2c_main.c

index 911ee50..9daba01 100644 (file)
@@ -345,9 +345,17 @@ static void process_l2cap_cmd (tL2C_LCB *p_lcb, UINT8 *p, UINT16 pkt_len)
         switch (cmd_code)
         {
         case L2CAP_CMD_REJECT:
+            if (p + 2 > p_next_cmd) {
+              android_errorWriteLog(0x534e4554, "74202041");
+              return;
+            }
             STREAM_TO_UINT16 (rej_reason, p);
             if (rej_reason == L2CAP_CMD_REJ_MTU_EXCEEDED)
             {
+                if (p + 2 > p_next_cmd) {
+                  android_errorWriteLog(0x534e4554, "74202041");
+                  return;
+                }
                 STREAM_TO_UINT16 (rej_mtu, p);
                 /* What to do with the MTU reject ? We have negotiated an MTU. For now */
                 /* we will ignore it and let a higher protocol timeout take care of it */
@@ -356,6 +364,10 @@ static void process_l2cap_cmd (tL2C_LCB *p_lcb, UINT8 *p, UINT16 pkt_len)
             }
             if (rej_reason == L2CAP_CMD_REJ_INVALID_CID)
             {
+                if (p + 4 > p_next_cmd) {
+                  android_errorWriteLog(0x534e4554, "74202041");
+                  return;
+                }
                 STREAM_TO_UINT16 (rcid, p);
                 STREAM_TO_UINT16 (lcid, p);
 
@@ -388,6 +400,10 @@ static void process_l2cap_cmd (tL2C_LCB *p_lcb, UINT8 *p, UINT16 pkt_len)
             break;
 
         case L2CAP_CMD_CONN_REQ:
+            if (p + 4 > p_next_cmd) {
+              android_errorWriteLog(0x534e4554, "74202041");
+              return;
+            }
             STREAM_TO_UINT16 (con_info.psm, p);
             STREAM_TO_UINT16 (rcid, p);
             if ((p_rcb = l2cu_find_rcb_by_psm (con_info.psm)) == NULL)
@@ -419,6 +435,10 @@ static void process_l2cap_cmd (tL2C_LCB *p_lcb, UINT8 *p, UINT16 pkt_len)
             break;
 
         case L2CAP_CMD_CONN_RSP:
+            if (p + 8 > p_next_cmd) {
+              android_errorWriteLog(0x534e4554, "74202041");
+              return;
+            }
             STREAM_TO_UINT16 (con_info.remote_cid, p);
             STREAM_TO_UINT16 (lcid, p);
             STREAM_TO_UINT16 (con_info.l2cap_result, p);
@@ -451,6 +471,10 @@ static void process_l2cap_cmd (tL2C_LCB *p_lcb, UINT8 *p, UINT16 pkt_len)
             cfg_rej = FALSE;
             cfg_rej_len = 0;
 
+            if (p + 4 > p_next_cmd) {
+              android_errorWriteLog(0x534e4554, "74202041");
+              return;
+            }
             STREAM_TO_UINT16 (lcid, p);
             STREAM_TO_UINT16 (cfg_info.flags, p);
 
@@ -461,6 +485,10 @@ static void process_l2cap_cmd (tL2C_LCB *p_lcb, UINT8 *p, UINT16 pkt_len)
 
             while (p < p_cfg_end)
             {
+                if (p + 2 > p_next_cmd) {
+                  android_errorWriteLog(0x534e4554, "74202041");
+                  return;
+                }
                 STREAM_TO_UINT8 (cfg_code, p);
                 STREAM_TO_UINT8 (cfg_len, p);
 
@@ -468,16 +496,28 @@ static void process_l2cap_cmd (tL2C_LCB *p_lcb, UINT8 *p, UINT16 pkt_len)
                 {
                 case L2CAP_CFG_TYPE_MTU:
                     cfg_info.mtu_present = TRUE;
+                    if (p + 2 > p_next_cmd) {
+                      android_errorWriteLog(0x534e4554, "74202041");
+                      return;
+                    }
                     STREAM_TO_UINT16 (cfg_info.mtu, p);
                     break;
 
                 case L2CAP_CFG_TYPE_FLUSH_TOUT:
                     cfg_info.flush_to_present = TRUE;
+                    if (p + 2 > p_next_cmd) {
+                      android_errorWriteLog(0x534e4554, "74202041");
+                      return;
+                    }
                     STREAM_TO_UINT16 (cfg_info.flush_to, p);
                     break;
 
                 case L2CAP_CFG_TYPE_QOS:
                     cfg_info.qos_present = TRUE;
+                    if (p + 2 + 5 * 4 > p_next_cmd) {
+                      android_errorWriteLog(0x534e4554, "74202041");
+                      return;
+                    }
                     STREAM_TO_UINT8  (cfg_info.qos.qos_flags, p);
                     STREAM_TO_UINT8  (cfg_info.qos.service_type, p);
                     STREAM_TO_UINT32 (cfg_info.qos.token_rate, p);
@@ -489,6 +529,10 @@ static void process_l2cap_cmd (tL2C_LCB *p_lcb, UINT8 *p, UINT16 pkt_len)
 
                 case L2CAP_CFG_TYPE_FCR:
                     cfg_info.fcr_present = TRUE;
+                    if (p + 3 + 3 * 2 > p_next_cmd) {
+                      android_errorWriteLog(0x534e4554, "74202041");
+                      return;
+                    }
                     STREAM_TO_UINT8 (cfg_info.fcr.mode, p);
                     STREAM_TO_UINT8 (cfg_info.fcr.tx_win_sz, p);
                     STREAM_TO_UINT8 (cfg_info.fcr.max_transmit, p);
@@ -499,11 +543,19 @@ static void process_l2cap_cmd (tL2C_LCB *p_lcb, UINT8 *p, UINT16 pkt_len)
 
                 case L2CAP_CFG_TYPE_FCS:
                     cfg_info.fcs_present = TRUE;
+                    if (p + 1 > p_next_cmd) {
+                      android_errorWriteLog(0x534e4554, "74202041");
+                      return;
+                    }
                     STREAM_TO_UINT8 (cfg_info.fcs, p);
                     break;
 
                 case L2CAP_CFG_TYPE_EXT_FLOW:
                     cfg_info.ext_flow_spec_present = TRUE;
+                    if (p + 2 + 2 + 3 * 4 > p_next_cmd) {
+                      android_errorWriteLog(0x534e4554, "74202041");
+                      return;
+                    }
                     STREAM_TO_UINT8  (cfg_info.ext_flow_spec.id, p);
                     STREAM_TO_UINT8  (cfg_info.ext_flow_spec.stype, p);
                     STREAM_TO_UINT16 (cfg_info.ext_flow_spec.max_sdu_size, p);
@@ -554,6 +606,10 @@ static void process_l2cap_cmd (tL2C_LCB *p_lcb, UINT8 *p, UINT16 pkt_len)
 
         case L2CAP_CMD_CONFIG_RSP:
             p_cfg_end = p + cmd_len;
+            if (p + 6 > p_next_cmd) {
+              android_errorWriteLog(0x534e4554, "74202041");
+              return;
+            }
             STREAM_TO_UINT16 (lcid, p);
             STREAM_TO_UINT16 (cfg_info.flags, p);
             STREAM_TO_UINT16 (cfg_info.result, p);
@@ -563,6 +619,10 @@ static void process_l2cap_cmd (tL2C_LCB *p_lcb, UINT8 *p, UINT16 pkt_len)
 
             while (p < p_cfg_end)
             {
+                if (p + 2 > p_next_cmd) {
+                  android_errorWriteLog(0x534e4554, "74202041");
+                  return;
+                }
                 STREAM_TO_UINT8 (cfg_code, p);
                 STREAM_TO_UINT8 (cfg_len, p);
 
@@ -570,16 +630,28 @@ static void process_l2cap_cmd (tL2C_LCB *p_lcb, UINT8 *p, UINT16 pkt_len)
                 {
                 case L2CAP_CFG_TYPE_MTU:
                     cfg_info.mtu_present = TRUE;
+                    if (p + 2 > p_next_cmd) {
+                      android_errorWriteLog(0x534e4554, "74202041");
+                      return;
+                    }
                     STREAM_TO_UINT16 (cfg_info.mtu, p);
                     break;
 
                 case L2CAP_CFG_TYPE_FLUSH_TOUT:
                     cfg_info.flush_to_present = TRUE;
+                    if (p + 2 > p_next_cmd) {
+                      android_errorWriteLog(0x534e4554, "74202041");
+                      return;
+                    }
                     STREAM_TO_UINT16 (cfg_info.flush_to, p);
                     break;
 
                 case L2CAP_CFG_TYPE_QOS:
                     cfg_info.qos_present = TRUE;
+                    if (p + 2 + 5 * 4 > p_next_cmd) {
+                      android_errorWriteLog(0x534e4554, "74202041");
+                      return;
+                    }
                     STREAM_TO_UINT8  (cfg_info.qos.qos_flags, p);
                     STREAM_TO_UINT8  (cfg_info.qos.service_type, p);
                     STREAM_TO_UINT32 (cfg_info.qos.token_rate, p);
@@ -591,6 +663,10 @@ static void process_l2cap_cmd (tL2C_LCB *p_lcb, UINT8 *p, UINT16 pkt_len)
 
                 case L2CAP_CFG_TYPE_FCR:
                     cfg_info.fcr_present = TRUE;
+                    if (p + 3 + 3 * 2 > p_next_cmd) {
+                      android_errorWriteLog(0x534e4554, "74202041");
+                      return;
+                    }
                     STREAM_TO_UINT8 (cfg_info.fcr.mode, p);
                     STREAM_TO_UINT8 (cfg_info.fcr.tx_win_sz, p);
                     STREAM_TO_UINT8 (cfg_info.fcr.max_transmit, p);
@@ -601,11 +677,19 @@ static void process_l2cap_cmd (tL2C_LCB *p_lcb, UINT8 *p, UINT16 pkt_len)
 
                 case L2CAP_CFG_TYPE_FCS:
                     cfg_info.fcs_present = TRUE;
+                    if (p + 1 > p_next_cmd) {
+                      android_errorWriteLog(0x534e4554, "74202041");
+                      return;
+                    }
                     STREAM_TO_UINT8 (cfg_info.fcs, p);
                     break;
 
                 case L2CAP_CFG_TYPE_EXT_FLOW:
                     cfg_info.ext_flow_spec_present = TRUE;
+                    if (p + 2 + 2 + 3 * 4 > p_next_cmd) {
+                      android_errorWriteLog(0x534e4554, "74202041");
+                      return;
+                    }
                     STREAM_TO_UINT8  (cfg_info.ext_flow_spec.id, p);
                     STREAM_TO_UINT8  (cfg_info.ext_flow_spec.stype, p);
                     STREAM_TO_UINT16 (cfg_info.ext_flow_spec.max_sdu_size, p);
@@ -636,6 +720,10 @@ static void process_l2cap_cmd (tL2C_LCB *p_lcb, UINT8 *p, UINT16 pkt_len)
             break;
 
         case L2CAP_CMD_DISC_REQ:
+            if (p + 4 > p_next_cmd) {
+              android_errorWriteLog(0x534e4554, "74202041");
+              return;
+            }
             STREAM_TO_UINT16 (lcid, p);
             STREAM_TO_UINT16 (rcid, p);
 
@@ -653,6 +741,10 @@ static void process_l2cap_cmd (tL2C_LCB *p_lcb, UINT8 *p, UINT16 pkt_len)
             break;
 
         case L2CAP_CMD_DISC_RSP:
+            if (p + 4 > p_next_cmd) {
+              android_errorWriteLog(0x534e4554, "74202041");
+              return;
+            }
             STREAM_TO_UINT16 (rcid, p);
             STREAM_TO_UINT16 (lcid, p);
 
@@ -682,6 +774,10 @@ static void process_l2cap_cmd (tL2C_LCB *p_lcb, UINT8 *p, UINT16 pkt_len)
             break;
 
         case L2CAP_CMD_INFO_REQ:
+            if (p + 2 > p_next_cmd) {
+              android_errorWriteLog(0x534e4554, "74202041");
+              return;
+            }
             STREAM_TO_UINT16 (info_type, p);
             l2cu_send_peer_info_rsp (p_lcb, id, info_type);
             break;
@@ -694,6 +790,10 @@ static void process_l2cap_cmd (tL2C_LCB *p_lcb, UINT8 *p, UINT16 pkt_len)
                 p_lcb->w4_info_rsp = FALSE;
             }
 
+            if (p + 4 > p_next_cmd) {
+              android_errorWriteLog(0x534e4554, "74202041");
+              return;
+            }
             STREAM_TO_UINT16 (info_type, p);
             STREAM_TO_UINT16 (result, p);
 
@@ -702,6 +802,10 @@ static void process_l2cap_cmd (tL2C_LCB *p_lcb, UINT8 *p, UINT16 pkt_len)
             if ( (info_type == L2CAP_EXTENDED_FEATURES_INFO_TYPE)
               && (result == L2CAP_INFO_RESP_RESULT_SUCCESS) )
             {
+                if (p + 4 > p_next_cmd) {
+                  android_errorWriteLog(0x534e4554, "74202041");
+                  return;
+                }
                 STREAM_TO_UINT32( p_lcb->peer_ext_fea, p );
 
 #if (L2CAP_NUM_FIXED_CHNLS > 0)