--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/components/quagga/patches/37-cve-2017-5495.patch Tue Feb 14 18:38:42 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;