]> git.puffer.fish Git - mirror/frr.git/commitdiff
Quagga: Fix alignment in netlink messages in some cases
authorvivek <vivek@cumulusnetworks.com>
Fri, 15 Apr 2016 20:32:23 +0000 (13:32 -0700)
committerDonald Sharp <sharpd@cumulusnetworks.com>
Fri, 23 Sep 2016 13:30:55 +0000 (09:30 -0400)
The alignment of nlmsg_len is calculated wrong leading to wrong rta_len
calculations for nested TLVs when the data length of the last TLV added
to the nested TLV is not aligned to RTA_ALIGNTO already. Use same fix
that was implemented in iproute2 by Thomas Graf circa 2005. A reference
to the fix is at
http://oss.sgi.com/archives/netdev/2005-03/msg03103.html.

Signed-off-by: Vivek Venkatraman <vivek@cumulusnetworks.com>
Reviewed-by: Donald Sharp <sharpd@cumulusnetworks.com>
Ticket: CM-6491
Reviewed By: CCR-3087
Testing Done: MPLS testing with other patches in SE-1

Note: Prior to MPLS, we didn't face this problem as we haven't really had
any nested TLVs; even if RTA_MULTIPATH were to be considered a nested TLV,
it didn't have any non-aligned fields.

zebra/rt_netlink.c

index a6984f7f2f0b7ce6eb9b62185169c5e9a03e9824..41ecb1d0c4960025758d17f80d474429f37e55d5 100644 (file)
@@ -1647,14 +1647,14 @@ addattr_l (struct nlmsghdr *n, unsigned int maxlen, int type, void *data, int al
 
   len = RTA_LENGTH (alen);
 
-  if (NLMSG_ALIGN (n->nlmsg_len) + len > maxlen)
+  if (NLMSG_ALIGN (n->nlmsg_len) + RTA_ALIGN (len) > maxlen)
     return -1;
 
   rta = (struct rtattr *) (((char *) n) + NLMSG_ALIGN (n->nlmsg_len));
   rta->rta_type = type;
   rta->rta_len = len;
   memcpy (RTA_DATA (rta), data, alen);
-  n->nlmsg_len = NLMSG_ALIGN (n->nlmsg_len) + len;
+  n->nlmsg_len = NLMSG_ALIGN (n->nlmsg_len) + RTA_ALIGN (len);
 
   return 0;
 }
@@ -1667,14 +1667,14 @@ rta_addattr_l (struct rtattr *rta, int maxlen, int type, void *data, int alen)
 
   len = RTA_LENGTH (alen);
 
-  if ((int)RTA_ALIGN (rta->rta_len) + len > maxlen)
+  if (RTA_ALIGN (rta->rta_len) + RTA_ALIGN (len) > maxlen)
     return -1;
 
   subrta = (struct rtattr *) (((char *) rta) + RTA_ALIGN (rta->rta_len));
   subrta->rta_type = type;
   subrta->rta_len = len;
   memcpy (RTA_DATA (subrta), data, alen);
-  rta->rta_len = NLMSG_ALIGN (rta->rta_len) + len;
+  rta->rta_len = NLMSG_ALIGN (rta->rta_len) + RTA_ALIGN (len);
 
   return 0;
 }
@@ -1684,21 +1684,7 @@ rta_addattr_l (struct rtattr *rta, int maxlen, int type, void *data, int alen)
 int
 addattr32 (struct nlmsghdr *n, unsigned int maxlen, int type, int data)
 {
-  int len;
-  struct rtattr *rta;
-
-  len = RTA_LENGTH (4);
-
-  if (NLMSG_ALIGN (n->nlmsg_len) + len > maxlen)
-    return -1;
-
-  rta = (struct rtattr *) (((char *) n) + NLMSG_ALIGN (n->nlmsg_len));
-  rta->rta_type = type;
-  rta->rta_len = len;
-  memcpy (RTA_DATA (rta), &data, 4);
-  n->nlmsg_len = NLMSG_ALIGN (n->nlmsg_len) + len;
-
-  return 0;
+  return addattr_l(n, maxlen, type, &data, sizeof(u_int32_t));
 }
 
 static int