panjf2000 / gnet

🚀 gnet is a high-performance, lightweight, non-blocking, event-driven networking framework written in pure Go.
https://gnet.host
Apache License 2.0
9.69k stars 1.04k forks source link

[Bug]: conn.Next not safe #647

Closed zhongweikang closed 2 weeks ago

zhongweikang commented 2 weeks ago

Actions I've taken before I'm here

What happened?

https://github.com/panjf2000/gnet/blob/v2.5.9/connection_unix.go#L327-L330

代码329行,返回了c.inboundBuffer内部的字节数组 代码327行defer c.inboundBuffer.Discard(n),会回收c.inboundBuffer中的字节数组,回收到sync.Pool

假设有两个goroutine 一个goroutine正在使用329行返回的字节数组 另一个goroutine读取到了327行回收的字节数组(因为被回收了,所以另一个goroutine能被复用) 导致两个goroutine同时操作了同一块字节数组,报文错乱!

Major version of gnet

v2

Specific version of gnet

V2

Operating system

Linux, macOS

OS version

Linux 3.10.0

Go version

go1.17.12

Relevant log output

Code snippets (optional)

defer c.inboundBuffer.Discard(n) //nolint:errcheck
    if len(head) >= n {
        return head[:n], err
    }

How to Reproduce

多个事件循环并发执行时概率复现

Does this issue reproduce with the latest release?

It can reproduce with the latest release

panjf2000 commented 2 weeks ago

看文档,这个方法本来就是非线程安全的:https://pkg.go.dev/github.com/panjf2000/gnet/v2#Conn

gh-translator commented 2 weeks ago

🤖 Non-English text detected, translating ...


Looking at the documentation, this method is inherently non-thread-safe: https://pkg.go.dev/github.com/panjf2000/gnet/v2#Conn