208 lines
6.2 KiB
C++
208 lines
6.2 KiB
C++
/*
|
|
* Copyright (C) 2021 The Android Open Source Project
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
/* 'system/nfc/src/fuzzers/rw/t4t.cc' is used as reference to come up with file */
|
|
|
|
#include "fuzz.h"
|
|
|
|
#include "../includes/memutils.h"
|
|
char enable_selective_overload = ENABLE_NONE;
|
|
extern bool testInProgress;
|
|
extern char* vulnPtr;
|
|
|
|
#define MODULE_NAME "Type4 Read/Write"
|
|
|
|
enum {
|
|
SUB_TYPE_DETECT_NDEF,
|
|
SUB_TYPE_READ_NDEF,
|
|
SUB_TYPE_UPDATE_NDEF,
|
|
SUB_TYPE_PRESENCE_CHECK,
|
|
SUB_TYPE_SET_READ_ONLY,
|
|
SUB_TYPE_FORMAT_NDEF,
|
|
|
|
SUB_TYPE_MAX
|
|
};
|
|
|
|
static void rw_cback(tRW_EVENT event, tRW_DATA* p_rw_data) {
|
|
FUZZLOG(MODULE_NAME ": rw_cback: event=0x%02x, p_rw_data=%p", event, p_rw_data);
|
|
|
|
if (event == RW_T4T_RAW_FRAME_EVT) {
|
|
if (p_rw_data->raw_frame.p_data) {
|
|
GKI_freebuf(p_rw_data->raw_frame.p_data);
|
|
p_rw_data->raw_frame.p_data = nullptr;
|
|
}
|
|
} else if (event == RW_T4T_NDEF_READ_EVT || event == RW_T4T_NDEF_READ_CPLT_EVT) {
|
|
if (p_rw_data->data.p_data) {
|
|
GKI_freebuf(p_rw_data->data.p_data);
|
|
p_rw_data->data.p_data = nullptr;
|
|
}
|
|
}
|
|
}
|
|
|
|
#define TEST_NFCID_VALUE \
|
|
{ 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88 }
|
|
|
|
static bool Init(Fuzz_Context& /*ctx*/) {
|
|
tNFC_ACTIVATE_DEVT activate_params = {.protocol = NFC_PROTOCOL_ISO_DEP,
|
|
.rf_tech_param = {
|
|
.mode = NFC_DISCOVERY_TYPE_POLL_A,
|
|
}};
|
|
|
|
rw_init();
|
|
if (NFC_STATUS_OK != RW_SetActivatedTagType(&activate_params, rw_cback)) {
|
|
FUZZLOG(MODULE_NAME ": RW_SetActivatedTagType failed");
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
static bool Init_PresenceCheck(Fuzz_Context& /*ctx*/) {
|
|
return NFC_STATUS_OK == RW_T4tPresenceCheck(1);
|
|
}
|
|
|
|
static bool Init_DetectNDef(Fuzz_Context& /*ctx*/) {
|
|
return NFC_STATUS_OK == RW_T4tDetectNDef();
|
|
}
|
|
|
|
static bool Init_ReadNDef(Fuzz_Context& /*ctx*/) {
|
|
return NFC_STATUS_OK == RW_T4tReadNDef();
|
|
}
|
|
|
|
static bool Init_UpdateNDef(Fuzz_Context& ctx) {
|
|
const uint8_t data[] = {0x01, 0x02, 0x03, 0x04, 0x01, 0x02, 0x03, 0x04,
|
|
0x01, 0x02, 0x03, 0x04, 0x01, 0x02, 0x03, 0x04};
|
|
|
|
auto scratch = ctx.GetBuffer(sizeof(data), data);
|
|
return NFC_STATUS_OK == RW_T4tUpdateNDef(sizeof(data), scratch);
|
|
}
|
|
|
|
static bool Init_FormatNDef(Fuzz_Context& /*ctx*/) {
|
|
return NFC_STATUS_OK == RW_T4tFormatNDef();
|
|
}
|
|
|
|
static bool Init_SetNDefReadOnly(Fuzz_Context& /*ctx*/) {
|
|
return NFC_STATUS_OK == RW_T4tSetNDefReadOnly();
|
|
}
|
|
|
|
static bool Fuzz_Init(Fuzz_Context& ctx) {
|
|
if (!Init(ctx)) {
|
|
FUZZLOG(MODULE_NAME ": initialization failed");
|
|
return false;
|
|
}
|
|
|
|
bool result = false;
|
|
switch (ctx.SubType) {
|
|
case SUB_TYPE_DETECT_NDEF:
|
|
result = Init_DetectNDef(ctx);
|
|
break;
|
|
case SUB_TYPE_UPDATE_NDEF:
|
|
result = Init_UpdateNDef(ctx);
|
|
break;
|
|
case SUB_TYPE_PRESENCE_CHECK:
|
|
result = Init_PresenceCheck(ctx);
|
|
break;
|
|
case SUB_TYPE_READ_NDEF:
|
|
result = Init_ReadNDef(ctx);
|
|
break;
|
|
case SUB_TYPE_FORMAT_NDEF:
|
|
result = Init_FormatNDef(ctx);
|
|
break;
|
|
case SUB_TYPE_SET_READ_ONLY:
|
|
result = Init_SetNDefReadOnly(ctx);
|
|
break;
|
|
default:
|
|
FUZZLOG(MODULE_NAME ": Unknown command %d", ctx.SubType);
|
|
result = false;
|
|
break;
|
|
}
|
|
|
|
if (!result) {
|
|
FUZZLOG(MODULE_NAME ": Initializing command %02X failed", ctx.SubType);
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
static void Fuzz_Deinit(Fuzz_Context& /*ctx*/) {
|
|
if (rf_cback) {
|
|
tNFC_CONN conn = {.deactivate = {.status = NFC_STATUS_OK,
|
|
.type = NFC_DEACTIVATE_TYPE_IDLE,
|
|
.is_ntf = true,
|
|
.reason = NFC_DEACTIVATE_REASON_DH_REQ_FAILED}};
|
|
|
|
rf_cback(NFC_RF_CONN_ID, NFC_DEACTIVATE_CEVT, &conn);
|
|
}
|
|
}
|
|
|
|
static void Fuzz_Run(Fuzz_Context& ctx) {
|
|
for (auto it = ctx.Data.cbegin() + 1; it != ctx.Data.cend(); ++it) {
|
|
NFC_HDR* p_msg;
|
|
|
|
/* CVE-2021-0925 starts */
|
|
enable_selective_overload = ENABLE_ALL;
|
|
/* CVE-2021-0925 ends */
|
|
|
|
p_msg = (NFC_HDR*)GKI_getbuf(sizeof(NFC_HDR) + it->size());
|
|
|
|
/* CVE-2021-0925 starts */
|
|
vulnPtr = (char*)p_msg;
|
|
enable_selective_overload = ENABLE_FREE_CHECK | ENABLE_REALLOC_CHECK;
|
|
/* CVE-2021-0925 ends */
|
|
|
|
if (p_msg == nullptr) {
|
|
FUZZLOG(MODULE_NAME ": GKI_getbuf returns null, size=%zu", it->size());
|
|
return;
|
|
}
|
|
|
|
/* Initialize NFC_HDR */
|
|
p_msg->len = it->size();
|
|
p_msg->offset = 0;
|
|
|
|
uint8_t* p = (uint8_t*)(p_msg + 1) + p_msg->offset;
|
|
memcpy(p, it->data(), it->size());
|
|
|
|
tNFC_CONN conn = {.data = {
|
|
.status = NFC_STATUS_OK,
|
|
.p_data = p_msg,
|
|
}};
|
|
|
|
FUZZLOG(MODULE_NAME ": SubType=%02X, Response[%zd/%zd]=%s", ctx.SubType,
|
|
it - ctx.Data.cbegin(), ctx.Data.size() - 1, BytesToHex(*it).c_str());
|
|
|
|
/* CVE-2021-0925 starts */
|
|
testInProgress = true;
|
|
/* CVE-2021-0925 ends */
|
|
|
|
rf_cback(NFC_RF_CONN_ID, NFC_DATA_CEVT, &conn);
|
|
|
|
/* CVE-2021-0925 starts */
|
|
testInProgress = false;
|
|
/* CVE-2021-0925 ends */
|
|
}
|
|
}
|
|
|
|
void Type4_FixPackets(uint8_t /*SubType*/, std::vector<bytes_t>& /*Data*/) {}
|
|
|
|
void Type4_Fuzz(uint8_t SubType, const std::vector<bytes_t>& Data) {
|
|
Fuzz_Context ctx(SubType % SUB_TYPE_MAX, Data);
|
|
if (Fuzz_Init(ctx)) {
|
|
Fuzz_Run(ctx);
|
|
}
|
|
|
|
Fuzz_Deinit(ctx);
|
|
}
|