Skip to content

Commit 2a4c627

Browse files
Pierre Imaiandi34
authored andcommitted
Improve length checks in DHCP Options parsing of dhcpcd.
Bug: 26461634 Change-Id: Iefa45ba440df8ab6e2af391220fae22dcddec96b (cherry picked from commit 3320c04abf2f5e75cf3a78ad29417753d8e3c2a2)
1 parent 6f91ba0 commit 2a4c627

File tree

1 file changed

+21
-8
lines changed

1 file changed

+21
-8
lines changed

dhcp.c

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -271,21 +271,34 @@ valid_length(uint8_t option, int dl, int *type)
271271

272272
if (type)
273273
*type = opt->type;
274-
274+
/* The size of RFC3442 and RFC5969 options is checked at a later
275+
* stage in the code */
275276
if (opt->type == 0 ||
276277
opt->type & (STRING | RFC3442 | RFC5969))
277278
return 0;
278-
279+
/* The code does not use SINT16 / SINT32 together with ARRAY.
280+
* It is however far easier to reason about the code if all
281+
* possible array elements are included, and also does not code
282+
* any additional CPU resources. sizeof(uintXX_t) ==
283+
* sizeof(intXX_t) can be assumed. */
279284
sz = 0;
280-
if (opt->type & (UINT32 | IPV4))
285+
if (opt->type & (UINT32 | SINT32 | IPV4))
281286
sz = sizeof(uint32_t);
282-
if (opt->type & UINT16)
287+
else if (opt->type & (UINT16 | SINT16))
283288
sz = sizeof(uint16_t);
284-
if (opt->type & UINT8)
289+
else if (opt->type & UINT8)
285290
sz = sizeof(uint8_t);
286-
if (opt->type & (IPV4 | ARRAY))
287-
return dl % sz;
288-
return (dl == sz ? 0 : -1);
291+
if (opt->type & ARRAY) {
292+
/* The result of modulo zero is undefined. There are no
293+
* options defined in this file that do not match one of
294+
* the if-clauses above, so the following is not really
295+
* necessary. However, to avoid confusion and unexpected
296+
* behavior if the defined options are ever extended,
297+
* returning false here seems sensible. */
298+
if (!sz) return -1;
299+
return (dl % sz == 0) ? 0 : -1;
300+
}
301+
return (sz == dl) ? 0 : -1;
289302
}
290303

291304
/* unknown option, so let it pass */

0 commit comments

Comments
 (0)