]> Cypherpunks repositories - gostls13.git/commitdiff
net: allocate res_state entirely in C memory
authorRuss Cox <rsc@golang.org>
Tue, 8 Nov 2022 21:16:44 +0000 (16:16 -0500)
committerGopher Robot <gobot@golang.org>
Tue, 8 Nov 2022 22:14:56 +0000 (22:14 +0000)
The linux-amd64-wsl builder was failing because the res_nsearch
implementation was storing pointer to the res_state's own fields
in other fields in the res_state. If the res_state is Go memory, this
looks like pointers to Go pointers. Moving the res_state to C memory
avoids the problem.

The linux-amd64-wsl builder has been fixed a different way by
replacing res_nsearch with res_search on Linux, where it is thread-safe.
But other systems that still need to use res_nsearch (such as macOS)
may run into the same kind of problem, so it is probably still worth
arranging for the res_state to live entirely in C memory.

Fixes #56658 (again).

Change-Id: I58a14e72c866eaceb02ad828854a1f626b9b8e73
Reviewed-on: https://go-review.googlesource.com/c/go/+/448798
Run-TryBot: Russ Cox <rsc@golang.org>
Auto-Submit: Russ Cox <rsc@golang.org>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@google.com>
src/net/cgo_unix.go

index 8cf3b87d84b0633a77cee761e5a2e381a3c463db..b9759d05a3a979e58aa023ac9fb2299a110b0898 100644 (file)
@@ -331,11 +331,12 @@ func cgoLookupCNAME(ctx context.Context, name string) (cname string, err error,
 // resSearch will make a call to the 'res_nsearch' routine in the C library
 // and parse the output as a slice of DNS resources.
 func resSearch(ctx context.Context, hostname string, rtype, class int) ([]dnsmessage.Resource, error) {
-       var state _C_struct___res_state
-       if err := _C_res_ninit(&state); err != nil {
+       state := (*_C_struct___res_state)(_C_malloc(unsafe.Sizeof(_C_struct___res_state{})))
+       defer _C_free(unsafe.Pointer(state))
+       if err := _C_res_ninit(state); err != nil {
                return nil, errors.New("res_ninit failure: " + err.Error())
        }
-       defer _C_res_nclose(&state)
+       defer _C_res_nclose(state)
 
        // Some res_nsearch implementations (like macOS) do not set errno.
        // They set h_errno, which is not per-thread and useless to us.
@@ -350,7 +351,7 @@ func resSearch(ctx context.Context, hostname string, rtype, class int) ([]dnsmes
        defer _C_free(unsafe.Pointer(buf))
        s := _C_CString(hostname)
        defer _C_FreeCString(s)
-       size, err := _C_res_nsearch(&state, s, class, rtype, buf, bufSize)
+       size, err := _C_res_nsearch(state, s, class, rtype, buf, bufSize)
        if size <= 0 || size > bufSize {
                return nil, errors.New("res_nsearch failure")
        }