[quagga-dev 1787] Re: alignment faults in ospfd LSA processing on sparc64

Paul Jakma paul at clubi.ie
Thu Nov 4 10:24:20 GMT 2004


On Mon, 1 Nov 2004, Paul Jakma wrote:

> And we need to check LSA header length for alignment before dereferencing it. 
> I'll stick that on my TODO list.

Attached is an untested (and probably wrong) attempt to add alignment 
checks to ospfd.

regards,
-- 
Paul Jakma	paul at clubi.ie	paul at jakma.org	Key ID: 64A2FF6A
Fortune:
Q:	"What is the burning question on the mind of every dyslexic
 	existentialist?"
A:	"Is there a dog?"
-------------- next part --------------
? ospfd/ospf_packet.loT
? ospfd/test
? ospfd/test.c
Index: ospfd/ospf_packet.c
===================================================================
RCS file: /var/cvsroot/quagga/ospfd/ospf_packet.c,v
retrieving revision 1.51
diff -u -r1.51 ospf_packet.c
--- ospfd/ospf_packet.c	2 Nov 2004 20:26:45 -0000	1.51
+++ ospfd/ospf_packet.c	4 Nov 2004 10:23:09 -0000
@@ -271,6 +271,8 @@
   
 
   ibuf = STREAM_PNT (s);
+
+  /* ospf header must already be aligned - see ospf_read */
   ospfh = (struct ospf_header *) ibuf;
 
   /* Get pointer to the end of the packet. */
@@ -743,6 +745,13 @@
 
   hello = (struct ospf_hello *) STREAM_PNT (s);
 
+  if (OSPF_IS_MISALIGNED (hello, struct ospf_hello))
+    {
+      zlog_warn ("ospf_hello[%s]: Hello header is misaligned!",
+                 inet_ntoa (iph->ip_src));
+      return;
+    }
+  
   /* If Hello is myself, silently discard. */
   if (IPV4_ADDR_SAME (&ospfh->router_id, &oi->ospf->router_id))
     {
@@ -974,7 +983,13 @@
     {
       lsah = (struct lsa_header *) STREAM_PNT (s);
       stream_forward (s, OSPF_LSA_HEADER_SIZE);
-
+      
+      if (OSPF_IS_MISALIGNED (lsah, struct lsa_header))
+        {
+          zlog_warn ("Packet [DD:RECV]: LSA Header misaligned!");
+          return;
+        }
+      
       /* Unknown LS type. */
       if (lsah->type < OSPF_MIN_LSA || lsah->type >= OSPF_MAX_LSA)
 	{
@@ -1089,9 +1104,14 @@
 
   /* Increment statistics. */
   oi->db_desc_in++;
-
+  
   dd = (struct ospf_db_desc *) STREAM_PNT (s);
-
+  if (OSPF_IS_MISALIGNED (dd, struct ospf_db_desc))
+    {
+      zlog_warn ("Packet[DD]: DB Description header misaligned!");
+      return;
+    }
+  
   nbr = ospf_nbr_lookup (oi, iph, ospfh);
   if (nbr == NULL)
     {
@@ -1449,6 +1469,13 @@
        size -= length, stream_forward (s, length), count--)
     {
       lsah = (struct lsa_header *) STREAM_PNT (s);
+      
+      if (OSPF_IS_MISALIGNED (lsah, struct lsa_header))
+        {
+          zlog_warn ("Link State Update: LSA header misaligned!");
+          return lsas;
+        }
+      
       length = ntohs (lsah->length);
 
       if (length > size)
@@ -1961,10 +1988,17 @@
       lsa = ospf_lsa_new ();
       lsa->data = (struct lsa_header *) STREAM_PNT (s);
 
-      /* lsah = (struct lsa_header *) STREAM_PNT (s); */
+      if (OSPF_IS_MISALIGNED (lsa->data, struct lsa_header))
+        {
+          zlog_warn ("Link State Acknowledgment: LSA header misaligned!");
+          lsa->data = NULL;
+          ospf_lsa_discard (lsa);
+          return;
+        }
+            
       size -= OSPF_LSA_HEADER_SIZE;
       stream_forward (s, OSPF_LSA_HEADER_SIZE);
-
+      
       if (lsa->data->type < OSPF_MIN_LSA || lsa->data->type >= OSPF_MAX_LSA)
 	{
 	  lsa->data = NULL;
@@ -2356,7 +2390,15 @@
   
   /* Get ospf packet header. */
   ospfh = (struct ospf_header *) STREAM_PNT (ibuf);
-
+  if (OSPF_IS_MISALIGNED (ospfh, struct ospf_header))
+    {
+      /* this couldnt possibly happen, iph must already be aligned */
+      zlog_warn ("ospf_read[%s]: OSPF Header misaligned!",
+                 inet_ntoa (iph->ip_src));
+      stream_free (ibuf);
+      return 0;
+    }
+  
   /* associate packet with ospf interface */
   oi = ospf_if_lookup_recv_if (ospf, iph->ip_src);
 
Index: ospfd/ospfd.h
===================================================================
RCS file: /var/cvsroot/quagga/ospfd/ospfd.h,v
retrieving revision 1.11
diff -u -r1.11 ospfd.h
--- ospfd/ospfd.h	11 Oct 2004 11:00:31 -0000	1.11
+++ ospfd/ospfd.h	4 Nov 2004 10:23:10 -0000
@@ -125,6 +125,18 @@
 #define OSPF_LS_REFRESH_SHIFT       (60 * 15)
 #define OSPF_LS_REFRESH_JITTER      60
 
+/* Alignment for network data 
+ * attribute will have been defined in zebra.h if non-GCC
+ */
+#define OSPF_DEFAULT_ALIGNMENT 4U
+#ifdef __attribute__
+#define OSPF_IS_MISALIGNED(PNT,TYPE) \
+  ((uintptr_t)(PNT) % OSPF_DEFAULT_ALIGNMENT)
+#else
+#define OSPF_IS_MISALIGNED(PNT,TYPE) \
+  ((uintptr_t)(PNT) % __alignof__ (TYPE))
+#endif /* OSPF_IS_MISALIGNED */
+
 /* OSPF master for system wide configuration and variables. */
 struct ospf_master
 {


More information about the Quagga-dev mailing list