From 9ea10763e47c195802d1f5a5c653cacaf6c1890f Mon Sep 17 00:00:00 2001 From: ginuerzh Date: Sun, 21 Jun 2026 16:47:12 +0800 Subject: [PATCH] fix(listener): add panic recovery in TUN/TAP listenLoop for wintun crashes On Windows, wintun.dll may pass an invalid pointer to the logMessage callback, causing a nil pointer dereference in UTF16PtrToString that panics the entire process. The upstream wintun-go library has not fixed this since 2021. Add defer/recover in tun/tungo/tap listenLoop inner closures to convert panics from createTun/createTap into logged errors, allowing the retry loop to recover gracefully instead of crashing the process. Fixes go-gost/gost#482 --- listener/tap/listener.go | 9 ++++++++- listener/tun/listener.go | 9 ++++++++- listener/tungo/listener.go | 9 ++++++++- 3 files changed, 24 insertions(+), 3 deletions(-) diff --git a/listener/tap/listener.go b/listener/tap/listener.go index e86ff31f..3b868a2f 100644 --- a/listener/tap/listener.go +++ b/listener/tap/listener.go @@ -2,6 +2,7 @@ package tap import ( "context" + "fmt" "net" "time" @@ -68,7 +69,13 @@ func (l *tapListener) Init(md mdata.Metadata) (err error) { func (l *tapListener) listenLoop() { for { ctx, cancel := context.WithCancel(context.Background()) - err := func() error { + err := func() (err error) { + defer func() { + if r := recover(); r != nil { + err = fmt.Errorf("panic in createTap: %v", r) + } + }() + ifce, name, ip, err := l.createTap() if err != nil { if ifce != nil { diff --git a/listener/tun/listener.go b/listener/tun/listener.go index 551a339e..a94a0451 100644 --- a/listener/tun/listener.go +++ b/listener/tun/listener.go @@ -2,6 +2,7 @@ package tun import ( "context" + "fmt" "net" "time" @@ -75,7 +76,13 @@ func (l *tunListener) Init(md mdata.Metadata) (err error) { func (l *tunListener) listenLoop(ready context.CancelCauseFunc) { for { ctx, cancel := context.WithCancel(context.Background()) - err := func() error { + err := func() (err error) { + defer func() { + if r := recover(); r != nil { + err = fmt.Errorf("panic in createTun: %v", r) + } + }() + ifce, name, ip, err := l.createTun() if err != nil { if ifce != nil { diff --git a/listener/tungo/listener.go b/listener/tungo/listener.go index 548e8ff6..fac92098 100644 --- a/listener/tungo/listener.go +++ b/listener/tungo/listener.go @@ -2,6 +2,7 @@ package tungo import ( "context" + "fmt" "net" "time" @@ -68,7 +69,13 @@ func (l *tunListener) Init(md mdata.Metadata) (err error) { func (l *tunListener) listenLoop(ready context.CancelCauseFunc) { for { ctx, cancel := context.WithCancel(context.Background()) - err := func() error { + err := func() (err error) { + defer func() { + if r := recover(); r != nil { + err = fmt.Errorf("panic in createTun: %v", r) + } + }() + ifce, name, ip, err := l.createTun() if err != nil { if ifce != nil {