@@ -37,7 +37,8 @@ const u8_t level_2_tag_size[4] = {
37
37
};
38
38
#endif
39
39
40
- struct ieee802154_fcf_seq * ieee802154_validate_fc_seq (u8_t * buf , u8_t * * p_buf )
40
+ struct ieee802154_fcf_seq * ieee802154_validate_fc_seq (u8_t * buf , u8_t * * p_buf ,
41
+ u8_t * length )
41
42
{
42
43
struct ieee802154_fcf_seq * fs = (struct ieee802154_fcf_seq * )buf ;
43
44
@@ -81,17 +82,20 @@ struct ieee802154_fcf_seq *ieee802154_validate_fc_seq(u8_t *buf, u8_t **p_buf)
81
82
#endif
82
83
83
84
if (p_buf ) {
84
- * p_buf = buf + 3 ;
85
+ * length -= IEEE802154_FCF_SEQ_LENGTH ;
86
+ * p_buf = buf + IEEE802154_FCF_SEQ_LENGTH ;
85
87
}
86
88
87
89
return fs ;
88
90
}
89
91
90
92
static inline struct ieee802154_address_field *
91
- validate_addr (u8_t * buf , u8_t * * p_buf ,
93
+ validate_addr (u8_t * buf , u8_t * * p_buf , u8_t * length ,
92
94
enum ieee802154_addressing_mode mode ,
93
95
bool pan_id_compression )
94
96
{
97
+ u8_t len = 0 ;
98
+
95
99
* p_buf = buf ;
96
100
97
101
NET_DBG ("Buf %p - mode %d - pan id comp %d" ,
@@ -102,59 +106,76 @@ validate_addr(u8_t *buf, u8_t **p_buf,
102
106
}
103
107
104
108
if (!pan_id_compression ) {
105
- * p_buf + = IEEE802154_PAN_ID_LENGTH ;
109
+ len = IEEE802154_PAN_ID_LENGTH ;
106
110
}
107
111
108
112
if (mode == IEEE802154_ADDR_MODE_SHORT ) {
109
- * p_buf += IEEE802154_SHORT_ADDR_LENGTH ;
113
+ len += IEEE802154_SHORT_ADDR_LENGTH ;
110
114
} else {
111
115
/* IEEE802154_ADDR_MODE_EXTENDED */
112
- * p_buf += IEEE802154_EXT_ADDR_LENGTH ;
116
+ len += IEEE802154_EXT_ADDR_LENGTH ;
113
117
}
114
118
119
+ if (len > * length ) {
120
+ return NULL ;
121
+ }
122
+
123
+ * p_buf += len ;
124
+ * length -= len ;
125
+
115
126
return (struct ieee802154_address_field * )buf ;
116
127
}
117
128
118
129
#ifdef CONFIG_NET_L2_IEEE802154_SECURITY
119
130
struct ieee802154_aux_security_hdr *
120
- ieee802154_validate_aux_security_hdr (u8_t * buf , u8_t * * p_buf )
131
+ ieee802154_validate_aux_security_hdr (u8_t * buf , u8_t * * p_buf , u8_t * length )
121
132
{
122
133
struct ieee802154_aux_security_hdr * ash =
123
134
(struct ieee802154_aux_security_hdr * )buf ;
135
+ u8_t len = IEEE802154_SECURITY_CF_LENGTH +
136
+ IEEE802154_SECURITY_FRAME_COUNTER_LENGTH ;
124
137
125
- * p_buf = buf ;
138
+ /* At least the asf is sized of: control field + frame counter */
139
+ if (* length < len ) {
140
+ return NULL ;
141
+ }
126
142
127
143
/* Only implicit key mode is supported for now */
128
144
if (ash -> control .key_id_mode != IEEE802154_KEY_ID_MODE_IMPLICIT ) {
129
145
return NULL ;
130
146
}
131
147
132
- /* At least the asf is sized of: control field + frame counter */
133
- * p_buf += sizeof (struct ieee802154_security_control_field ) +
134
- sizeof (u32_t );
135
-
136
148
/* Explicit key must have a key index != 0x00, see Section 7.4.3.2 */
137
149
switch (ash -> control .key_id_mode ) {
138
150
case IEEE802154_KEY_ID_MODE_IMPLICIT :
139
151
break ;
140
152
case IEEE802154_KEY_ID_MODE_INDEX :
141
- * p_buf += IEEE8021254_KEY_ID_FIELD_INDEX_LENGTH ;
153
+ len += IEEE8021254_KEY_ID_FIELD_INDEX_LENGTH ;
154
+ if (* length < len ) {
155
+ return NULL ;
156
+ }
142
157
143
158
if (!ash -> kif .mode_1 .key_index ) {
144
159
return NULL ;
145
160
}
146
161
147
162
break ;
148
163
case IEEE802154_KEY_ID_MODE_SRC_4_INDEX :
149
- * p_buf += IEEE8021254_KEY_ID_FIELD_SRC_4_INDEX_LENGTH ;
164
+ len += IEEE8021254_KEY_ID_FIELD_SRC_4_INDEX_LENGTH ;
165
+ if (* length < len ) {
166
+ return NULL ;
167
+ }
150
168
151
169
if (!ash -> kif .mode_2 .key_index ) {
152
170
return NULL ;
153
171
}
154
172
155
173
break ;
156
174
case IEEE802154_KEY_ID_MODE_SRC_8_INDEX :
157
- * p_buf += IEEE8021254_KEY_ID_FIELD_SRC_8_INDEX_LENGTH ;
175
+ len += IEEE8021254_KEY_ID_FIELD_SRC_8_INDEX_LENGTH ;
176
+ if (* length < len ) {
177
+ return NULL ;
178
+ }
158
179
159
180
if (!ash -> kif .mode_3 .key_index ) {
160
181
return NULL ;
@@ -163,44 +184,52 @@ ieee802154_validate_aux_security_hdr(u8_t *buf, u8_t **p_buf)
163
184
break ;
164
185
}
165
186
187
+ * p_buf = buf + len ;
188
+ * length -= len ;
189
+
166
190
return ash ;
167
191
}
168
192
#endif /* CONFIG_NET_L2_IEEE802154_SECURITY */
169
193
170
194
static inline bool
171
- validate_beacon (struct ieee802154_mpdu * mpdu , u8_t * buf , u8_t length )
195
+ validate_beacon (struct ieee802154_mpdu * mpdu , u8_t * buf , u8_t * length )
172
196
{
173
197
struct ieee802154_beacon * b = (struct ieee802154_beacon * )buf ;
174
- u8_t * p_buf = buf ;
175
198
struct ieee802154_pas_spec * pas ;
199
+ u8_t len = IEEE802154_BEACON_SF_SIZE +
200
+ IEEE802154_BEACON_GTS_SPEC_SIZE ;
201
+
176
202
177
- if (length < IEEE802154_BEACON_MIN_SIZE ) {
203
+ if (* length < len ) {
178
204
return false;
179
205
}
180
206
181
- p_buf += IEEE802154_BEACON_SF_SIZE + IEEE802154_BEACON_GTS_SPEC_SIZE ;
182
-
183
207
if (b -> gts .desc_count ) {
184
- p_buf += IEEE802154_BEACON_GTS_DIR_SIZE +
208
+ len += IEEE802154_BEACON_GTS_DIR_SIZE +
185
209
b -> gts .desc_count * IEEE802154_BEACON_GTS_SIZE ;
186
210
}
187
211
188
- if (length < ( p_buf - buf ) ) {
212
+ if (* length < len ) {
189
213
return false;
190
214
}
191
215
192
- pas = (struct ieee802154_pas_spec * )p_buf ;
193
- p_buf += IEEE802154_BEACON_PAS_SPEC_SIZE ;
216
+ pas = (struct ieee802154_pas_spec * )buf + len ;
217
+
218
+ len += IEEE802154_BEACON_PAS_SPEC_SIZE ;
219
+ if (* length < len ) {
220
+ return false;
221
+ }
194
222
195
223
if (pas -> nb_sap || pas -> nb_eap ) {
196
- p_buf += (pas -> nb_sap * IEEE802154_SHORT_ADDR_LENGTH ) +
224
+ len += (pas -> nb_sap * IEEE802154_SHORT_ADDR_LENGTH ) +
197
225
(pas -> nb_eap * IEEE802154_EXT_ADDR_LENGTH );
198
226
}
199
227
200
- if (length < ( p_buf - buf ) ) {
228
+ if (* length < len ) {
201
229
return false;
202
230
}
203
231
232
+ * length -= len ;
204
233
mpdu -> beacon = b ;
205
234
206
235
return true;
@@ -241,26 +270,37 @@ validate_mac_command_cfi_to_mhr(struct ieee802154_mhr *mhr,
241
270
}
242
271
243
272
static inline bool
244
- validate_mac_command (struct ieee802154_mpdu * mpdu , u8_t * buf , u8_t length )
273
+ validate_mac_command (struct ieee802154_mpdu * mpdu , u8_t * buf , u8_t * length )
245
274
{
246
275
struct ieee802154_command * c = (struct ieee802154_command * )buf ;
276
+ u8_t len = IEEE802154_CMD_CFI_LENGTH ;
247
277
bool src_pan_brdcst_chk = false;
248
278
bool dst_brdcst_chk = false;
249
279
u8_t comp = 0U ;
250
280
u8_t ar = 0U ;
251
281
u8_t src , dst ;
252
282
283
+ if (* length < len ) {
284
+ return false;
285
+ }
286
+
253
287
switch (c -> cfi ) {
254
288
case IEEE802154_CFI_UNKNOWN :
255
289
return false;
256
290
case IEEE802154_CFI_ASSOCIATION_REQUEST :
291
+ len += IEEE802154_CMD_ASSOC_REQ_LENGTH ;
257
292
src = IEEE802154_EXT_ADDR_LENGTH ;
258
293
src_pan_brdcst_chk = true;
259
294
dst = IEEE802154_ADDR_MODE_SHORT |
260
295
IEEE802154_ADDR_MODE_EXTENDED ;
296
+
261
297
break ;
262
298
case IEEE802154_CFI_ASSOCIATION_RESPONSE :
299
+ len += IEEE802154_CMD_ASSOC_RES_LENGTH ;
263
300
case IEEE802154_CFI_DISASSOCIATION_NOTIFICATION :
301
+ if (c -> cfi == IEEE802154_CFI_DISASSOCIATION_NOTIFICATION ) {
302
+ len += IEEE802154_CMD_DISASSOC_NOTE_LENGTH ;
303
+ }
264
304
case IEEE802154_CFI_PAN_ID_CONLICT_NOTIFICATION :
265
305
ar = 1U ;
266
306
comp = 1U ;
@@ -296,6 +336,7 @@ validate_mac_command(struct ieee802154_mpdu *mpdu, u8_t *buf, u8_t length)
296
336
297
337
break ;
298
338
case IEEE802154_CFI_COORDINATOR_REALIGNEMENT :
339
+ len += IEEE802154_CMD_COORD_REALIGN_LENGTH ;
299
340
src = IEEE802154_EXT_ADDR_LENGTH ;
300
341
301
342
if (mpdu -> mhr .fs -> fc .dst_addr_mode ==
@@ -308,6 +349,7 @@ validate_mac_command(struct ieee802154_mpdu *mpdu, u8_t *buf, u8_t length)
308
349
309
350
break ;
310
351
case IEEE802154_CFI_GTS_REQUEST :
352
+ len += IEEE802154_GTS_REQUEST_LENGTH ;
311
353
ar = 1U ;
312
354
src = IEEE802154_ADDR_MODE_SHORT ;
313
355
dst = IEEE802154_ADDR_MODE_NONE ;
@@ -317,54 +359,60 @@ validate_mac_command(struct ieee802154_mpdu *mpdu, u8_t *buf, u8_t length)
317
359
return false;
318
360
}
319
361
362
+ if (* length < len ) {
363
+ return false;
364
+ }
365
+
320
366
if (!validate_mac_command_cfi_to_mhr (& mpdu -> mhr , ar , comp ,
321
367
src , src_pan_brdcst_chk ,
322
368
dst , dst_brdcst_chk )) {
323
369
return false;
324
370
}
325
371
372
+ * length -= len ;
326
373
mpdu -> command = c ;
327
374
328
375
return true;
329
376
}
330
377
331
378
static inline bool
332
379
validate_payload_and_mfr (struct ieee802154_mpdu * mpdu ,
333
- u8_t * buf , u8_t * p_buf , u8_t length )
380
+ u8_t * buf , u8_t * p_buf , u8_t * length )
334
381
{
335
382
u8_t type = mpdu -> mhr .fs -> fc .frame_type ;
336
- u8_t payload_length ;
337
-
338
- payload_length = length - (p_buf - buf );
339
383
340
- NET_DBG ("Header size: %u, vs total length %u: payload size %u" ,
341
- (u32_t )(p_buf - buf ), length , payload_length );
384
+ NET_DBG ("Header size: %u, payload size %u" ,
385
+ (u32_t )(p_buf - buf ), * length );
342
386
343
387
if (type == IEEE802154_FRAME_TYPE_BEACON ) {
344
- if (!validate_beacon (mpdu , p_buf , payload_length )) {
388
+ if (!validate_beacon (mpdu , p_buf , length )) {
345
389
return false;
346
390
}
347
391
} else if (type == IEEE802154_FRAME_TYPE_DATA ) {
348
392
/** A data frame embeds a payload */
349
- if (payload_length == 0U ) {
393
+ if (* length == 0U ) {
350
394
return false;
351
395
}
352
396
353
397
mpdu -> payload = (void * )p_buf ;
354
398
} else if (type == IEEE802154_FRAME_TYPE_ACK ) {
355
399
/** An ACK frame has no payload */
356
- if (payload_length ) {
400
+ if (* length ) {
357
401
return false;
358
402
}
359
403
360
404
mpdu -> payload = NULL ;
361
405
} else {
362
- if (!validate_mac_command (mpdu , p_buf , payload_length )) {
406
+ if (!validate_mac_command (mpdu , p_buf , length )) {
363
407
return false;
364
408
}
365
409
}
366
410
367
- mpdu -> mfr = (struct ieee802154_mfr * )(p_buf + payload_length );
411
+ if (* length ) {
412
+ mpdu -> mfr = (struct ieee802154_mfr * )(p_buf + * length );
413
+ } else {
414
+ mpdu -> mfr = NULL ;
415
+ }
368
416
369
417
return true;
370
418
}
@@ -379,7 +427,7 @@ bool ieee802154_validate_frame(u8_t *buf, u8_t length,
379
427
return false;
380
428
}
381
429
382
- mpdu -> mhr .fs = ieee802154_validate_fc_seq (buf , & p_buf );
430
+ mpdu -> mhr .fs = ieee802154_validate_fc_seq (buf , & p_buf , & length );
383
431
if (!mpdu -> mhr .fs ) {
384
432
return false;
385
433
}
@@ -389,25 +437,26 @@ bool ieee802154_validate_frame(u8_t *buf, u8_t length,
389
437
return false;
390
438
}
391
439
392
- mpdu -> mhr .dst_addr = validate_addr (p_buf , & p_buf ,
440
+ mpdu -> mhr .dst_addr = validate_addr (p_buf , & p_buf , & length ,
393
441
mpdu -> mhr .fs -> fc .dst_addr_mode ,
394
442
false);
395
443
396
- mpdu -> mhr .src_addr = validate_addr (p_buf , & p_buf ,
444
+ mpdu -> mhr .src_addr = validate_addr (p_buf , & p_buf , & length ,
397
445
mpdu -> mhr .fs -> fc .src_addr_mode ,
398
446
(mpdu -> mhr .fs -> fc .pan_id_comp ));
399
447
400
448
#ifdef CONFIG_NET_L2_IEEE802154_SECURITY
401
449
if (mpdu -> mhr .fs -> fc .security_enabled ) {
402
450
mpdu -> mhr .aux_sec =
403
- ieee802154_validate_aux_security_hdr (p_buf , & p_buf );
451
+ ieee802154_validate_aux_security_hdr (p_buf , & p_buf ,
452
+ & length );
404
453
if (!mpdu -> mhr .aux_sec ) {
405
454
return false;
406
455
}
407
456
}
408
457
#endif
409
458
410
- return validate_payload_and_mfr (mpdu , buf , p_buf , length );
459
+ return validate_payload_and_mfr (mpdu , buf , p_buf , & length );
411
460
}
412
461
413
462
u8_t ieee802154_compute_header_size (struct net_if * iface ,
0 commit comments