From c5d141688dd0141a3d2649cb96536bba4e02d075 Mon Sep 17 00:00:00 2001 From: lucus Date: Thu, 28 Jun 2018 16:04:50 +0900 Subject: [PATCH 1/2] Fix the buffer overlap panic when read a udp/packet socket --- shadowstream/packet.go | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/shadowstream/packet.go b/shadowstream/packet.go index 8bbb27b5..3f6cc445 100644 --- a/shadowstream/packet.go +++ b/shadowstream/packet.go @@ -46,19 +46,20 @@ func Unpack(dst, pkt []byte, s Cipher) ([]byte, error) { type packetConn struct { net.PacketConn Cipher - buf []byte + wbuf []byte + rbuf []byte sync.Mutex // write lock } // NewPacketConn wraps a net.PacketConn with stream cipher encryption/decryption. func NewPacketConn(c net.PacketConn, ciph Cipher) net.PacketConn { - return &packetConn{PacketConn: c, Cipher: ciph, buf: make([]byte, 64*1024)} + return &packetConn{PacketConn: c, Cipher: ciph, wbuf: make([]byte, 64*1024), rbuf: make([]byte, 64*1024)} } func (c *packetConn) WriteTo(b []byte, addr net.Addr) (int, error) { c.Lock() defer c.Unlock() - buf, err := Pack(c.buf, b, c.Cipher) + buf, err := Pack(c.wbuf, b, c.Cipher) if err != nil { return 0, err } @@ -67,10 +68,10 @@ func (c *packetConn) WriteTo(b []byte, addr net.Addr) (int, error) { } func (c *packetConn) ReadFrom(b []byte) (int, net.Addr, error) { - n, addr, err := c.PacketConn.ReadFrom(b) + n, addr, err := c.PacketConn.ReadFrom(c.rbuf) if err != nil { return n, addr, err } - b, err = Unpack(b, b[:n], c.Cipher) + b, err = Unpack(b, c.rbuf[:n], c.Cipher) return len(b), addr, err } From cc5b55c1b6c3d8b0541ee243adf6c0590f69a0c7 Mon Sep 17 00:00:00 2001 From: lucus Date: Thu, 28 Jun 2018 23:39:02 +0900 Subject: [PATCH 2/2] Use copy instead of a new buffer --- shadowstream/packet.go | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/shadowstream/packet.go b/shadowstream/packet.go index 3f6cc445..b266f581 100644 --- a/shadowstream/packet.go +++ b/shadowstream/packet.go @@ -46,20 +46,19 @@ func Unpack(dst, pkt []byte, s Cipher) ([]byte, error) { type packetConn struct { net.PacketConn Cipher - wbuf []byte - rbuf []byte + buf []byte sync.Mutex // write lock } // NewPacketConn wraps a net.PacketConn with stream cipher encryption/decryption. func NewPacketConn(c net.PacketConn, ciph Cipher) net.PacketConn { - return &packetConn{PacketConn: c, Cipher: ciph, wbuf: make([]byte, 64*1024), rbuf: make([]byte, 64*1024)} + return &packetConn{PacketConn: c, Cipher: ciph, buf: make([]byte, 64*1024)} } func (c *packetConn) WriteTo(b []byte, addr net.Addr) (int, error) { c.Lock() defer c.Unlock() - buf, err := Pack(c.wbuf, b, c.Cipher) + buf, err := Pack(c.buf, b, c.Cipher) if err != nil { return 0, err } @@ -68,10 +67,14 @@ func (c *packetConn) WriteTo(b []byte, addr net.Addr) (int, error) { } func (c *packetConn) ReadFrom(b []byte) (int, net.Addr, error) { - n, addr, err := c.PacketConn.ReadFrom(c.rbuf) + n, addr, err := c.PacketConn.ReadFrom(b) if err != nil { return n, addr, err } - b, err = Unpack(b, c.rbuf[:n], c.Cipher) + bb, err := Unpack(b[c.IVSize():], b[:n], c.Cipher) + if err != nil { + return n, addr, err + } + copy(b, bb) return len(b), addr, err }