Fix parsing overflow in unformat_mac_address_t() 79/17379/2
authorBenoît Ganne <bganne@cisco.com>
Thu, 7 Feb 2019 12:21:42 +0000 (13:21 +0100)
committerFlorin Coras <florin.coras@gmail.com>
Thu, 7 Feb 2019 19:11:22 +0000 (19:11 +0000)
'%x' unformat specifier expects a pointer to a 4-byte object and will
overflow when using a pointer to a 1-byte object. Use '%X' instead which
allows to pass the size of the object alongside its pointer.

The bug was exposed with the following commands:
~# make run
DBGvpp# loop create
loop0
DBGvpp# set ip6 neigh loop0 3001::2 a:a:a:a:a:a
DBGvpp# show ip6 neigh
Time     Address  Flags  Link layer         Interface
35.7743  ::2      D      0a:0a:0a:0a:0a:0a  loop0
         ^^^
  wrong address: should be 3001::2
Note that the bug impact depends from the parsing order and memory
layout.

Change-Id: I29ba2eb53ba5a2daf4517215602d027508e2cb9f
Signed-off-by: Benoît Ganne <bganne@cisco.com>
src/vnet/ethernet/mac_address.c

index eab7cef..6f40e50 100644 (file)
@@ -39,9 +39,9 @@ unformat_mac_address_t (unformat_input_t * input, va_list * args)
   mac_address_t *mac = va_arg (*args, mac_address_t *);
   u32 i, a[3];
 
-  if (unformat (input, "%_%x:%x:%x:%x:%x:%x%_",
-               &mac->bytes[0], &mac->bytes[1], &mac->bytes[2],
-               &mac->bytes[3], &mac->bytes[4], &mac->bytes[5]))
+  if (unformat (input, "%_%X:%X:%X:%X:%X:%X%_",
+               1, &mac->bytes[0], 1, &mac->bytes[1], 1, &mac->bytes[2],
+               1, &mac->bytes[3], 1, &mac->bytes[4], 1, &mac->bytes[5]))
     return (1);
   else if (unformat (input, "%_%x.%x.%x%_", &a[0], &a[1], &a[2]))
     {