Browse code

Replace unaligned 16bit access to TCP MSS value with bytewise access

TCP options are not always word-aligned, and accessing a 16bit value
at an odd memory address will cause a "bus error" crash on some
architectures, e.g. Linux/Sparc(64)

Trac #497

Signed-off-by: Gert Doering <gert@greenie.muc.de>
Acked-by: Steffan Karger <steffan.karger@fox-it.com>
Message-Id: <1440680402-96548-1-git-send-email-gert@greenie.muc.de>
URL: http://article.gmane.org/gmane.network.openvpn.devel/10056

Gert Doering authored on 2015/08/27 22:00:02
Showing 1 changed files
... ...
@@ -129,7 +129,7 @@ mss_fixup_dowork (struct buffer *buf, uint16_t maxmss)
129 129
 {
130 130
   int hlen, olen, optlen;
131 131
   uint8_t *opt;
132
-  uint16_t *mss;
132
+  uint16_t mssval;
133 133
   int accumulate;
134 134
   struct openvpn_tcphdr *tc;
135 135
 
... ...
@@ -159,14 +159,13 @@ mss_fixup_dowork (struct buffer *buf, uint16_t maxmss)
159 159
       if (*opt == OPENVPN_TCPOPT_MAXSEG) {
160 160
         if (optlen != OPENVPN_TCPOLEN_MAXSEG)
161 161
           continue;
162
-        mss = (uint16_t *)(opt + 2);
163
-        if (ntohs (*mss) > maxmss) {
164
-          dmsg (D_MSS, "MSS: %d -> %d",
165
-               (int) ntohs (*mss),
166
-	       (int) maxmss);
167
-          accumulate = *mss;
168
-          *mss = htons (maxmss);
169
-          accumulate -= *mss;
162
+	mssval = (opt[2]<<8)+opt[3];
163
+	if (mssval > maxmss) {
164
+	  dmsg (D_MSS, "MSS: %d -> %d", (int) mssval, (int) maxmss);
165
+	  accumulate = htons(mssval);
166
+	  opt[2] = (maxmss>>8)&0xff;
167
+	  opt[3] = maxmss&0xff;
168
+	  accumulate -= htons(maxmss);
170 169
           ADJUST_CHECKSUM (accumulate, tc->check);
171 170
         }
172 171
       }