Ver código fonte

ipv6: fix potential misaligned memory access

Also makes use of encoding/binary package.

Change-Id: I0faf7d55bf3340e84b7d7cf1c77ab3886c728a07
Reviewed-on: https://go-review.googlesource.com/19533
Run-TryBot: Mikio Hara <mikioh.mikioh@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
Mikio Hara 9 anos atrás
pai
commit
b6d7b1396e
4 arquivos alterados com 21 adições e 11 exclusões
  1. 1 2
      ipv6/control_rfc2292_unix.go
  2. 4 8
      ipv6/control_rfc3542_unix.go
  3. 2 1
      ipv6/header.go
  4. 14 0
      ipv6/helper.go

+ 1 - 2
ipv6/control_rfc2292_unix.go

@@ -20,8 +20,7 @@ func marshal2292HopLimit(b []byte, cm *ControlMessage) []byte {
 	m.SetLen(syscall.CmsgLen(4))
 	if cm != nil {
 		data := b[syscall.CmsgLen(0):]
-		// TODO(mikio): fix potential misaligned memory access
-		*(*int32)(unsafe.Pointer(&data[:4][0])) = int32(cm.HopLimit)
+		nativeEndian.PutUint32(data[:4], uint32(cm.HopLimit))
 	}
 	return b[syscall.CmsgSpace(4):]
 }

+ 4 - 8
ipv6/control_rfc3542_unix.go

@@ -20,15 +20,13 @@ func marshalTrafficClass(b []byte, cm *ControlMessage) []byte {
 	m.SetLen(syscall.CmsgLen(4))
 	if cm != nil {
 		data := b[syscall.CmsgLen(0):]
-		// TODO(mikio): fix potential misaligned memory access
-		*(*int32)(unsafe.Pointer(&data[:4][0])) = int32(cm.TrafficClass)
+		nativeEndian.PutUint32(data[:4], uint32(cm.TrafficClass))
 	}
 	return b[syscall.CmsgSpace(4):]
 }
 
 func parseTrafficClass(cm *ControlMessage, b []byte) {
-	// TODO(mikio): fix potential misaligned memory access
-	cm.TrafficClass = int(*(*int32)(unsafe.Pointer(&b[:4][0])))
+	cm.TrafficClass = int(nativeEndian.Uint32(b[:4]))
 }
 
 func marshalHopLimit(b []byte, cm *ControlMessage) []byte {
@@ -38,15 +36,13 @@ func marshalHopLimit(b []byte, cm *ControlMessage) []byte {
 	m.SetLen(syscall.CmsgLen(4))
 	if cm != nil {
 		data := b[syscall.CmsgLen(0):]
-		// TODO(mikio): fix potential misaligned memory access
-		*(*int32)(unsafe.Pointer(&data[:4][0])) = int32(cm.HopLimit)
+		nativeEndian.PutUint32(data[:4], uint32(cm.HopLimit))
 	}
 	return b[syscall.CmsgSpace(4):]
 }
 
 func parseHopLimit(cm *ControlMessage, b []byte) {
-	// TODO(mikio): fix potential misaligned memory access
-	cm.HopLimit = int(*(*int32)(unsafe.Pointer(&b[:4][0])))
+	cm.HopLimit = int(nativeEndian.Uint32(b[:4]))
 }
 
 func marshalPacketInfo(b []byte, cm *ControlMessage) []byte {

+ 2 - 1
ipv6/header.go

@@ -5,6 +5,7 @@
 package ipv6
 
 import (
+	"encoding/binary"
 	"fmt"
 	"net"
 )
@@ -42,7 +43,7 @@ func ParseHeader(b []byte) (*Header, error) {
 		Version:      int(b[0]) >> 4,
 		TrafficClass: int(b[0]&0x0f)<<4 | int(b[1])>>4,
 		FlowLabel:    int(b[1]&0x0f)<<16 | int(b[2])<<8 | int(b[3]),
-		PayloadLen:   int(b[4])<<8 | int(b[5]),
+		PayloadLen:   int(binary.BigEndian.Uint16(b[4:6])),
 		NextHeader:   int(b[6]),
 		HopLimit:     int(b[7]),
 	}

+ 14 - 0
ipv6/helper.go

@@ -5,8 +5,10 @@
 package ipv6
 
 import (
+	"encoding/binary"
 	"errors"
 	"net"
+	"unsafe"
 )
 
 var (
@@ -15,8 +17,20 @@ var (
 	errInvalidConnType = errors.New("invalid conn type")
 	errOpNoSupport     = errors.New("operation not supported")
 	errNoSuchInterface = errors.New("no such interface")
+
+	nativeEndian binary.ByteOrder
 )
 
+func init() {
+	i := uint32(1)
+	b := (*[4]byte)(unsafe.Pointer(&i))
+	if b[0] == 1 {
+		nativeEndian = binary.LittleEndian
+	} else {
+		nativeEndian = binary.BigEndian
+	}
+}
+
 func boolint(b bool) int {
 	if b {
 		return 1