summaryrefslogtreecommitdiff
path: root/exports
diff options
context:
space:
mode:
authorJeroen Wijenbergh <jeroen.wijenbergh@geant.org>2025-08-13 14:06:28 +0200
committerJeroen Wijenbergh <jeroen.wijenbergh@geant.org>2025-08-13 14:34:27 +0200
commitb4f4f5600298436c63b89f289c318d777300c499 (patch)
tree13d4ed4aae2058a3cdff7b335c4c2fd3ed5c2004 /exports
parent47183a18ca03b3e2bb8e0d51870ae7913fb04fae (diff)
Exports: Attempt to fix ARM MTE crash
Diffstat (limited to 'exports')
-rw-r--r--exports/exports.go44
1 files changed, 31 insertions, 13 deletions
diff --git a/exports/exports.go b/exports/exports.go
index 880101a..47b9f14 100644
--- a/exports/exports.go
+++ b/exports/exports.go
@@ -33,6 +33,24 @@ import (
"codeberg.org/eduVPN/eduvpn-common/util"
)
+// goString copies a null-terminated *C.char to a Go string.
+// the default C.GoString doesn't play well with ARM MTE
+// see: https://github.com/golang/go/issues/27610#issuecomment-2381919857
+// see also: https://codeberg.org/eduVPN/android/issues/31
+// this was changed from: https://github.com/ebitengine/purego/blob/77ed15346fbb448af291a0509e024e06252a428f/internal/strings/strings.go#L25C1-L40C2
+// License: https://github.com/ebitengine/purego/blob/77ed15346fbb448af291a0509e024e06252a428f/LICENSE
+func goString(c *C.char) string {
+ ptr := unsafe.Pointer(c)
+ if ptr == nil {
+ return ""
+ }
+ length := 0
+ for *(*byte)(unsafe.Add(ptr, uintptr(length))) != '\x00' {
+ length++
+ }
+ return C.GoStringN(c, C.int(length))
+}
+
// VPNState is the current state of the library
var VPNState *client.Client
@@ -144,9 +162,9 @@ func Register(
return getCError(i18nerr.NewInternal("failed to register, a VPN state is already present"))
}
c, err := client.New(
- C.GoString(name),
- C.GoString(version),
- C.GoString(configDirectory),
+ goString(name),
+ goString(version),
+ goString(configDirectory),
func(oldState client.FSMStateID, newState client.FSMStateID, data interface{}) bool {
return stateCallback(cb, oldState, newState, data)
},
@@ -297,7 +315,7 @@ func AddServer(c C.uintptr_t, _type C.int, id *C.char, ot *C.longlong) *C.char {
got := int64(*ot)
auth = &got
}
- err = state.AddServer(v, C.GoString(id), srvtypes.Type(_type), auth)
+ err = state.AddServer(v, goString(id), srvtypes.Type(_type), auth)
return getCError(err)
}
@@ -331,7 +349,7 @@ func RemoveServer(_type C.int, id *C.char) *C.char {
if stateErr != nil {
return getCError(stateErr)
}
- err := state.RemoveServer(C.GoString(id), srvtypes.Type(_type))
+ err := state.RemoveServer(goString(id), srvtypes.Type(_type))
return getCError(err)
}
@@ -547,7 +565,7 @@ func GetConfig(c C.uintptr_t, _type C.int, id *C.char, pTCP C.int, startup C.int
}
preferTCPBool := pTCP != 0
startupBool := startup != 0
- cfg, err := state.GetConfig(ck, C.GoString(id), srvtypes.Type(_type), preferTCPBool, startupBool)
+ cfg, err := state.GetConfig(ck, goString(id), srvtypes.Type(_type), preferTCPBool, startupBool)
if cfg != nil && err == nil {
d, err := getReturnData(cfg)
if err == nil {
@@ -581,7 +599,7 @@ func SetProfileID(data *C.char) *C.char {
if stateErr != nil {
return getCError(stateErr)
}
- profileErr := state.SetProfileID(C.GoString(data))
+ profileErr := state.SetProfileID(goString(data))
return getCError(profileErr)
}
@@ -610,7 +628,7 @@ func SetSecureLocation(orgID *C.char, cc *C.char) *C.char {
if stateErr != nil {
return getCError(stateErr)
}
- locationErr := state.SetSecureLocation(C.GoString(orgID), C.GoString(cc))
+ locationErr := state.SetSecureLocation(goString(orgID), goString(cc))
return getCError(locationErr)
}
@@ -669,7 +687,7 @@ func DiscoServers(c C.uintptr_t, search *C.char) (*C.char, *C.char) {
if err != nil {
return nil, getCError(err)
}
- servers, err := state.DiscoServers(ck, C.GoString(search))
+ servers, err := state.DiscoServers(ck, goString(search))
if servers == nil && err != nil {
return nil, getCError(err)
}
@@ -744,7 +762,7 @@ func DiscoOrganizations(c C.uintptr_t, search *C.char) (*C.char, *C.char) {
if err != nil {
return nil, getCError(err)
}
- orgs, err := state.DiscoOrganizations(ck, C.GoString(search))
+ orgs, err := state.DiscoOrganizations(ck, goString(search))
if orgs == nil && err != nil {
return nil, getCError(err)
}
@@ -846,7 +864,7 @@ func StartFailover(c C.uintptr_t, gateway *C.char, mtu C.int, readRxBytes C.Read
if err != nil {
return C.int(0), getCError(err)
}
- dropped, droppedErr := state.StartFailover(ck, C.GoString(gateway), int(mtu), func() (int64, error) {
+ dropped, droppedErr := state.StartFailover(ck, goString(gateway), int(mtu), func() (int64, error) {
rxBytes := int64(C.get_read_rx_bytes(readRxBytes))
if rxBytes < 0 {
return 0, i18nerr.NewInternal("client gave an invalid rx bytes value")
@@ -1035,7 +1053,7 @@ func SetTokenHandler(getter C.TokenGetter, setter C.TokenSetter) *C.char {
//
//export CalculateGateway
func CalculateGateway(subnet *C.char) (*C.char, *C.char) {
- gw, err := util.CalculateGateway(C.GoString(subnet))
+ gw, err := util.CalculateGateway(goString(subnet))
if err != nil {
return nil, getCError(err)
}
@@ -1076,7 +1094,7 @@ func CookieReply(c C.uintptr_t, data *C.char) *C.char {
if err != nil {
return getCError(err)
}
- err = v.Send(C.GoString(data))
+ err = v.Send(goString(data))
return getCError(err)
}