]> Cypherpunks repositories - gostls13.git/commitdiff
net: more accurate parsing of IPv4 header on IPConn
authorMikio Hara <mikioh.mikioh@gmail.com>
Sun, 18 Jan 2015 07:28:15 +0000 (16:28 +0900)
committerMikio Hara <mikioh.mikioh@gmail.com>
Mon, 19 Jan 2015 03:20:59 +0000 (03:20 +0000)
As shown in #9395, inaccurate implementation would be a cause of parsing
IPv4 header twice and corrupted upper-layer message issues.

Change-Id: Ia1a042e7ca58ee4fcb38fe9ec753c2ab100592ca
Reviewed-on: https://go-review.googlesource.com/3001
Reviewed-by: Ian Lance Taylor <iant@golang.org>
src/net/iprawsock_posix.go

index 99b081ba8c8ea5ddccc3eefa8ae7f85212d56d87..e11eacec6a0cd648c445e70bb1625e77ffc3b29d 100644 (file)
@@ -83,17 +83,28 @@ func (c *IPConn) ReadFromIP(b []byte) (int, *IPAddr, error) {
        switch sa := sa.(type) {
        case *syscall.SockaddrInet4:
                addr = &IPAddr{IP: sa.Addr[0:]}
-               if len(b) >= IPv4len { // discard ipv4 header
-                       hsize := (int(b[0]) & 0xf) * 4
-                       copy(b, b[hsize:])
-                       n -= hsize
-               }
+               n = stripIPv4Header(n, b)
        case *syscall.SockaddrInet6:
                addr = &IPAddr{IP: sa.Addr[0:], Zone: zoneToString(int(sa.ZoneId))}
        }
        return n, addr, err
 }
 
+func stripIPv4Header(n int, b []byte) int {
+       if len(b) < 20 {
+               return n
+       }
+       l := int(b[0]&0x0f) << 2
+       if 20 > l || l > len(b) {
+               return n
+       }
+       if b[0]>>4 != 4 {
+               return n
+       }
+       copy(b, b[l:])
+       return n - l
+}
+
 // ReadFrom implements the PacketConn ReadFrom method.
 func (c *IPConn) ReadFrom(b []byte) (int, Addr, error) {
        if !c.ok() {