Skip to content

fix(voice): nil-guard udpConnImpl.Close to prevent SIGSEGV on un-opened conn#550

Merged
topi314 merged 1 commit into
disgoorg:masterfrom
sealbro:fix/udp-close-nil-guard
Jun 7, 2026
Merged

fix(voice): nil-guard udpConnImpl.Close to prevent SIGSEGV on un-opened conn#550
topi314 merged 1 commit into
disgoorg:masterfrom
sealbro:fix/udp-close-nil-guard

Conversation

@sealbro

@sealbro sealbro commented Jun 7, 2026

Copy link
Copy Markdown
Contributor

Summary

Fixes a nil-pointer panic in (*udpConnImpl).Close() when called before Open() has assigned u.conn.

(*connImpl).HandleVoiceStateUpdate unconditionally calls c.udp.Close() whenever a VOICE_STATE_UPDATE arrives with ChannelID == nil (the bot was kicked, moved, or its session was torn down before voice negotiation completed). If the UDP connection was never opened, u.conn is still nil and the bare return u.conn.Close() panics with a SIGSEGV, taking down the entire gateway listener goroutine.

The fix adds a nil-check so Close() is safe to call on an un-opened UDP conn — matching the defensive if c.audioSender != nil { ... } and if c.audioReceiver != nil { ... } guards already present on the surrounding lines of HandleVoiceStateUpdate.

Stack (reproduced against v0.19.5)

panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x2 addr=0x18 pc=0x10301d654]

goroutine 85 [running]:
github.com/disgoorg/disgo/voice.(*udpConnImpl).Close(...)
        voice/udp_conn.go:401 +0xa4
github.com/disgoorg/disgo/voice.(*connImpl).HandleVoiceStateUpdate(...)
        voice/conn.go:186 +0x110
github.com/disgoorg/disgo/voice.(*managerImpl).HandleVoiceStateUpdate(...)
        voice/manager.go:72 +0xf4
github.com/disgoorg/disgo/bot/handlers.gatewayHandlerVoiceStateUpdate(...)
        bot/handlers/voice_handlers.go:28 +0x294
...

Test plan

  • go build ./... in disgo and a downstream voice-bot consumer
  • Downstream integration tests that previously SIGSEGV'd within ~30s now run to completion

HandleVoiceStateUpdate unconditionally calls c.udp.Close() when the bot
transitions to ChannelID == nil (kicked, moved, or session ending before
audio negotiation completed). If Open() was never called on the
udpConnImpl, u.conn is still nil and the bare u.conn.Close() panics with
a SIGSEGV, taking down the whole gateway listener goroutine.

Add a nil-check so Close() is safe to call on an un-opened UDP conn.
@topi314 topi314 merged commit de15e6a into disgoorg:master Jun 7, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Development

Successfully merging this pull request may close these issues.

2 participants