Snort mailing list archives

Re: Bus error on sparc


From: Michael Bell <michael.bell () cms hu-berlin de>
Date: Wed, 14 May 2003 16:44:43 +0200

Hi,

I made finally some small fixes in decode.(c|h) and some more fixes in spp_stream4.c. I removed SPARC_TWIDDLE from spp_stream4.c and changed the code for alignment a little bit.

Can a more experienced snort developer verify the diffs please? I only made some small hacks to fix the bus errors but of course I cannot say that I know what I'm doing :)

Without the patch it is possible to crash snort on sparc with some wellformed packets (even if stream4 is not activated).

Thanks Michael
--
-------------------------------------------------------------------
Michael Bell                   Email: michael.bell () cms hu-berlin de
ZE Computer- und Medienservice            Tel.: +49 (0)30-2093 2482
(Computing Centre)                        Fax:  +49 (0)30-2093 2704
Humboldt-University of Berlin
Unter den Linden 6
10099 Berlin                   Email (private): michael.bell () web de
Germany                                       http://www.openca.org
--- snort-2.0.0/src/decode.c    2003-04-09 21:18:23.000000000 +0200
+++ decode.c    2003-05-14 13:27:09.000000000 +0200
@@ -42,7 +42,6 @@
 HttpUri UriBufs[URI_COUNT];
 u_int8_t DecodeBuffer[DECODE_BLEN];
 
-
 /*
  * Function: DecodeEthPkt(Packet *, char *, struct pcap_pkthdr*, u_int8_t*)
  *
@@ -2326,8 +2325,10 @@
     if(pv.checksums_mode & DO_UDP_CHECKSUMS)
     {
         /* look at the UDP checksum to make sure we've got a good packet */
-        ph.sip = (u_int32_t)(p->iph->ip_src.s_addr);
-        ph.dip = (u_int32_t)(p->iph->ip_dst.s_addr);
+        // ph.sip = (u_int32_t)(p->iph->ip_src.s_addr);
+        // ph.dip = (u_int32_t)(p->iph->ip_dst.s_addr);
+        ph.sip = get_u_int32_t (&p->iph->ip_src.s_addr);
+        ph.dip = get_u_int32_t (&p->iph->ip_dst.s_addr);
         ph.zero = 0;
         ph.protocol = p->iph->ip_proto;
         /* ph.udplen is up there */
@@ -3233,3 +3234,24 @@
     pv.decoder_flags.tcpopt_decode     = 1;
     pv.decoder_flags.ipopt_decode     = 1;
 }
+
+u_int8_t get_u_int8_t (void *buffer)
+{
+    u_int8_t i;
+    memcpy (&i, buffer, sizeof (u_int8_t));
+    return i;
+}
+
+u_int16_t get_u_int16_t (void *buffer)
+{
+    u_int16_t i;
+    memcpy (&i, buffer, sizeof (u_int16_t));
+    return i;
+}
+
+u_int32_t get_u_int32_t (void *buffer)
+{
+    u_int32_t i;
+    memcpy (&i, buffer, sizeof (u_int32_t));
+    return i;
+}
--- snort-2.0.0/src/decode.h    2003-04-09 17:45:13.000000000 +0200
+++ decode.h    2003-05-14 13:27:09.000000000 +0200
@@ -1229,6 +1229,10 @@
 void DecodeIPOptions(u_int8_t *, u_int32_t, Packet *);
 void DecodePPPoEPkt(Packet *, struct pcap_pkthdr *, u_int8_t *);
 
