Xray-core: Solution for panic: runtime error: slice bounds out of range [2:0]

Greatings!

I have lot of users on simple VLESS+TCP+XTLS config, which most of time is okay, but every 5-15 minutes i have a panic and crash Xray for about 30 seconds. I don’t know how this error occurs, but it is exists on all versions of Xray (until latest 1.7) have this weird bug:

panic: runtime error: slice bounds out of range [2:0]

also lots of other people has this issue, for example: #1422

Solution:

i looked the exact line of code which cause this error, and found out that in an array never low index be higher than high index, [A:B], so never A should be higher than B, and i don’t know it happening! its not logical, buy may in some other parts of code which main developers are aware of, A became higher than B, then i add a compare between A and B, that never A be higher than B, And it solved the panic for ever!:

file: github.com/xtls/xray-core/common/buf/buffer.go:253

// Read implements io.Reader.Read().
func (b *Buffer) Read(data []byte) (int, error) {
	if b.Len() == 0 {
		return 0, io.EOF
	}
        // this is line 253
	nBytes := copy(data, b.v[b.start:b.end])
	if int32(nBytes) == b.Len() {
		b.Clear()
	} else {
		b.start += int32(nBytes)
	}
	return nBytes, nil
}

I added this line of code above line 253

	if b.start >= b.end {
		return 0, io.EOF
	}

Dear @RPRX

Q1: I ask you to check the code and include it in next version Q2: is “return 0, io.EOF” is best return for such that illogical inputs?

final code:

// Read implements io.Reader.Read().
func (b *Buffer) Read(data []byte) (int, error) {
	if b.Len() == 0 {
		return 0, io.EOF
	}
	if b.start >= b.end {
		return 0, io.EOF
	}
	nBytes := copy(data, b.v[b.start:b.end])
	if int32(nBytes) == b.Len() {
		b.Clear()
	} else {
		b.start += int32(nBytes)
	}
	return nBytes, nil
}

full panic log:

goroutine 1699405 [running]:
github.com/xtls/xray-core/common/buf.(*Buffer).Read(...)
github.com/xtls/xray-core/common/buf/buffer.go:253
github.com/xtls/xray-core/common/buf.SplitBytes({0xc00c62b7d8, 0x1, 0x1}, {0xc007b5a000?, 0xc00b170e70?, 0xc006a07dfc?}) github.com/xtls/xray-core/common/buf/multi_buffer.go:105 +0x290
github.com/xtls/xray-core/common/buf.(*BufferedReader).Read(0xc00bce2570, {0xc007b5a000?, 0xc00bb9e060?, 0x0?}) github.com/xtls/xray-core/common/buf/reader.go:68 +0x92 io.ReadAtLeast({0x11ca3c0, 0xc00bce2570}, {0xc007b5a000, 0x2e, 0x2000}, 0x2e) io/io.go:332 +0x9a io.ReadFull(...)
io/io.go:351
github.com/xtls/xray-core/common/buf.(*Buffer).ReadFullFrom(0xc00bb9e060?, {0x11ca3c0?, 0xc00bce2570?}, 0x2?)
github.com/xtls/xray-core/common/buf/buffer.go:276 +0x85 github.com/xtls/xray-core/proxy/vless/encoding.(*LengthPacketReader).ReadMultiBuffer(0xc002c2dfb0) github.com/xtls/xray-core/proxy/vless/encoding/addons.go:180 +0x205
github.com/xtls/xray-core/common/buf.copyInternal({0x11cb1c0, 0xc002c2dfb0}, {0x11c9700, 0xc00bb6abc0}, 0xc00b7338a8)
github.com/xtls/xray-core/common/buf/copy.go:81 +0x69 github.com/xtls/xray-core/common/buf.Copy({0x11cb1c0, 0xc002c2dfb0}, {0x11c9700, 0xc00bb6abc0}, {0xc001394f20, 0x1, 0xc001394f18?})
github.com/xtls/xray-core/common/buf/copy.go:104 +0xa5 github.com/xtls/xray-core/proxy/vless/inbound.(*Handler).Process.func4()
github.com/xtls/xray-core/proxy/vless/inbound/inbound.go:514 +0x1f9
github.com/xtls/xray-core/common/task.OnSuccess.func1()
github.com/xtls/xray-core/common/task/task.go:12 +0x25
github.com/xtls/xray-core/common/task.Run.func1(0xc0005c2001?)
github.com/xtls/xray-core/common/task/task.go:28 +0x2e
created by github.com/xtls/xray-core/common/task.Run github.com/xtls/xray-core/common/task/task.go:27 +0xde

About this issue

  • Original URL
  • State: closed
  • Created a year ago
  • Comments: 18 (13 by maintainers)

Commits related to this issue

Most upvoted comments

@zerodwide @moradianali Use the latest commit, not the latest version.

看来下次需要连发两个版本,bugfix 专版 v1.7.3,和 Reality 专版 v1.8.0