From cec7e47086bb782337a7fc0f350714a6ecf6ecbe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=96=E7=95=8C?= Date: Tue, 10 Dec 2024 13:04:55 +0800 Subject: [PATCH] Add workaround for `bulkBarrierPreWrite: unaligned arguments` panic --- experimental/libbox/config.go | 8 ++++---- experimental/libbox/http.go | 18 ++++++------------ experimental/libbox/panic.go | 12 ++++++++++++ experimental/libbox/service_error.go | 4 ++-- experimental/libbox/tun.go | 8 ++++---- 5 files changed, 28 insertions(+), 22 deletions(-) create mode 100644 experimental/libbox/panic.go diff --git a/experimental/libbox/config.go b/experimental/libbox/config.go index 56c56189..c8d0693a 100644 --- a/experimental/libbox/config.go +++ b/experimental/libbox/config.go @@ -139,17 +139,17 @@ func (s *platformInterfaceStub) SendNotification(notification *platform.Notifica return nil } -func FormatConfig(configContent string) (string, error) { +func FormatConfig(configContent string) (*StringBox, error) { options, err := parseConfig(configContent) if err != nil { - return "", err + return nil, err } var buffer bytes.Buffer encoder := json.NewEncoder(&buffer) encoder.SetIndent("", " ") err = encoder.Encode(options) if err != nil { - return "", err + return nil, err } - return buffer.String(), nil + return wrapString(buffer.String()), nil } diff --git a/experimental/libbox/http.go b/experimental/libbox/http.go index 3e1a04d0..e037de00 100644 --- a/experimental/libbox/http.go +++ b/experimental/libbox/http.go @@ -50,8 +50,7 @@ type HTTPRequest interface { } type HTTPResponse interface { - GetContent() ([]byte, error) - GetContentString() (string, error) + GetContent() (*StringBox, error) WriteTo(path string) error } @@ -210,27 +209,22 @@ type httpResponse struct { } func (h *httpResponse) errorString() string { - content, err := h.GetContentString() + content, err := h.GetContent() if err != nil { return fmt.Sprint("HTTP ", h.Status) } return fmt.Sprint("HTTP ", h.Status, ": ", content) } -func (h *httpResponse) GetContent() ([]byte, error) { +func (h *httpResponse) GetContent() (*StringBox, error) { h.getContentOnce.Do(func() { defer h.Body.Close() h.content, h.contentError = io.ReadAll(h.Body) }) - return h.content, h.contentError -} - -func (h *httpResponse) GetContentString() (string, error) { - content, err := h.GetContent() - if err != nil { - return "", err + if h.contentError != nil { + return nil, h.contentError } - return string(content), nil + return wrapString(string(h.content)), nil } func (h *httpResponse) WriteTo(path string) error { diff --git a/experimental/libbox/panic.go b/experimental/libbox/panic.go new file mode 100644 index 00000000..62fe1326 --- /dev/null +++ b/experimental/libbox/panic.go @@ -0,0 +1,12 @@ +package libbox + +// https://github.com/golang/go/issues/46893 +// TODO: remove after `bulkBarrierPreWrite: unaligned arguments` fixed + +type StringBox struct { + Value string +} + +func wrapString(value string) *StringBox { + return &StringBox{Value: value} +} diff --git a/experimental/libbox/service_error.go b/experimental/libbox/service_error.go index 2f22574a..bb0593bf 100644 --- a/experimental/libbox/service_error.go +++ b/experimental/libbox/service_error.go @@ -13,12 +13,12 @@ func ClearServiceError() { os.Remove(serviceErrorPath()) } -func ReadServiceError() (string, error) { +func ReadServiceError() (*StringBox, error) { data, err := os.ReadFile(serviceErrorPath()) if err == nil { os.Remove(serviceErrorPath()) } - return string(data), err + return wrapString(string(data)), err } func WriteServiceError(message string) error { diff --git a/experimental/libbox/tun.go b/experimental/libbox/tun.go index 5c6e3370..18b7910e 100644 --- a/experimental/libbox/tun.go +++ b/experimental/libbox/tun.go @@ -13,7 +13,7 @@ import ( type TunOptions interface { GetInet4Address() RoutePrefixIterator GetInet6Address() RoutePrefixIterator - GetDNSServerAddress() (string, error) + GetDNSServerAddress() (*StringBox, error) GetMTU() int32 GetAutoRoute() bool GetStrictRoute() bool @@ -89,11 +89,11 @@ func (o *tunOptions) GetInet6Address() RoutePrefixIterator { return mapRoutePrefix(o.Inet6Address) } -func (o *tunOptions) GetDNSServerAddress() (string, error) { +func (o *tunOptions) GetDNSServerAddress() (*StringBox, error) { if len(o.Inet4Address) == 0 || o.Inet4Address[0].Bits() == 32 { - return "", E.New("need one more IPv4 address for DNS hijacking") + return nil, E.New("need one more IPv4 address for DNS hijacking") } - return o.Inet4Address[0].Addr().Next().String(), nil + return wrapString(o.Inet4Address[0].Addr().Next().String()), nil } func (o *tunOptions) GetMTU() int32 {