-
Notifications
You must be signed in to change notification settings - Fork 5k
fix issue #3563: There is a buffer overflow bug in Shadowsocks UDP packet encoding #3564
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 issue #3563: There is a buffer overflow bug in Shadowsocks UDP packet encoding #3564
Conversation
… the EncodeUDPPacket function of proxy/shadowsocks/protocol.go, a fixed-size buffer of 2048 bytes is created using buf.New(). However, the actual size of a UDP packet includes: IV: 16 bytes (e.g., for aes-128-gcm) Destination address: 7~258 bytes (depending on IPv4/IPv6/domain) Payload: variable, up to 2048 bytes AEAD authentication tag: 16 bytes When the incoming payload is large (close to 2048 bytes), the total size exceeds the buffer capacity. When b.Extend() is called in AEADCipher.EncodePacket() to allocate space for the authentication tag, it triggers panic: extending out of bound, causing the process to crash. Fix Before creating the buffer, calculate the required buffer size based on IV length, maximum address length (258 bytes), payload length, and AEAD overhead (16 bytes). If the required size exceeds the default buffer size (2048 bytes), use buf.NewWithSize() to allocate a sufficiently large buffer.
xiaokangwang
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for your work, this looks good to me!
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## master #3564 +/- ##
==========================================
+ Coverage 22.78% 23.22% +0.43%
==========================================
Files 819 836 +17
Lines 52429 45434 -6995
==========================================
- Hits 11946 10551 -1395
+ Misses 39279 33668 -5611
- Partials 1204 1215 +11 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
|
Why is "max address length" 258? Isn't it v2ray-core/proxy/trojan/protocol.go Lines 147 to 160 in b2c3b25
|
I will send a pull request with the suggested change. Sorry for not catching this during review. |
… the EncodeUDPPacket function of proxy/shadowsocks/protocol.go, a fixed-size buffer of 2048 bytes is created using buf.New().
However, the actual size of a UDP packet includes: IV: 16 bytes (e.g., for aes-128-gcm)
Destination address: 7~258 bytes (depending on IPv4/IPv6/domain) Payload: variable, up to 2048 bytes
AEAD authentication tag: 16 bytes
When the incoming payload is large (close to 2048 bytes), the total size exceeds the buffer capacity. When b.Extend() is called in AEADCipher.EncodePacket() to allocate space for the authentication tag, it triggers panic: extending out of bound, causing the process to crash. Fix
Before creating the buffer, calculate the required buffer size based on IV length, maximum address length (258 bytes), payload length, and AEAD overhead (16 bytes). If the required size exceeds the default buffer size (2048 bytes), use buf.NewWithSize() to allocate a sufficiently large buffer.
问题描述
Shadowsocks UDP 数据包编码时存在缓冲区溢出的 bug。在 proxy/shadowsocks/protocol.go 的 EncodeUDPPacket 函数中,使用 buf.New() 创建了一个固定大小为 2048 字节的缓冲区。
然而,UDP 数据包的实际大小需要包含:
IV:16 字节(以 aes-128-gcm 为例)
目标地址:7~258 字节(取决于 IPv4/IPv6/域名)
Payload:可变,最大可达 2048 字节
AEAD 认证标签:16 字节
当传入的 payload 较大(接近 2048 字节)时,总大小会超过缓冲区容量。在调用 AEADCipher.EncodePacket() 中的 b.Extend() 扩展认证标签空间时,会触发 panic: extending out of bound,导致进程崩溃。
修复方案
在创建缓冲区之前,根据 IV 长度、最大地址长度(258 字节)、payload 长度和 AEAD overhead(16 字节)计算所需的缓冲区大小。如果需要的大小超过默认缓冲区大小(2048 字节),则使用 buf.NewWithSize() 分配足够大的缓冲区。