+u_int8_t  get_u_int8_t  (void *buffer);
+u_int16_t get_u_int16_t (void *buffer);
+u_int32_t get_u_int32_t (void *buffer);
+
 /* XXX not sure where this guy needs to live at the moment */
 typedef struct _PortList
 {
--- snort-2.0.0/src/preprocessors/spp_stream4.c 2003-04-11 22:45:17.000000000 +0200
+++ spp_stream4.c       2003-05-14 14:23:58.000000000 +0200
@@ -149,16 +149,6 @@
 extern int *file_line;
 #endif /* SNORT_20 */
 
-
-/* We must twiddle to align the offset the ethernet header and align
-   the IP header on solaris -- maybe this will work on HPUX too.
-*/
-#if defined (SOLARIS) || defined (SUNOS) || defined (HPUX)
-#define SPARC_TWIDDLE       2
-#else
-#define SPARC_TWIDDLE       0
-#endif
-
 /* values for the smartbits detector/self perservation */
 #define SELF_PRES_THRESHOLD        50
 #define SELF_PRES_PERIOD           90
@@ -1444,7 +1434,13 @@
         DEBUG_WRAP(DebugMessage(DEBUG_STREAM, "p->tcph is null, returning\n"););
         return 1;
     }
-    
+
+    if(p->iph->ip_proto != IPPROTO_TCP)
+    {
+        DEBUG_WRAP(DebugMessage(DEBUG_STREAM, "ip protocol is not tcp, returning\n"););
+        return 1;
+    }
+  
     if(p->packet_flags & PKT_REBUILT_STREAM)
     {
         DEBUG_WRAP(DebugMessage(DEBUG_STREAM, "REBUILT_STREAM returning\n"););
@@ -3847,18 +3843,24 @@
 
 void InitStream4Pkt()
 {
-    stream_pkt->pkth = calloc(sizeof(SnortPktHeader)+
-                              ETHERNET_HEADER_LEN +
-                              SPARC_TWIDDLE + IP_MAXPACKET,
-                              sizeof(char));
-
+    stream_pkt->pkth = SafeAlloc(sizeof(SnortPktHeader)+
+                              sizeof(EtherHdr) +
+                             sizeof(IPHdr) +
+                             sizeof(TCPHdr) +
+                              IP_MAXPACKET +
+                             6, /* maximum lost through two memory alignments */
+                              0 , NULL);
+
+    /* take care about 4-byte memory alignment of several architectures */
+    /* pkth is correctly aligned for every variable                     */
+    /* eh and iph must be aligned by the software                       */
     stream_pkt->pkt = ((u_int8_t *)stream_pkt->pkth) + sizeof(SnortPktHeader);
-    stream_pkt->eh = (EtherHdr *)((u_int8_t *)stream_pkt->pkt + SPARC_TWIDDLE);
-    stream_pkt->iph =
-        (IPHdr *)((u_int8_t *)stream_pkt->eh + ETHERNET_HEADER_LEN);
-    stream_pkt->tcph = (TCPHdr *)((u_int8_t *)stream_pkt->iph + IP_HEADER_LEN);
+    stream_pkt->pkt += (4 - (sizeof(SnortPktHeader) %4)) %4;
+    stream_pkt->eh   = (EtherHdr *)((u_int8_t *)stream_pkt->pkt);
+    stream_pkt->iph  = (IPHdr *)((u_int8_t *)stream_pkt->eh + sizeof(EtherHdr) + (4-(sizeof(EtherHdr) %4))%4);
+    stream_pkt->tcph = (TCPHdr *)((u_int8_t *)stream_pkt->iph + sizeof(IPHdr));
 
-    stream_pkt->data = (u_int8_t *)stream_pkt->tcph + TCP_HEADER_LEN;
+    stream_pkt->data = (u_int8_t *)stream_pkt->tcph + sizeof(TCPHdr);
 
     stream_pkt->eh->ether_type = htons(0x0800);
     SET_IP_VER(stream_pkt->iph, 0x4);
@@ -3870,6 +3872,12 @@
 
     SET_TCP_OFFSET(stream_pkt->tcph,0x5);
     stream_pkt->tcph->th_flags = TH_PUSH|TH_ACK;
+
+    /* try to crash ip header via sigbus error             */
+    /* this is code to test the alignment                  */
+    /* if the alignment is wrong then the code crashs here */
+    stream_pkt->iph->ip_src.s_addr = 0;
+    stream_pkt->iph->ip_dst.s_addr = 0;
 }
 
 

Current thread: