Index: lib/stream.c =================================================================== RCS file: /var/cvsroot/quagga/lib/stream.c,v retrieving revision 1.1.1.1 diff -u -r1.1.1.1 stream.c --- lib/stream.c 13 Dec 2002 20:15:29 -0000 1.1.1.1 +++ lib/stream.c 15 Nov 2004 11:36:44 -0000 @@ -26,7 +26,7 @@ #include "memory.h" #include "network.h" #include "prefix.h" - +#include "log.h" /*A macro to check pointers in order to not go behind the allocated mem block @@ -35,8 +35,12 @@ */ #define CHECK_SIZE(S, Z) \ - if (((S)->putp + (Z)) > (S)->size) \ - (Z) = (S)->size - (S)->putp; + if (((S)->putp + (Z)) > (S)->size) \ + (Z) = (S)->size - (S)->putp; + +#define UPDATE_ENDP(S) \ + if ((S)->putp > (S)->endp) \ + (S)->endp = (S)->putp; /* Stream is fixed length buffer for network output/input. */ @@ -45,7 +49,13 @@ stream_new (size_t size) { struct stream *s; - + + if (size == 0) + { + zlog_warn ("stream_new(): called with 0 size!"); + return NULL; + } + s = XCALLOC (MTYPE_STREAM, sizeof (struct stream)); s->data = XCALLOC (MTYPE_STREAM_DATA, size); @@ -194,20 +204,22 @@ memset (s->data + s->putp, 0, size); s->putp += size; - if (s->putp > s->endp) - s->endp = s->putp; + + UPDATE_ENDP(s); } /* Put character to the stream. */ int stream_putc (struct stream *s, u_char c) { - if (s->putp >= s->size) return 0; - + if (STREAM_REMAIN (s) < sizeof(u_char)) + { + zlog_warn ("stream_putc(): size exceeds free stream space!"); + return 0; + } s->data[s->putp] = c; s->putp++; - if (s->putp > s->endp) - s->endp = s->putp; + UPDATE_ENDP(s); return 1; } @@ -215,13 +227,14 @@ int stream_putw (struct stream *s, u_int16_t w) { - if ((s->size - s->putp) < 2) return 0; + if (STREAM_REMAIN (s) < sizeof(u_int16_t)) + return 0; s->data[s->putp++] = (u_char)(w >> 8); s->data[s->putp++] = (u_char) w; - - if (s->putp > s->endp) - s->endp = s->putp; + + UPDATE_ENDP (s); + return 2; } @@ -229,21 +242,25 @@ int stream_putl (struct stream *s, u_int32_t l) { - if ((s->size - s->putp) < 4) return 0; - + if (STREAM_REMAIN (s) < sizeof(u_int32_t)) + return 0; + s->data[s->putp++] = (u_char)(l >> 24); s->data[s->putp++] = (u_char)(l >> 16); s->data[s->putp++] = (u_char)(l >> 8); s->data[s->putp++] = (u_char)l; - - if (s->putp > s->endp) - s->endp = s->putp; + + UPDATE_ENDP (s); + return 4; } int stream_putc_at (struct stream *s, unsigned long putp, u_char c) { + if (putp >= STREAM_SIZE(s)) + return 0; + s->data[putp] = c; return 1; } @@ -251,6 +268,9 @@ int stream_putw_at (struct stream *s, unsigned long putp, u_int16_t w) { + if (putp+sizeof(u_int16_t) >= STREAM_SIZE(s)) + return 0; + s->data[putp] = (u_char)(w >> 8); s->data[putp + 1] = (u_char) w; return 2; @@ -259,6 +279,9 @@ int stream_putl_at (struct stream *s, unsigned long putp, u_int32_t l) { + if ( (putp + sizeof (u_int32_t)) >= STREAM_SIZE(s)) + return 0; + s->data[putp] = (u_char)(l >> 24); s->data[putp + 1] = (u_char)(l >> 16); s->data[putp + 2] = (u_char)(l >> 8); @@ -270,14 +293,13 @@ int stream_put_ipv4 (struct stream *s, u_int32_t l) { - if ((s->size - s->putp) < 4) + if (STREAM_REMAIN(s) < 4) return 0; memcpy (s->data + s->putp, &l, 4); s->putp += 4; - if (s->putp > s->endp) - s->endp = s->putp; + UPDATE_ENDP(s); return 4; } @@ -285,14 +307,13 @@ int stream_put_in_addr (struct stream *s, struct in_addr *addr) { - if ((s->size - s->putp) < 4) + if (STREAM_REMAIN(s) < 4) return 0; memcpy (s->data + s->putp, addr, 4); s->putp += 4; - - if (s->putp > s->endp) - s->endp = s->putp; + + UPDATE_ENDP(s); return 4; } @@ -304,15 +325,13 @@ psize = PSIZE (p->prefixlen); - if ((s->size - s->putp) < psize) return 0; + if (STREAM_REMAIN(s) < psize) return 0; stream_putc (s, p->prefixlen); memcpy (s->data + s->putp, &p->u.prefix, psize); s->putp += psize; - if (s->putp > s->endp) - s->endp = s->putp; - + UPDATE_ENDP(s); return psize; } @@ -361,8 +380,7 @@ memcpy (s->data + s->putp, ptr, size); s->putp += size; - if (s->putp > s->endp) - s->endp = s->putp; + UPDATE_ENDP(s); return size; } Index: lib/ChangeLog =================================================================== RCS file: /var/cvsroot/quagga/lib/ChangeLog,v retrieving revision 1.75 diff -u -r1.75 ChangeLog --- lib/ChangeLog 8 Nov 2004 17:34:07 -0000 1.75 +++ lib/ChangeLog 15 Nov 2004 11:36:46 -0000 @@ -1,3 +1,11 @@ +2004-11-15 Paul Jakma + + * stream.c: wrap endp updates in a macro, UPDATE_ENDP. + (stream_new) catch 0 size alloc requests. + (stream_put?_*) check there is sufficient space remaining in + stream. + problems and fixes suggested by Sowmini Varadhan. + 2004-11-08 Paul Jakma * buffer.c: Add missing include of log.h.