summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDonald Sharp <sharpd@cumulusnetworks.com>2017-04-15 13:25:03 -0400
committerDonald Sharp <sharpd@cumulusnetworks.com>2017-04-15 13:26:56 -0400
commit7abc04e686fefeb76bc825e908837e55bec0efc7 (patch)
tree269e8dc855be7b15646f6db3fbec86ca88487d56
parent9fbea8d56d4aa5d71ce0ae9204e15fbd06c3c02a (diff)
zebra: Add some more checks to fec [un]registration
Be a bit more rigoruous about what we can receive from another protocol and attempt to make the code less likely to crash and to just safely bail out when an error is received. Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
-rw-r--r--zebra/zserv.c38
1 files changed, 38 insertions, 0 deletions
diff --git a/zebra/zserv.c b/zebra/zserv.c
index afbaf7eefa..416e5444ea 100644
--- a/zebra/zserv.c
+++ b/zebra/zserv.c
@@ -934,6 +934,8 @@ zserv_rnh_unregister (struct zserv *client, int sock, u_short length,
return 0;
}
+#define ZEBRA_MIN_FEC_LENGTH 9
+
/* FEC register */
static int
zserv_fec_register (struct zserv *client, int sock, u_short length)
@@ -950,10 +952,28 @@ zserv_fec_register (struct zserv *client, int sock, u_short length)
if (!zvrf)
return 0; // unexpected
+ /*
+ * The minimum amount of data that can be sent for one fec
+ * registration
+ */
+ if (length < ZEBRA_MIN_FEC_LENGTH)
+ {
+ zlog_err ("fec_register: Received a fec register of length %d, it is of insufficient size to properly decode",
+ length);
+ return -1;
+ }
+
while (l < length)
{
flags = stream_getw(s);
p.family = stream_getw(s);
+ if (p.family != AF_INET &&
+ p.family != AF_INET6)
+ {
+ zlog_err ("fec_register: Received unknown family type %d\n",
+ p.family);
+ return -1;
+ }
p.prefixlen = stream_getc(s);
l += 5;
stream_get(&p.u.prefix, s, PSIZE(p.prefixlen));
@@ -984,11 +1004,29 @@ zserv_fec_unregister (struct zserv *client, int sock, u_short length)
if (!zvrf)
return 0; // unexpected
+ /*
+ * The minimum amount of data that can be sent for one
+ * fec unregistration
+ */
+ if (length < ZEBRA_MIN_FEC_LENGTH)
+ {
+ zlog_err ("fec_unregister: Received a fec unregister of length %d, it is of insufficient size to properly decode",
+ length);
+ return -1;
+ }
+
while (l < length)
{
//flags = stream_getw(s);
(void)stream_getw(s);
p.family = stream_getw(s);
+ if (p.family != AF_INET &&
+ p.family != AF_INET6)
+ {
+ zlog_err ("fec_unregister: Received unknown family type %d\n",
+ p.family);
+ return -1;
+ }
p.prefixlen = stream_getc(s);
l += 5;
stream_get(&p.u.prefix, s, PSIZE(p.prefixlen));