[하루한줄] CVE-2021-32487: Heap Buffer overflow in GSM RRM Channel Release, Cell Selection Indicator

URL

Heap Buffer overflow in GSM RRM Channel Release, Cell Selection Indicator

Target

MediaTek Modem 2G RRM

Explain

MediaTek baseband에서 발견된 heap overflow 취약점입니다. 해당 취약점을 악용하면 baseband의 runtime 중 임의 코드 실행을 할 수 있습니다.

GSM Radio Resource Management Channel Release message의

Cell selection indicator after release of all TCH and SDCCH라는 Information element(IE:정보 요소)를 decoding 하는 과정에서 취약점이 발생합니다.

함수 FDD_rr_decode_eutran_individual_priority_para_description에서 GSM(Global System for Mobile communication) 정보를 처리하기 위해 384 byte 크기의 메모리를 할당합니다. 문제는 message stream을 decoding 했을 때 해당 메모리에 저장할 수 있는 element는 최대 96개 뿐이지만, element 개수의 최댓값을 제한하지 않아 할당된 메모리 chunk 넘어 데이터를 덮어쓸 수 있습니다.

uint FDD_csrr_decode_redirection_ie(byte **bs,short length)

{
  byte description_type_;
  ushort arfcn;
  uint uVar5;
  void *dst;
  undefined bsic;
  ushort uVar1;
  int still_has_repetition;
  uint band_indicator;
  void *pvVar2;
  int local_v0_364;
  ushort *gsm_desc_struct_iterator;
  undefined *puVar3;
  uint uVar7;
  uint gsm_desc_counter;
  undefined *puVar1;
  byte description_type;
  
  puVar1 = PTR_global_state_906094b4;
  uVar7 = *(uint *)(PTR_global_state_906094b4 + 8);
  **(short **)PTR_global_state_906094b4 = **(short **)PTR_global_state_906094b4 + -3;
                    /* RAT type */
  description_type_ = bit_stream_read(bs,3);
  *(byte *)(uVar7 + 0x8b9) = description_type_;
  dhl_brief_trace(5,0,(byte *)0xf00009e,PTR_DAT_906094b8);
  if (*(char *)(uVar7 + 0x8b9) != '\x03') {
    ppbVar6 = (byte **)FDD_rr_get_current_rr_ptr();
    mrs_set_as_reason_not_moving_to_lte((uint)ppbVar6,3);
  }
  description_type = *(byte *)(uVar7 + 0x8b9);
  if (description_type == 1) {
                    /* UTRAN FDD Description */
    if (*(int *)(uVar7 + 0x8c0) == 0) {
      pvVar2 = get_ctrl_buffer_ext(0x3c0,PTR_s_pcore/modem/gas/rrm/rmc/src/csrr_906094bc,0x136e);
      *(void **)(uVar7 + 0x8c0) = pvVar2;
    }
    __wrap_memset(*(void **)(uVar7 + 0x8c0),0,0x3c0);
    uVar5 = FDD_csrr_decode_utran_fdd_descriptions(bs,0,6,4);
  }
  else {
                    /* GSM Description */
    if (description_type == 0) {
                    /* separately handles the IEI 77 (Cell selection) length */
      if ((int)length << 3 < 0x16) {
        return 0;
      }
        /*
         * VULNERABILITY BASIS:
         *   the allocation is to a fixed size!
         */
      dst = get_ctrl_buffer_ext(0x180,PTR_s_pcore/modem/gas/rrm/rmc/src/csrr_906094bc,0x1328);

      *(void **)(uVar7 + 0x8bc) = dst;
                    /* initially allocated for 0x180 / 4 = 96 entries */
      __wrap_memset(dst,0,0x180);
      gsm_desc_struct_iterator = (ushort *)(*(int *)(uVar7 + 0x8bc) + 2);
      gsm_desc_counter = 0;
      while( true ) {
        still_has_repetition = bit_stream_read(bs,1);
        **(short **)puVar1 = **(short **)puVar1 + -1;
        
        /*
         * VULNERABILITY:
         *   the recursion only stops with the 0 bit
         *   never because it is too long!
         */
        if (still_has_repetition != 1) break;

        band_indicator = bit_stream_read(bs,1);
        arfcn = bit_stream_read(bs,10);
                    /* Write ARFCN and BSIC directly to the allocated memory */
        /*
         * MEMORY CORRUPTION HAPPENS
         */
        *gsm_desc_struct_iterator = arfcn;
        bsic = bit_stream_read(bs,6);
        *(undefined *)(gsm_desc_struct_iterator + -1) = bsic;

        **(short **)PTR_RR_GLOBAL_PTR_90601f1c = **(short **)PTR_RR_GLOBAL_PTR_90601f1c + -0x11;
        if ((band_indicator & 0xff) == 1) {
          uVar1 = FDD_rr_arfcn_PCS_band_tag((uint)*gsm_desc_struct_iterator);
          *gsm_desc_struct_iterator = uVar1;
        }
        gsm_desc_struct_iterator = gsm_desc_struct_iterator + 2;
        gsm_desc_counter = gsm_desc_counter + 1;
      }
      if (gsm_desc_counter != 0) {
        FDD_rrm_store_gsm_redirection_list(gsm_desc_counter & 0xff,0,*(void **)(uVar7 + 0x8bc),puVar3);
      }
      else {
        dhl_brief_trace(5,0,0xe60009f,0);
      }
      uVar5 = (uint)(gsm_desc_counter != 0);
                    /* free the buffer allocated in the begining of this block */
      free_ctrl_buffer_ext(*(void **)(uVar7 + 0x8bc),PTR_s_pcore/modem/gas/rrm/rmc/src/csrr_906094bc,0x1363);
      *(undefined4 *)(uVar7 + 0x8bc) = 0;
    }
    else {
      if (description_type == 3) {
                    /* E-UTRAN Description */
        uVar5 = FDD_csrr_decode_eutran_redirection_list(bs);
      }
      else {
        uVar5 = 0;
      }
    }
  }
  local_v0_364 = FDD_rr_is_GSM_ChannelLockEnable();
  if (local_v0_364 == 1) {
    uVar5 = uVar7;
  }
  return uVar5;
}


본 글은 CC BY-SA 4.0 라이선스로 배포됩니다. 공유 또는 변경 시 반드시 출처를 남겨주시기 바랍니다.