25459915 problem in SERVICE/QUAGGA
authorBrian Utterback <brian.utterback@oracle.com>
Tue, 14 Feb 2017 18:22:31 -0800
changeset 7669 4efcda591db9
parent 7668 98611b4a801e
child 7670 4e60db2d9462
25459915 problem in SERVICE/QUAGGA
components/quagga/patches/37-cve-2017-5495.patch
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/components/quagga/patches/37-cve-2017-5495.patch	Tue Feb 14 18:22:31 2017 -0800
@@ -0,0 +1,397 @@
+This patch fixes CVE-2017-5495, which is in all versions of Quagga 
+prior to 1.1.0. After upgrading to a version later than that, this patch
+may be removed.
+See:
+http://git.savannah.gnu.org/gitweb/?p=quagga.git;a=commit;h=b7ceefea77a246fe5c1dcd1b91bf6079d1b97c02
+http://git.savannah.gnu.org/gitweb/?p=quagga.git;a=commit;h=7d66284a5817a1613b1e4d64a0775ec04fdf8c01
+
+*** lib/command.c
+--- lib/command.c
+*************** config_from_file (struct vty *vty, FILE
+*** 2306,2312 ****
+    int ret;
+    vector vline;
+  
+!   while (fgets (vty->buf, VTY_BUFSIZ, fp))
+      {
+        vline = cmd_make_strvec (vty->buf);
+  
+--- 2306,2312 ----
+    int ret;
+    vector vline;
+  
+!   while (fgets (vty->buf, vty->max, fp))
+      {
+        vline = cmd_make_strvec (vty->buf);
+  
+*** lib/vty.c
+--- lib/vty.c
+***************
+*** 39,44 ****
+--- 39,46 ----
+  
+  #include <arpa/telnet.h>
+  
++ #define VTY_BUFSIZ 4096
++ 
+  /* Vty events */
+  enum event 
+  {
+*************** static u_char restricted_mode = 0;
+*** 90,95 ****
+--- 92,113 ----
+  char integrate_default[] = SYSCONFDIR INTEGRATE_DEFAULT_CONFIG;
+  
+  
++ static void
++ vty_buf_assert (struct vty *vty)
++ {
++   assert (vty->cp <= vty->length);
++   assert (vty->length < vty->max);
++   assert (vty->buf[vty->length] == '\0');
++ }
++ 
++ /* Sanity/safety wrappers around access to vty->buf */
++ static void vty_buf_put (struct vty *vty, char c)
++ {
++   vty_buf_assert (vty);
++   vty->buf[vty->cp] = c;
++   vty->buf[vty->max - 1] = '\0';
++ }
++ 
+  /* VTY standard output function. */
+  int
+  vty_out (struct vty *vty, const char *format, ...)
+*************** vty_write (struct vty *vty, const char *
+*** 470,553 ****
+    buffer_put (vty->obuf, buf, nbytes);
+  }
+  
+- /* Ensure length of input buffer.  Is buffer is short, double it. */
+- static void
+- vty_ensure (struct vty *vty, int length)
+- {
+-   if (vty->max <= length)
+-     {
+-       vty->max *= 2;
+-       vty->buf = XREALLOC (MTYPE_VTY, vty->buf, vty->max);
+-     }
+- }
+- 
+  /* Basic function to insert character into vty. */
+  static void
+  vty_self_insert (struct vty *vty, char c)
+  {
+    int i;
+    int length;
+  
+-   vty_ensure (vty, vty->length + 1);
+    length = vty->length - vty->cp;
+    memmove (&vty->buf[vty->cp + 1], &vty->buf[vty->cp], length);
+!   vty->buf[vty->cp] = c;
+  
+    vty_write (vty, &vty->buf[vty->cp], length + 1);
+    for (i = 0; i < length; i++)
+      vty_write (vty, &telnet_backward_char, 1);
+  
+    vty->cp++;
+!   vty->length++;
+  }
+  
+  /* Self insert character 'c' in overwrite mode. */
+  static void
+  vty_self_insert_overwrite (struct vty *vty, char c)
+  {
+!   vty_ensure (vty, vty->length + 1);
+!   vty->buf[vty->cp++] = c;
+! 
+!   if (vty->cp > vty->length)
+!     vty->length++;
+! 
+!   if ((vty->node == AUTH_NODE) || (vty->node == AUTH_ENABLE_NODE))
+!     return;
+  
+    vty_write (vty, &c, 1);
+  }
+  
+! /* Insert a word into vty interface with overwrite mode. */
+  static void
+  vty_insert_word_overwrite (struct vty *vty, char *str)
+  {
+!   int len = strlen (str);
+!   vty_write (vty, str, len);
+!   strcpy (&vty->buf[vty->cp], str);
+!   vty->cp += len;
+    vty->length = vty->cp;
+  }
+  
+  /* Forward character. */
+  static void
+  vty_forward_char (struct vty *vty)
+  {
+    if (vty->cp < vty->length)
+      {
+        vty_write (vty, &vty->buf[vty->cp], 1);
+        vty->cp++;
+      }
+  }
+  
+  /* Backward character. */
+  static void
+  vty_backward_char (struct vty *vty)
+  {
+    if (vty->cp > 0)
+      {
+        vty->cp--;
+        vty_write (vty, &telnet_backward_char, 1);
+      }
+  }
+  
+  /* Move to the beginning of the line. */
+--- 488,591 ----
+    buffer_put (vty->obuf, buf, nbytes);
+  }
+  
+  /* Basic function to insert character into vty. */
+  static void
+  vty_self_insert (struct vty *vty, char c)
+  {
+    int i;
+    int length;
++   
++   vty_buf_assert (vty);
++   
++   /* length is sans nul, max is with */
++   if (vty->length + 1 >= vty->max)
++     return;
+  
+    length = vty->length - vty->cp;
+    memmove (&vty->buf[vty->cp + 1], &vty->buf[vty->cp], length);
+!   vty->length++;
+!   vty->buf[vty->length] = '\0';
+! 
+!   vty_buf_put (vty, c);
+  
+    vty_write (vty, &vty->buf[vty->cp], length + 1);
+    for (i = 0; i < length; i++)
+      vty_write (vty, &telnet_backward_char, 1);
+  
+    vty->cp++;
+!   
+!   vty_buf_assert (vty);
+  }
+  
+  /* Self insert character 'c' in overwrite mode. */
+  static void
+  vty_self_insert_overwrite (struct vty *vty, char c)
+  {
+!   vty_buf_assert (vty);
+!   
+!   if (vty->cp == vty->length)
+!     {
+!       vty_self_insert (vty, c);
+!       return;
+!     }
+  
++   vty_buf_put (vty, c);
++   vty->cp++;
++   
++   vty_buf_assert (vty);
++   
+    vty_write (vty, &c, 1);
+  }
+  
+! /**
+!  * Insert a string into vty->buf at the current cursor position.
+!  *
+!  * If the resultant string would be larger than VTY_BUFSIZ it is
+!  * truncated to fit.
+!  */
+  static void
+  vty_insert_word_overwrite (struct vty *vty, char *str)
+  {
+!   vty_buf_assert (vty);
+!   
+!   size_t nwrite = MIN ((int) strlen (str), vty->max - vty->cp - 1);
+!   memcpy (&vty->buf[vty->cp], str, nwrite);
+!   vty->cp += nwrite;
+    vty->length = vty->cp;
++   vty->buf[vty->length] = '\0';
++   vty_buf_assert (vty);
++   
++   vty_write (vty, str, nwrite);
+  }
+  
+  /* Forward character. */
+  static void
+  vty_forward_char (struct vty *vty)
+  {
++   vty_buf_assert (vty);
++   
+    if (vty->cp < vty->length)
+      {
+        vty_write (vty, &vty->buf[vty->cp], 1);
+        vty->cp++;
+      }
++   
++   vty_buf_assert (vty);
+  }
+  
+  /* Backward character. */
+  static void
+  vty_backward_char (struct vty *vty)
+  {
++   vty_buf_assert (vty);
++   
+    if (vty->cp > 0)
+      {
+        vty->cp--;
+        vty_write (vty, &telnet_backward_char, 1);
+      }
++   
++   vty_buf_assert (vty);
+  }
+  
+  /* Move to the beginning of the line. */
+*************** vty_history_print (struct vty *vty)
+*** 582,588 ****
+    length = strlen (vty->hist[vty->hp]);
+    memcpy (vty->buf, vty->hist[vty->hp], length);
+    vty->cp = vty->length = length;
+! 
+    /* Redraw current line */
+    vty_redraw_line (vty);
+  }
+--- 620,628 ----
+    length = strlen (vty->hist[vty->hp]);
+    memcpy (vty->buf, vty->hist[vty->hp], length);
+    vty->cp = vty->length = length;
+!   vty->buf[vty->length] = '\0';
+!   vty_buf_assert (vty);
+!   
+    /* Redraw current line */
+    vty_redraw_line (vty);
+  }
+*************** vty_redraw_line (struct vty *vty)
+*** 638,643 ****
+--- 678,685 ----
+  {
+    vty_write (vty, vty->buf, vty->length);
+    vty->cp = vty->length;
++   
++   vty_buf_assert (vty);
+  }
+  
+  /* Forward word. */
+*************** vty_delete_char (struct vty *vty)
+*** 737,746 ****
+        vty_down_level (vty);
+        return;
+      }
+! 
+    if (vty->cp == vty->length)
+      return;			/* completion need here? */
+  
+    size = vty->length - vty->cp;
+  
+    vty->length--;
+--- 779,790 ----
+        vty_down_level (vty);
+        return;
+      }
+!   
+    if (vty->cp == vty->length)
+      return;			/* completion need here? */
+  
++   vty_buf_assert (vty);
++   
+    size = vty->length - vty->cp;
+  
+    vty->length--;
+*************** vty_kill_line (struct vty *vty)
+*** 787,792 ****
+--- 831,837 ----
+  
+    memset (&vty->buf[vty->cp], 0, size);
+    vty->length = vty->cp;
++   vty_buf_assert (vty);
+  }
+  
+  /* Kill line from the beginning. */
+*************** vtysh_read (struct thread *thread)
+*** 2087,2098 ****
+    printf ("line: %.*s\n", nbytes, buf);
+  #endif /* VTYSH_DEBUG */
+  
+    for (p = buf; p < buf+nbytes; p++)
+      {
+-       vty_ensure(vty, vty->length+1);
+        vty->buf[vty->length++] = *p;
+        if (*p == '\0')
+  	{
+  	  /* Pass this line to parser. */
+  	  ret = vty_execute (vty);
+  	  /* Note that vty_execute clears the command buffer and resets
+--- 2132,2152 ----
+    printf ("line: %.*s\n", nbytes, buf);
+  #endif /* VTYSH_DEBUG */
+  
++   if (vty->length + nbytes >= vty->max)
++     {
++       /* Clear command line buffer. */
++       vty->cp = vty->length = 0;
++       vty_clear_buf (vty);
++       vty_out (vty, "%% Command is too long.%s", VTY_NEWLINE);
++       goto out;
++     }
++   
+    for (p = buf; p < buf+nbytes; p++)
+      {
+        vty->buf[vty->length++] = *p;
+        if (*p == '\0')
+  	{
++ 	  
+  	  /* Pass this line to parser. */
+  	  ret = vty_execute (vty);
+  	  /* Note that vty_execute clears the command buffer and resets
+*************** vtysh_read (struct thread *thread)
+*** 2113,2118 ****
+--- 2167,2173 ----
+  	}
+      }
+  
++ out:
+    vty_event (VTYSH_READ, sock, vty);
+  
+    return 0;
+*** lib/vty.h
+--- lib/vty.h
+*************** Software Foundation, Inc., 59 Temple Pla
+*** 24,30 ****
+  #include "thread.h"
+  #include "log.h"
+  
+- #define VTY_BUFSIZ 512
+  #define VTY_MAXHIST 20
+  
+  /* VTY struct. */
+--- 24,29 ----
+*** vtysh/vtysh.c
+--- vtysh/vtysh.c
+*************** vtysh_config_from_file (struct vty *vty,
+*** 459,465 ****
+    vector vline;
+    struct cmd_element *cmd;
+  
+!   while (fgets (vty->buf, VTY_BUFSIZ, fp))
+      {
+        if (vty->buf[0] == '!' || vty->buf[1] == '#')
+  	continue;
+--- 459,465 ----
+    vector vline;
+    struct cmd_element *cmd;
+  
+!   while (fgets (vty->buf, vty->max, fp))
+      {
+        if (vty->buf[0] == '!' || vty->buf[1] == '#')
+  	continue;