1 /*
2  * Copyright (C) 2021 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 /* 'system/nfc/src/fuzzers/rw/t4t.cc' is used as reference to come up with file */
18 
19 #include "fuzz.h"
20 
21 #include "../includes/memutils.h"
22 char enable_selective_overload = ENABLE_NONE;
23 extern bool testInProgress;
24 extern char* vulnPtr;
25 
26 #define MODULE_NAME "Type4 Read/Write"
27 
28 enum {
29     SUB_TYPE_DETECT_NDEF,
30     SUB_TYPE_READ_NDEF,
31     SUB_TYPE_UPDATE_NDEF,
32     SUB_TYPE_PRESENCE_CHECK,
33     SUB_TYPE_SET_READ_ONLY,
34     SUB_TYPE_FORMAT_NDEF,
35 
36     SUB_TYPE_MAX
37 };
38 
rw_cback(tRW_EVENT event,tRW_DATA * p_rw_data)39 static void rw_cback(tRW_EVENT event, tRW_DATA* p_rw_data) {
40     FUZZLOG(MODULE_NAME ": rw_cback: event=0x%02x, p_rw_data=%p", event, p_rw_data);
41 
42     if (event == RW_T4T_RAW_FRAME_EVT) {
43         if (p_rw_data->raw_frame.p_data) {
44             GKI_freebuf(p_rw_data->raw_frame.p_data);
45             p_rw_data->raw_frame.p_data = nullptr;
46         }
47     } else if (event == RW_T4T_NDEF_READ_EVT || event == RW_T4T_NDEF_READ_CPLT_EVT) {
48         if (p_rw_data->data.p_data) {
49             GKI_freebuf(p_rw_data->data.p_data);
50             p_rw_data->data.p_data = nullptr;
51         }
52     }
53 }
54 
55 #define TEST_NFCID_VALUE \
56     { 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88 }
57 
Init(Fuzz_Context &)58 static bool Init(Fuzz_Context& /*ctx*/) {
59     tNFC_ACTIVATE_DEVT activate_params = {.protocol = NFC_PROTOCOL_ISO_DEP,
60                                           .rf_tech_param = {
61                                                   .mode = NFC_DISCOVERY_TYPE_POLL_A,
62                                           }};
63 
64     rw_init();
65     if (NFC_STATUS_OK != RW_SetActivatedTagType(&activate_params, rw_cback)) {
66         FUZZLOG(MODULE_NAME ": RW_SetActivatedTagType failed");
67         return false;
68     }
69 
70     return true;
71 }
72 
Init_PresenceCheck(Fuzz_Context &)73 static bool Init_PresenceCheck(Fuzz_Context& /*ctx*/) {
74     return NFC_STATUS_OK == RW_T4tPresenceCheck(1);
75 }
76 
Init_DetectNDef(Fuzz_Context &)77 static bool Init_DetectNDef(Fuzz_Context& /*ctx*/) {
78     return NFC_STATUS_OK == RW_T4tDetectNDef();
79 }
80 
Init_ReadNDef(Fuzz_Context &)81 static bool Init_ReadNDef(Fuzz_Context& /*ctx*/) {
82     return NFC_STATUS_OK == RW_T4tReadNDef();
83 }
84 
Init_UpdateNDef(Fuzz_Context & ctx)85 static bool Init_UpdateNDef(Fuzz_Context& ctx) {
86     const uint8_t data[] = {0x01, 0x02, 0x03, 0x04, 0x01, 0x02, 0x03, 0x04,
87                             0x01, 0x02, 0x03, 0x04, 0x01, 0x02, 0x03, 0x04};
88 
89     auto scratch = ctx.GetBuffer(sizeof(data), data);
90     return NFC_STATUS_OK == RW_T4tUpdateNDef(sizeof(data), scratch);
91 }
92 
Init_FormatNDef(Fuzz_Context &)93 static bool Init_FormatNDef(Fuzz_Context& /*ctx*/) {
94     return NFC_STATUS_OK == RW_T4tFormatNDef();
95 }
96 
Init_SetNDefReadOnly(Fuzz_Context &)97 static bool Init_SetNDefReadOnly(Fuzz_Context& /*ctx*/) {
98     return NFC_STATUS_OK == RW_T4tSetNDefReadOnly();
99 }
100 
Fuzz_Init(Fuzz_Context & ctx)101 static bool Fuzz_Init(Fuzz_Context& ctx) {
102     if (!Init(ctx)) {
103         FUZZLOG(MODULE_NAME ": initialization failed");
104         return false;
105     }
106 
107     bool result = false;
108     switch (ctx.SubType) {
109         case SUB_TYPE_DETECT_NDEF:
110             result = Init_DetectNDef(ctx);
111             break;
112         case SUB_TYPE_UPDATE_NDEF:
113             result = Init_UpdateNDef(ctx);
114             break;
115         case SUB_TYPE_PRESENCE_CHECK:
116             result = Init_PresenceCheck(ctx);
117             break;
118         case SUB_TYPE_READ_NDEF:
119             result = Init_ReadNDef(ctx);
120             break;
121         case SUB_TYPE_FORMAT_NDEF:
122             result = Init_FormatNDef(ctx);
123             break;
124         case SUB_TYPE_SET_READ_ONLY:
125             result = Init_SetNDefReadOnly(ctx);
126             break;
127         default:
128             FUZZLOG(MODULE_NAME ": Unknown command %d", ctx.SubType);
129             result = false;
130             break;
131     }
132 
133     if (!result) {
134         FUZZLOG(MODULE_NAME ": Initializing command %02X failed", ctx.SubType);
135     }
136 
137     return result;
138 }
139 
Fuzz_Deinit(Fuzz_Context &)140 static void Fuzz_Deinit(Fuzz_Context& /*ctx*/) {
141     if (rf_cback) {
142         tNFC_CONN conn = {.deactivate = {.status = NFC_STATUS_OK,
143                                          .type = NFC_DEACTIVATE_TYPE_IDLE,
144                                          .is_ntf = true,
145                                          .reason = NFC_DEACTIVATE_REASON_DH_REQ_FAILED}};
146 
147         rf_cback(NFC_RF_CONN_ID, NFC_DEACTIVATE_CEVT, &conn);
148     }
149 }
150 
Fuzz_Run(Fuzz_Context & ctx)151 static void Fuzz_Run(Fuzz_Context& ctx) {
152     for (auto it = ctx.Data.cbegin() + 1; it != ctx.Data.cend(); ++it) {
153         NFC_HDR* p_msg;
154 
155         /* CVE-2021-0925 starts */
156         enable_selective_overload = ENABLE_ALL;
157         /* CVE-2021-0925 ends */
158 
159         p_msg = (NFC_HDR*)GKI_getbuf(sizeof(NFC_HDR) + it->size());
160 
161         /* CVE-2021-0925 starts */
162         vulnPtr = (char*)p_msg;
163         enable_selective_overload = ENABLE_FREE_CHECK | ENABLE_REALLOC_CHECK;
164         /* CVE-2021-0925 ends */
165 
166         if (p_msg == nullptr) {
167             FUZZLOG(MODULE_NAME ": GKI_getbuf returns null, size=%zu", it->size());
168             return;
169         }
170 
171         /* Initialize NFC_HDR */
172         p_msg->len = it->size();
173         p_msg->offset = 0;
174 
175         uint8_t* p = (uint8_t*)(p_msg + 1) + p_msg->offset;
176         memcpy(p, it->data(), it->size());
177 
178         tNFC_CONN conn = {.data = {
179                                   .status = NFC_STATUS_OK,
180                                   .p_data = p_msg,
181                           }};
182 
183         FUZZLOG(MODULE_NAME ": SubType=%02X, Response[%zd/%zd]", ctx.SubType,
184                 it - ctx.Data.cbegin(), ctx.Data.size() - 1);
185 
186         /* CVE-2021-0925 starts */
187         testInProgress = true;
188         /* CVE-2021-0925 ends */
189 
190         rf_cback(NFC_RF_CONN_ID, NFC_DATA_CEVT, &conn);
191 
192         /* CVE-2021-0925 starts */
193         testInProgress = false;
194         /* CVE-2021-0925 ends */
195     }
196 }
197 
Type4_FixPackets(uint8_t,std::vector<bytes_t> &)198 void Type4_FixPackets(uint8_t /*SubType*/, std::vector<bytes_t>& /*Data*/) {}
199 
Type4_Fuzz(uint8_t SubType,const std::vector<bytes_t> & Data)200 void Type4_Fuzz(uint8_t SubType, const std::vector<bytes_t>& Data) {
201     Fuzz_Context ctx(SubType % SUB_TYPE_MAX, Data);
202     if (Fuzz_Init(ctx)) {
203         Fuzz_Run(ctx);
204     }
205 
206     Fuzz_Deinit(ctx);
207 }
208