NetBSD-Bugs archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

kern/43541: Unaligned access in pf_normalize_tcpopt()



>Number:         43541
>Category:       kern
>Synopsis:       Unaligned access in pf_normalize_tcpopt()
>Confidential:   no
>Severity:       serious
>Priority:       low
>Responsible:    kern-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Mon Jun 28 16:35:00 +0000 2010
>Originator:     Gregory T. Andersen
>Release:        5.0.2
>Organization:
CradlePoint Technology
>Environment:
NetBSD  5.0.2 NetBSD 5.0.2 (PUCK) #0: Fri Jun 25 11:18:40 MDT 2010  
andersen@andersen:/build/sys/arch/evbmips/compile/obj/PUCK evbmips
>Description:
Ran into a unaligned access kernel crasher on a MIPS32 architecture when 
certain PF rules are applied that manipulate tcp options (mss).
>How-To-Repeat:
Receive TCP packets where the MSS TCP option is unaligned on architecture that 
doesn't handle unaligned access with mss scrub rule in PF.
>Fix:
Potential patch:

Index: sys/dist/pf/net/pf_norm.c
===================================================================
--- sys/dist/pf/net/pf_norm.c
+++ sys/dist/pf/net/pf_norm.c   (working copy)
@@ -1878,7 +1878,7 @@
 pf_normalize_tcpopt(struct pf_rule *r, struct mbuf *m, struct tcphdr *th,
     int off)
 {
-       u_int16_t       *mss;
+       u_int16_t        mss;
        int              thoff;
        int              opt, cnt, optlen = 0;
        int              rewrite = 0;
@@ -1903,11 +1903,12 @@
                }
                switch (opt) {
                case TCPOPT_MAXSEG:
-                       mss = (u_int16_t *)(optp + 2);
-                       if ((ntohs(*mss)) > r->max_mss) {
+                       mss = (optp[2] << 8) | optp[3];
+                       if (mss > r->max_mss) {
                                th->th_sum = pf_cksum_fixup(th->th_sum,
-                                   *mss, htons(r->max_mss), 0);
-                               *mss = htons(r->max_mss);
+                                   htons(mss), htons(r->max_mss), 0);
+                               optp[2] = (u_char)(r->max_mss >> 8) & 0xff;
+                               optp[3] = (u_char)(r->max_mss) & 0xff;
                                rewrite = 1;
                        }
                        break;



Home | Main Index | Thread Index | Old Index