Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix the buffer overlap panic when read a udp/packet socket #97

Merged
merged 2 commits into from
Jun 28, 2018
Merged

Fix the buffer overlap panic when read a udp/packet socket #97

merged 2 commits into from
Jun 28, 2018

Conversation

lixin9311
Copy link
Collaborator

As explained in #95
It should be safe without locking when reading from the packet socket.

@@ -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
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No need for the extra buffer.

@@ -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)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Keep reading into b here…

if err != nil {
return n, addr, err
}
b, err = Unpack(b, b[:n], c.Cipher)
b, err = Unpack(b, c.rbuf[:n], c.Cipher)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

…and memmove here

bb, err = Unpack(b[c.IVSize():], b[:n], c. Cipher)
if err != nil {
    return n, addr, err
}
copy(b, bb)
return len(bb), addr, err

This way, we save 64KB per UDP connection and never have to worry about locking.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the Unpack will still panic, since b[c.IVSize():] and b[:n] partially overlaps.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How? Only XORKeyStream forbids inexact overlap. Unpack does not care.

@lixin9311
Copy link
Collaborator Author

We don't really need 64k buffer for read, since the MTU is much smaller, it xpuld be 10k or less. And if we use the buffer b in place, we have to call copy(). I don't think copy is better than just using a new buffer.

@riobard
Copy link

riobard commented Jun 28, 2018

Max UDP packet size is a little less than 64KB. We cannot assume it'll be smaller due to potential fragmentation reassembly. And the packet might not come from WAN at all, in which case 1500 MTU cannot be assumed either.

As for the extra copy, Golang implements it via memmove which is very efficient (especially when the packet size is small and it fits in the cache).

@lixin9311
Copy link
Collaborator Author

Fixed as you wish. By the way, I have a local build which is compatible with Shadowsocks-android as its built-in client. But it uses some features only available after go 1.11. If you would like to keep the code here, I can make a PR after go 1.11 is released.

@riobard riobard merged commit 26eb243 into shadowsocks:master Jun 28, 2018
@riobard
Copy link

riobard commented Jun 28, 2018

Thanks for the PR! BTW do we need to fix the AEAD packet Unpack as well? I think it will also be affected by the Go 1.11 InexactOverlap constraint.

What features do you use from Go 1.11? I'd like to take a look :D

@lixin9311
Copy link
Collaborator Author

you are right, the AEAD part also needs to be fixed.

New APIs in the net package have been exposed in go 1.11,
https://go-review.googlesource.com/c/go/+/72810

I need to protect the sockets which are connecting the server from VPN connections, before calling equivalent connect(socket) in C when creating them.
https://developer.android.com/reference/android/net/VpnService.html#protect(java.net.Socket)

@lixin9311 lixin9311 deleted the packet_decryption_overlap_fix branch June 28, 2018 17:39
xiahaijiao pushed a commit to xiahaijiao/go-shadowsocks2 that referenced this pull request Jan 10, 2024
…erlap_fix

Fix the buffer overlap panic when read a udp/packet socket
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants